Index: EcnlProtoTool/trunk/tcc-0.9.27/.cproject
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/.cproject	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.cproject	(revision 331)
@@ -20,5 +20,5 @@
 							<builder buildPath="${workspace_loc:/tcc}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.1947549202" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
 							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1351770923" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
-								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.373654238" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="false" valueType="boolean"/>
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.373654238" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.1091726519" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.1331241682" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
@@ -30,11 +30,18 @@
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.401098680" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.1123397289" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
-								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1138208172" name="Decimal representation of '-Wsatck-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1138208172" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.276254572" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
 								</option>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.1180675084" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="TCC_CPU_VERSION=7"/>
+									<listOptionValue builtIn="false" value="TCC_MUSL"/>
 									<listOptionValue builtIn="false" value="TCC_TARGET_ARM"/>
-									<listOptionValue builtIn="false" value="WITHOUT_LIBTCC"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_EABI"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_VFP"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_HARDFLOAT"/>
+									<listOptionValue builtIn="false" value="ONE_SOURCE=0"/>
+									<listOptionValue builtIn="false" value="CONFIG_TCC_STATIC"/>
 								</option>
 								<inputType id="%Base.Compiler.C.InputType.Id.1716911779" name="C å
@@ -57,5 +64,5 @@
 					</folderInfo>
 					<sourceEntries>
-						<entry excluding="tests|lib|examples|tccpe.c|tcccoff.c|x86_64-gen.c|x86_64-asm.h|il-opcodes.h|il-gen.c|i386-tok.h|i386-gen.c|i386-asm.h|i386-asm.c|c67-gen.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+						<entry excluding="lib/armeabi.c|lib/alloca-arm.S|tcctools.c|lib/va_list.c|lib/libtcc1.c|lib/lib-arm64.c|lib/bcheck.c|lib/alloca86-bt.S|lib/alloca86.S|lib/alloca86_64-bt.S|lib/alloca86_64.S|i386-link.c|conftest.c|c67-link.c|win32|x86_64-link.c|arm64-link.c|arm64-gen.c|tests|examples|tccpe.c|tcccoff.c|x86_64-gen.c|x86_64-asm.h|il-opcodes.h|il-gen.c|i386-tok.h|i386-gen.c|i386-asm.h|i386-asm.c|c67-gen.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
 					</sourceEntries>
 				</configuration>
@@ -71,3 +78,8 @@
 	</storageModule>
 	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/tcc-0.9.27"/>
+		</configuration>
+	</storageModule>
 </cproject>
Index: EcnlProtoTool/trunk/tcc-0.9.27/.gitignore
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/.gitignore	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.gitignore	(revision 331)
@@ -1,58 +1,57 @@
+*~
+\#*
+.#*
 *.o
 *.a
+*.exe
+*.dll
+*.obj
+*.pdb
+*.lib
+*.exp
+*.log
+*.bz2
+*.zip
+.gdb_history
+a.out
 tcc_g
 tcc
-/*-tcc
-tc2.c
-doc
-tc3s.c
-p3.c
-tc1.c
-error.c
-i386-gen1.c
-test.out1
-test.out1b
-test.out2
-test.out2b
-test.out3
-test.out3b
-web.sh
-memdebug.c
-bench
-Makefile.uClibc
-boundtest
-prog.ref
-test.ref
-test.out
-tcc-doc.html
-ideas
-tcctest.ref
-linux.tcc
-ldtest
-libtcc_test
-instr.S
-p.c
-p2.c
-tcctest[1234]
-test[1234].out
-tests/tcclib.h
-tests/tcctest.gcc
-tests/weaktest.*.o.txt
-tests2/fred.txt
-.gdb_history
+*-tcc
+libtcc*.def
+
+config*.h
+config*.mak
+config.texi
+conftest*
+tags
+TAGS
 tcc.1
 tcc.pod
-config.h
-config.mak
-config.texi
-tags
-.DS_Store
-*.swp
-lib/x86_64
-lib/i386
-lib/x86_64-win32
-lib/i386-win32
+tcc-doc.html
 tcc-doc.info
-conftest*
-tiny_libmaker
-*.dSYM
+
+win32/doc
+win32/libtcc
+win32/lib/32
+win32/lib/64
+win32/include/float.h
+win32/include/stdarg.h
+win32/include/stdbool.h
+win32/include/stddef.h
+win32/include/varargs.h
+win32/include/tcclib.h
+
+tests/tcctest[1234]
+tests/tcctest.gcc
+tests/*.out*
+tests/*.ref
+tests/*.txt
+tests/*.gcc
+tests/*-cc*
+tests/*-tcc*
+tests/libtcc_test
+tests/asm-c-connect
+tests/asm-c-connect-sep
+tests/vla_test
+tests/hello
+tests/tests2/fred.txt
Index: EcnlProtoTool/trunk/tcc-0.9.27/.info
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/.info	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.info	(revision 331)
@@ -4,4 +4,4 @@
 GCC_STRING=5.2-GNUARM-NONE_v16.01
 VERSION_IDE=
-E2STUDIO_VERSION=5.3.1.002
+E2STUDIO_VERSION=5.4.0.018
 ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/tcc-0.9.27/.project
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/.project	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.project	(revision 331)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>tcc-0.9.26</name>
+	<name>tcc-0.9.27</name>
 	<comment></comment>
 	<projects>
Index: EcnlProtoTool/trunk/tcc-0.9.27/Changelog
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/Changelog	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/Changelog	(revision 331)
@@ -1,2 +1,45 @@
+Version 0.9.27:
+
+User interface:
+- -x[c|a|n] filetype option (Sergey Korshunoff)
+- -P[1], -dD, -dM preprocessor options (Sergey Korshunoff)
+- -Wl,-(no-)whole-archive linker option (Reuben Thomas)
+- -mms-bitfields option (David Mertens)
+- -include <file> option (Michael Matz)
+- -mno-sse on x86-64 disables use of SSE instructions
+- @listfile support (Vlad Vissoultchev)
+- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
+- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
+  (Andrew Aladjev, Urs Janssen)
+
+Platforms:
+- new AARCH64 (arm64) target (Edmund Grimley Evans)
+- vastly improved support for ARM hard float calling convention
+   (Thomas Preud'homme, Daniel Gl旦ckner)
+- provide a runtime library for ARM (Thomas Preud'homme)
+- many x86_64 ABI fixes incl. XMM register passing and tests (James Lyon)
+- ABI tests with native compiler using libtcc (James Lyon)
+- UNICODE startup code supports wmain and wWinMain (YX Hao)
+- shared libraries for x86_64 (Michael Matz)
+- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
+
+Features:
+- VLA (variable length array) improved (James Lyon, Pip Cet)
+- import functions by ordinal in .def files on windows (YX Hao)
+- x86/x86_64 assembler much improved (Michael Matz)
+- simple dead code suppression (Edmund Grimley Evans, Michael Matz, grischka)
+- implement round/fmin/fmax etc. math on windows (Avi Halachmi)
+- #pragma once support (Sergey Korshunoff, Vlad Vissoultchev, ...)
+- switch/case code improved (Zdenek Pavlas)
+- ~15% faster by TinyAlloc fast memory allocator (Vlad Vissoultchev)
+- standard conforming (and GCC compatible) struct initialization
+   (Michael Matz)
+- bit-field layout made compatible with GCC (Michael Matz)
+- UTF8 in string literals supported (Zdenek Pavlas)
+_ _Generic(...) supported (Matthias Gatto)
+
+Licensing:
+- TinyCC partly relicensed to MIT license (See RELICENSING file).
+
 version 0.9.26:
 
@@ -11,5 +54,5 @@
 - Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
 - x86-64 assembler (Frederic Feret)
-- Many improvements for ARM target (Daniel Glöckner, Thomas Preud'homme)
+- Many improvements for ARM target (Daniel Gl旦ckner, Thomas Preud'homme)
 - Support WinCE PE ARM (Timo VJ Lahde)
 - Support ARM hardfloat calling convention (Thomas Preud'homme)
@@ -30,10 +73,10 @@
 
 - first support for x86-64 target (Shinichiro Hamaji)
-- support µClibc
+- support 袖Clibc
 - split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c
 - improved preprocess output with linenumbers and spaces preserved
 - tcc_relocate now copies code into user buffer
 - fix bitfields with non-int types and in unions
-- improve ARM cross-compiling (Daniel GlÃ¶ckner)
+- improve ARM cross-compiling (Daniel Gl旦ckner)
 - link stabstr sections from multiple objects
 - better (still limited) support for multiple TCCStates
@@ -52,5 +95,5 @@
 - Use _WIN32 for a windows hosted tcc and define it for the PE target,
   otherwise define __unix / __linux (Detlef Riekenberg)
-- Import changesets (part 3) 409,410: ARM EABI by Daniel GlÃ¶ckner
+- Import changesets (part 3) 409,410: ARM EABI by Daniel Gl旦ckner
 - Some in-between fixes:
   TCC -E no longer hangs with macro calls involving newlines.
@@ -93,5 +136,5 @@
   420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
   417: Make 'sizeof' unsigned (Rob Landley)
-  397: Fix save_reg for longlongs (Daniel GlÃ¶ckner)
+  397: Fix save_reg for longlongs (Daniel Gl旦ckner)
   396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
 
@@ -135,5 +178,5 @@
 version 0.9.21:
 
-- ARM target support (Daniel GlÃ¶ckner)
+- ARM target support (Daniel Gl旦ckner)
 - added '-funsigned-char, '-fsigned-char' and
   '-Wimplicit-function-declaration'
Index: EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle	(revision 331)
@@ -0,0 +1,71 @@
+
+In general, use the same coding style as the surrounding code.
+
+However, do not make any unnecessary changes as that complicates
+the VCS (git) history and makes it harder to merge patches. So
+do not modify code just to make it conform to a coding style.
+
+    Indentation
+
+Turn on a "fill tabs with spaces" option in your editor.
+
+Remove tabs and trailing spaces from any lines that are modified.
+
+Note that some files are indented with 2 spaces (when they
+have large indentation) while most are indented with 4 spaces.
+
+    Language
+
+TCC is mostly implemented in C90. Do not use any non-C90 features
+that are not already in use.
+
+Non-C90 features currently in use, as revealed by
+./configure --extra-cflags="-std=c90 -Wpedantic":
+
+- long long (including "LL" constants)
+- inline
+- very long string constants
+- assignment between function pointer and 'void *'
+- "//" comments
+- empty macro arguments (DEF_ASMTEST in i386-tok.h)
+- unnamed struct and union fields (in struct Sym), a C11 feature
+
+    Testing
+
+A simple "make test" is sufficient for some simple changes. However,
+before committing a change consider performing some of the following
+additional tests:
+
+- Build and run "make test" on several architectures.
+
+- Build with ./configure --enable-cross.
+
+- If the generation of relocations has been changed, try compiling
+  with TCC and linking with GCC/Clang. If the linker has been
+  modified, try compiling with GCC/Clang and linking with TCC.
+
+- Test with ASan/UBSan to detect memory corruption and undefined behaviour:
+
+make clean
+./configure
+make
+make test
+cp libtcc.a libtcc.a.hide
+
+make clean
+./configure --extra-cflags="-fsanitize=address,undefined -g"
+make
+cp libtcc.a.hide libtcc.a
+make test
+
+- Test with Valgrind to detect some uses of uninitialised values:
+
+make clean
+./configure
+make
+# On Intel, because Valgrind does floating-point arithmetic differently:
+( cd tests && gcc -I.. tcctest.c && valgrind -q ./a.out > test.ref )
+make test TCC="valgrind -q --leak-check=full `pwd`/tcc -B`pwd` -I`pwd`"
+
+  (Because of how VLAs are implemented, invalid reads are expected
+  with 79_vla_continue.)
Index: EcnlProtoTool/trunk/tcc-0.9.27/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/Makefile	(revision 331)
@@ -1,337 +1,332 @@
+# --------------------------------------------------------------------------
 #
 # Tiny C Compiler Makefile
 #
 
-TOP ?= .
+ifndef TOP
+ TOP = .
+ INCLUDED = no
+endif
+
 include $(TOP)/config.mak
-VPATH = $(top_srcdir)
-
-CPPFLAGS = -I$(TOP) # for config.h
-
-ifeq (-$(findstring gcc,$(CC))-,-gcc-)
-ifeq (-$(findstring $(GCC_MAJOR),01)-,--)
-CFLAGS+=-fno-strict-aliasing
-ifeq (-$(findstring $(GCC_MAJOR),23)-,--)
-CFLAGS+=-Wno-pointer-sign -Wno-sign-compare
-ifeq (-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-4--)
-CFLAGS+=-D_FORTIFY_SOURCE=0
+
+ifeq (-$(CC)-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-gcc-4--)
+ CFLAGS += -D_FORTIFY_SOURCE=0
+endif
+
+LIBTCC = libtcc.a
+LIBTCC1 = libtcc1.a
+LINK_LIBTCC =
+LIBS =
+CFLAGS += -I$(TOP)
+CFLAGS += $(CPPFLAGS)
+VPATH = $(TOPSRC)
+
+ifdef CONFIG_WIN32
+ ifneq ($(CONFIG_static),yes)
+  LIBTCC = libtcc$(DLLSUF)
+  LIBTCCDEF = libtcc.def
+ endif
+ CFGWIN = -win
+ NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
 else
-CFLAGS+=-Wno-unused-result
-endif
-endif
-endif
-else # not GCC
-ifeq (-$(findstring clang,$(CC))-,-clang-)
-# make clang accept gnuisms in libtcc1.c
-CFLAGS+=-fheinous-gnu-extensions
-endif
-endif
-
-CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
-CFLAGS_P=$(CFLAGS) -pg -static
-LIBS_P=
-LDFLAGS_P=$(LDFLAGS)
-
-ifdef CONFIG_WIN64
-CONFIG_WIN32=yes
-endif
-
-ifndef CONFIG_WIN32
-LIBS=-lm
-ifndef CONFIG_NOLDL
-LIBS+=-ldl
-endif
-endif
-
-# make libtcc as static or dynamic library?
-ifdef DISABLE_STATIC
-LIBTCC=libtcc.so.1.0
-LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
-ifdef DISABLE_RPATH
-LINK_LIBTCC=
-endif
-else
-LIBTCC=libtcc.a
-LINK_LIBTCC=
-endif
+ LIBS=-lm
+ ifneq ($(CONFIG_ldl),no)
+  LIBS+=-ldl
+ endif
+ # make libtcc as static or dynamic library?
+ ifeq ($(CONFIG_static),no)
+  LIBTCC=libtcc$(DLLSUF)
+  export LD_LIBRARY_PATH := $(CURDIR)/$(TOP)
+  ifneq ($(CONFIG_rpath),no)
+   LINK_LIBTCC += -Wl,-rpath,"$(libdir)"
+  endif
+ endif
+ CFGWIN =-unx
+ NATIVE_TARGET = $(ARCH)
+ ifdef CONFIG_OSX
+  NATIVE_TARGET = $(ARCH)-osx
+  LDFLAGS += -flat_namespace -undefined warning
+  export MACOSX_DEPLOYMENT_TARGET := 10.2
+ endif
+endif
+
+# run local version of tcc with local libraries and includes
+TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
+TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
+TCCFLAGS = $(TCCFLAGS$(CFGWIN))
+TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
+ifdef CONFIG_OSX
+ TCCFLAGS += -D_ANSI_SOURCE
+endif
+
+CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
+LIBS_P = $(LIBS)
+LDFLAGS_P = $(LDFLAGS)
 
 CONFIG_$(ARCH) = yes
 NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
-NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
+NATIVE_DEFINES_$(CONFIG_x86_64) += -DTCC_TARGET_X86_64
 NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
+NATIVE_DEFINES_$(CONFIG_OSX) += -DTCC_TARGET_MACHO
 NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
-NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM -DWITHOUT_LIBTCC
+NATIVE_DEFINES_$(CONFIG_musl) += -DTCC_MUSL
+NATIVE_DEFINES_$(CONFIG_libgcc) += -DCONFIG_USE_LIBGCC
+NATIVE_DEFINES_$(CONFIG_selinux) += -DHAVE_SELINUX
+NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
 NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
 NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
 NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
+NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
 NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
 
-ifeq ($(TOP),.)
-
-PROGS=tcc$(EXESUF)
-I386_CROSS = i386-tcc$(EXESUF)
-WIN32_CROSS = i386-win32-tcc$(EXESUF)
-WIN64_CROSS = x86_64-win32-tcc$(EXESUF)
-WINCE_CROSS = arm-win32-tcc$(EXESUF)
-X64_CROSS = x86_64-tcc$(EXESUF)
-ARM_FPA_CROSS = arm-fpa-tcc$(EXESUF)
-ARM_FPA_LD_CROSS = arm-fpa-ld-tcc$(EXESUF)
-ARM_VFP_CROSS = arm-vfp-tcc$(EXESUF)
-ARM_EABI_CROSS = arm-eabi-tcc$(EXESUF)
-ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
-C67_CROSS = c67-tcc$(EXESUF)
-
-CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
+ifeq ($(INCLUDED),no)
+# --------------------------------------------------------------------------
+# running top Makefile
+
+PROGS = tcc$(EXESUF)
+TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
+TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
+
+all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
+
+# cross compiler targets to build
+TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
+# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
+
+# cross libtcc1.a targets to build
+LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
+
+PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
+LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
+
+# build cross compilers & libs
+cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
+
+# build specific cross compiler & lib
+cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
+
+install: ; @$(MAKE) --no-print-directory install$(CFGWIN)
+install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes
+uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN)
+
+ifdef CONFIG_cross
+all : cross
+endif
+
+# --------------------------------------------
+
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+
+DEF-i386        = -DTCC_TARGET_I386
+DEF-x86_64      = -DTCC_TARGET_X86_64
+DEF-i386-win32  = -DTCC_TARGET_PE -DTCC_TARGET_I386
+DEF-x86_64-win32= -DTCC_TARGET_PE -DTCC_TARGET_X86_64
+DEF-x86_64-osx  = -DTCC_TARGET_MACHO -DTCC_TARGET_X86_64
+DEF-arm-wince   = -DTCC_TARGET_PE -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP -DTCC_ARM_HARDFLOAT
+DEF-arm64       = -DTCC_TARGET_ARM64
+DEF-c67         = -DTCC_TARGET_C67 -w # disable warnigs
+DEF-arm-fpa     = -DTCC_TARGET_ARM
+DEF-arm-fpa-ld  = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
+DEF-arm-vfp     = -DTCC_TARGET_ARM -DTCC_ARM_VFP
+DEF-arm-eabi    = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
+DEF-arm-eabihf  = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
+DEF-arm         = $(DEF-arm-eabihf)
+DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES)
+
+DEFINES += $(DEF-$T) $(DEF-all)
+DEFINES += $(if $(ROOT-$T),-DCONFIG_SYSROOT="\"$(ROOT-$T)\"")
+DEFINES += $(if $(CRT-$T),-DCONFIG_TCC_CRTPREFIX="\"$(CRT-$T)\"")
+DEFINES += $(if $(LIB-$T),-DCONFIG_TCC_LIBPATHS="\"$(LIB-$T)\"")
+DEFINES += $(if $(INC-$T),-DCONFIG_TCC_SYSINCLUDEPATHS="\"$(INC-$T)\"")
+DEFINES += $(DEF-$(or $(findstring win,$T),unx))
+
+ifneq ($(X),)
+ifeq ($(CONFIG_WIN32),yes)
+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
+else
+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
+endif
+endif
+
+# include custom configuration (see make help)
+-include config-extra.mak
+
+CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
 CORE_FILES += tcc.h config.h libtcc.h tcctok.h
-CORE_FILES += dummy.c
-I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
-WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h tccpe.c
-WIN64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h tccpe.c
-WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
-X86_64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h
-ARM_FILES = $(CORE_FILES) arm-gen.c
-C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
-
-ifdef CONFIG_WIN64
-PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
-NATIVE_FILES=$(WIN64_FILES)
-PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
-LIBTCC1_CROSS=lib/i386-win32/libtcc1.a
-LIBTCC1=libtcc1.a
-else ifdef CONFIG_WIN32
-PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
-NATIVE_FILES=$(WIN32_FILES)
-PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
-LIBTCC1_CROSS=lib/x86_64-win32/libtcc1.a
-LIBTCC1=libtcc1.a
-else ifeq ($(ARCH),i386)
-NATIVE_FILES=$(I386_FILES)
-PROGS_CROSS=$(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
-LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a
-LIBTCC1=libtcc1.a
-else ifeq ($(ARCH),x86-64)
-NATIVE_FILES=$(X86_64_FILES)
-PROGS_CROSS=$(I386_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
-LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
-LIBTCC1=libtcc1.a
-else ifeq ($(ARCH),arm)
-NATIVE_FILES=$(ARM_FILES)
-PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(C67_CROSS)
-endif
-
-ifeq ($(TARGETOS),Darwin)
-PROGS+=tiny_libmaker$(EXESUF)
-endif
-
-ifdef CONFIG_USE_LIBGCC
-LIBTCC1=
-endif
-
-TCCLIBS = $(LIBTCC1) $(LIBTCC)
-TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
-
-ifdef CONFIG_CROSS
-PROGS+=$(PROGS_CROSS)
-TCCLIBS+=$(LIBTCC1_CROSS)
-endif
-
-all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
+i386_FILES = $(CORE_FILES) i386-gen.c i386-link.c i386-asm.c i386-asm.h i386-tok.h
+i386-win32_FILES = $(i386_FILES) tccpe.c
+x86_64_FILES = $(CORE_FILES) x86_64-gen.c x86_64-link.c i386-asm.c x86_64-asm.h
+x86_64-win32_FILES = $(x86_64_FILES) tccpe.c
+x86_64-osx_FILES = $(x86_64_FILES)
+arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c
+arm-wince_FILES = $(arm_FILES) tccpe.c
+arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c
+c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c
+
+# libtcc sources
+LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
+
+ifeq ($(ONE_SOURCE),yes)
+LIBTCC_OBJ = $(X)libtcc.o
+LIBTCC_INC = $($T_FILES)
+TCC_FILES = $(X)tcc.o
+tcc.o : DEFINES += -DONE_SOURCE=0
+else
+LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC))
+LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES))
+TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ)
+$(TCC_FILES) : DEFINES += -DONE_SOURCE=0
+endif
+
+# target specific object rule
+$(X)%.o : %.c $(LIBTCC_INC)
+	$(CC) -o $@ -c $< $(DEFINES) $(CFLAGS)
+
+# additional dependencies
+$(X)tcc.o : tcctools.c
 
 # Host Tiny C Compiler
 tcc$(EXESUF): tcc.o $(LIBTCC)
-	$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
+	$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
 
 # Cross Tiny C Compilers
-%-tcc$(EXESUF): tcc.c
-	$(CC) -o $@ $< -DONE_SOURCE $(DEFINES) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
+%-tcc$(EXESUF): FORCE
+	@$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
+
+$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
+	$(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
 
 # profiling version
-tcc_p$(EXESUF): $(NATIVE_FILES)
-	$(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
-
-$(I386_CROSS): DEFINES = -DTCC_TARGET_I386 \
-    -DCONFIG_TCCDIR="\"$(tccdir)/i386\""
-$(X64_CROSS): DEFINES = -DTCC_TARGET_X86_64
-$(WIN32_CROSS): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
-    -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-    -DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
-$(WIN64_CROSS): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
-    -DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
-    -DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
-$(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
-$(C67_CROSS): DEFINES = -DTCC_TARGET_C67
-$(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
-$(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
-$(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
-$(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI
-
-$(I386_CROSS): $(I386_FILES)
-$(X64_CROSS): $(X86_64_FILES)
-$(WIN32_CROSS): $(WIN32_FILES)
-$(WIN64_CROSS): $(WIN64_FILES)
-$(WINCE_CROSS): $(WINCE_FILES)
-$(C67_CROSS): $(C67_FILES)
-$(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
-
-# libtcc generation and test
-ifndef ONE_SOURCE
-LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
-LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
-else
-LIBTCC_OBJ = libtcc.o
-LIBTCC_INC = $(NATIVE_FILES)
-libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
-endif
-
-$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
-	$(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
-
+tcc_p$(EXESUF): $($T_FILES)
+	$(CC) -o $@ $< $(DEFINES) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
+
+# static libtcc library
 libtcc.a: $(LIBTCC_OBJ)
 	$(AR) rcs $@ $^
 
-libtcc.so.1.0: $(LIBTCC_OBJ)
+# dynamic libtcc library
+libtcc.so: $(LIBTCC_OBJ)
 	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
 
-libtcc.so.1.0: CFLAGS+=-fPIC
-
-# windows utilities
-tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
-	$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
-tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
-	$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
+libtcc.so: CFLAGS+=-fPIC
+libtcc.so: LDFLAGS+=-fPIC
+
+# windows dynamic libtcc library
+libtcc.dll : $(LIBTCC_OBJ)
+	$(CC) -shared -o $@ $^ $(LDFLAGS)
+libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
+
+# import file for windows libtcc.dll
+libtcc.def : libtcc.dll tcc$(EXESUF)
+	$(XTCC) -impdef $< -o $@
+XTCC ?= ./tcc$(EXESUF)
 
 # TinyCC runtime libraries
-libtcc1.a : FORCE
-	$(MAKE) -C lib native
-lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
-	$(MAKE) -C lib cross TARGET=$*
-
+libtcc1.a : tcc$(EXESUF) FORCE
+	@$(MAKE) -C lib DEFINES='$(DEF-$T)'
+
+# Cross libtcc1.a
+%-libtcc1.a : %-tcc$(EXESUF) FORCE
+	@$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
+
+.PRECIOUS: %-libtcc1.a
 FORCE:
 
-# install
-TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h tcclib.h
-INSTALL=install
-ifdef STRIP_BINARIES
-INSTALLBIN=$(INSTALL) -s
-else
-INSTALLBIN=$(INSTALL)
-endif
-
-ifndef CONFIG_WIN32
-install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
-	mkdir -p "$(bindir)"
-ifeq ($(CC),tcc)
-	$(INSTALL) -m755 $(PROGS) "$(bindir)"
-else
-	$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
-endif
-	mkdir -p "$(mandir)/man1"
-	-$(INSTALL) tcc.1 "$(mandir)/man1"
-	mkdir -p "$(infodir)"
-	-$(INSTALL) tcc-doc.info "$(infodir)"
-	mkdir -p "$(tccdir)"
-	mkdir -p "$(tccdir)/include"
-ifneq ($(LIBTCC1),)
-	$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
-endif
-	$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) "$(tccdir)/include"
-	mkdir -p "$(libdir)"
-	$(INSTALL) -m755 $(LIBTCC) "$(libdir)"
-ifdef DISABLE_STATIC
-	ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
-	ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
-endif
-	mkdir -p "$(includedir)"
-	$(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
-	mkdir -p "$(docdir)"
-	-$(INSTALL) -m644 tcc-doc.html "$(docdir)"
-ifdef CONFIG_CROSS
-	mkdir -p "$(tccdir)/win32/lib/32"
-	mkdir -p "$(tccdir)/win32/lib/64"
-ifeq ($(ARCH),x86-64)
-	mkdir -p "$(tccdir)/i386"
-	$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
-	cp -r "$(tccdir)/include" "$(tccdir)/i386"
-endif
-	$(INSTALL) -m644 win32/lib/*.def "$(tccdir)/win32/lib"
-	$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/win32/lib/32"
-	$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/win32/lib/64"
-	cp -r win32/include/. "$(tccdir)/win32/include"
-	cp -r include/. "$(tccdir)/win32/include"
-endif
-
-uninstall:
-	rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
-	rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
-	rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
-	rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
-	rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
-	rm -fv "$(libdir)/libtcc.so*"
-	rm -rf "$(tccdir)/win32"
-	-rmdir $(tccdir)/include
-ifeq ($(ARCH),x86-64)
-	rm -rf "$(tccdir)/i386"
-endif
-else
-# on windows
-install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
-	mkdir -p "$(tccdir)"
-	mkdir -p "$(tccdir)/lib"
-	mkdir -p "$(tccdir)/include"
-	mkdir -p "$(tccdir)/examples"
-	mkdir -p "$(tccdir)/doc"
-	mkdir -p "$(tccdir)/libtcc"
-	$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
-	$(INSTALL) -m644 $(LIBTCC1) win32/lib/*.def "$(tccdir)/lib"
-	cp -r win32/include/. "$(tccdir)/include"
-	cp -r win32/examples/. "$(tccdir)/examples"
-	$(INSTALL) -m644 $(addprefix include/,$(TCC_INCLUDES)) "$(tccdir)/include"
-	$(INSTALL) -m644 tcc-doc.html win32/tcc-win32.txt "$(tccdir)/doc"
-	$(INSTALL) -m644 $(LIBTCC) libtcc.h "$(tccdir)/libtcc"
-ifdef CONFIG_CROSS
-	mkdir -p "$(tccdir)/lib/32"
-	mkdir -p "$(tccdir)/lib/64"
-	-$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/lib/32"
-	-$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/lib/64"
-endif
-
-uninstall:
-	rm -rfv "$(tccdir)/*"
-endif
-
+# --------------------------------------------------------------------------
 # documentation and man page
 tcc-doc.html: tcc-doc.texi
-	-texi2html -monolithic -number $<
+	makeinfo --no-split --html --number-sections -o $@ $< || true
 
 tcc.1: tcc-doc.texi
-	-$(top_srcdir)/texi2pod.pl $< tcc.pod
-	-pod2man --section=1 --center=" " --release=" " tcc.pod > $@
+	$(TOPSRC)/texi2pod.pl $< tcc.pod \
+	&& pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod >tmp.1 \
+	&& mv tmp.1 $@ || rm -f tmp.1
 
 tcc-doc.info: tcc-doc.texi
-	-makeinfo $<
-
-# in tests subdir
-export LIBTCC1
-
-%est:
-	$(MAKE) -C tests $@
-
-clean:
-	rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF)
-	$(MAKE) -C tests $@
-ifneq ($(LIBTCC1),)
-	$(MAKE) -C lib $@
-endif
-
-distclean: clean
-	rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
-
-config.mak:
-	@echo "Please run ./configure."
-	@exit 1
+	makeinfo $< || true
+
+# --------------------------------------------------------------------------
+# install
+
+INSTALL = install -m644
+INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
+STRIP_yes = -s
+
+LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
+LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
+IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
+IBw = $(call IB,$(wildcard $1),$2)
+IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
+IFw = $(call IF,$(wildcard $1),$2)
+IR = mkdir -p $2 && cp -r $1/. $2
+
+# install progs & libs
+install-unx:
+	$(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
+	$(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+	$(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
+	$(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
+	$(call IFw,tcc.1,"$(mandir)/man1")
+	$(call IFw,tcc-doc.info,"$(infodir)")
+	$(call IFw,tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_W))" ""
+	$(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
+	$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
+endif
+
+# uninstall
+uninstall-unx:
+	@rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS),"$(bindir)/$P")
+	@rm -fv "$(libdir)/libtcc.a" "$(libdir)/libtcc.so" "$(includedir)/libtcc.h"
+	@rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
+	@rm -fv "$(docdir)/tcc-doc.html"
+	rm -r "$(tccdir)"
+
+# install progs & libs on windows
+install-win:
+	$(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
+	$(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
+	$(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+	$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
+	$(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
+	$(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
+	$(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)")
+	$(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_U))" ""
+	$(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
+endif
+
+# the msys-git shell works to configure && make except it does not have install
+ifeq "$(and $(CONFIG_WIN32),$(shell which install >/dev/null 2>&1 || echo no))" "no"
+install-win : INSTALL = cp
+install-win : INSTALLBIN = cp
+endif
+
+# uninstall on windows
+uninstall-win:
+	@rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P")
+	@rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F")
+	@rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F")
+	rm -r "$(tccdir)"
+
+# --------------------------------------------------------------------------
+# other stuff
+
+TAGFILES = *.[ch] include/*.h lib/*.[chS]
+tags : ; ctags $(TAGFILES)
+# cannot have both tags and TAGS on windows
+ETAGS : ; etags $(TAGFILES)
 
 # create release tarball from *current* git branch (including tcc-doc.html
 # and converting two files to CRLF)
-TCC-VERSION := tcc-$(shell cat $(top_srcdir)/VERSION)
+TCC-VERSION = tcc-$(VERSION)
 tar:    tcc-doc.html
 	mkdir $(TCC-VERSION)
@@ -345,6 +340,64 @@
 	git reset
 
-
-.PHONY: all clean tar distclean install uninstall FORCE
-
-endif # ifeq ($(TOP),.)
+config.mak:
+	$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
+
+# run all tests
+test:
+	$(MAKE) -C tests
+# run test(s) from tests2 subdir (see make help)
+tests2.%:
+	$(MAKE) -C tests/tests2 $@
+
+clean:
+	rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod
+	rm -f  *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS
+	@$(MAKE) -C lib $@
+	@$(MAKE) -C tests $@
+
+distclean: clean
+	rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
+
+.PHONY: all clean test tar tags ETAGS distclean install uninstall FORCE
+
+help:
+	@echo "make"
+	@echo "   build native compiler (from separate objects)"
+	@echo ""
+	@echo "make cross"
+	@echo "   build cross compilers (from one source)"
+	@echo ""
+	@echo "make ONE_SOURCE=yes / no"
+	@echo "   force building from one source / separate objects"
+	@echo ""
+	@echo "make cross-TARGET"
+	@echo "   build one specific cross compiler for 'TARGET', as in"
+	@echo "   $(TCC_X)"
+	@echo ""
+	@echo "Custom configuration:"
+	@echo "   The makefile includes a file 'config-extra.mak' if it is present."
+	@echo "   This file may contain some custom configuration.  For example:"
+	@echo ""
+	@echo "      NATIVE_DEFINES += -D..."
+	@echo ""
+	@echo "   Or for example to configure the search paths for a cross-compiler"
+	@echo "   that expects the linux files in <tccdir>/i386-linux:"
+	@echo ""
+	@echo "      ROOT-i386 = {B}/i386-linux"
+	@echo "      CRT-i386  = {B}/i386-linux/usr/lib"
+	@echo "      LIB-i386  = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
+	@echo "      INC-i386  = {B}/lib/include:{B}/i386-linux/usr/include"
+	@echo "      DEF-i386  += -D__linux__"
+	@echo ""
+	@echo "make test"
+	@echo "   run all tests"
+	@echo ""
+	@echo "make tests2.all / make tests2.37 / make tests2.37+"
+	@echo "   run all/single test(s) from tests2, optionally update .expect"
+	@echo ""
+	@echo "Other supported make targets:"
+	@echo "   install install-strip tags ETAGS tar clean distclean help"
+	@echo ""
+
+# --------------------------------------------------------------------------
+endif # ($(INCLUDED),no)
Index: EcnlProtoTool/trunk/tcc-0.9.27/README
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/README	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/README	(revision 331)
@@ -29,5 +29,5 @@
 -------------
 
-1) Installation on a i386 Linux host (for Windows read tcc-win32.txt)
+1) Installation on a i386/x86_64/arm Linux/OSX/FreeBSD host
 
    ./configure
@@ -36,16 +36,10 @@
    make install
 
-Alternatively, out-of-tree builds are supported: you may use different
-directories to hold build objects, kept separate from your source tree:
+   Notes: For OSX and FreeBSD, gmake should be used instead of make.
+   For Windows read tcc-win32.txt.
 
-   mkdir _build
-   cd _build
-   ../configure
-   make
-   make test
-   make install
-
-By default, tcc is installed in /usr/local/bin.
-./configure --help  shows configuration options.
+makeinfo must be installed to compile the doc.  By default, tcc is
+installed in /usr/local/bin.  ./configure --help  shows configuration
+options.
 
 
Index: EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING	(revision 331)
@@ -0,0 +1,60 @@
+
+ Relicensing TinyCC
+ ------------------
+
+ The authors listed below hereby confirm their agreement to relicense TinyCC
+ including their past contributions under the following terms:
+
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+
+
+ Author (name)              I agree (YES/NO)    Files/Features (optional)
+ ------------------------------------------------------------------------------
+ Adam Sampson               YES                 makefiles
+ Daniel Gl旦ckner            NO                  arm-gen.c
+ Daniel Gl旦ckner            YES                 not arm-gen.c
+ Edmund Grimley Evans       YES                 arm64
+ Fabrice Bellard            YES                 original author
+ Fr辿d辿ric F辿ret             YES                 x86 64/16 bit asm
+ grischka                   YES                 tccpe.c
+ Henry Kroll                YES
+ Joe Soroka                 YES
+ Kirill Smelkov             YES
+ mingodad                   YES
+ Pip Cet                    YES
+ Shinichiro Hamaji          YES                 x86_64-gen.c
+ Vincent Lef竪vre            YES
+ Thomas Preud'homme         YES                 arm-gen.c
+ Timo VJ L辰hde (Timppa)     ?                   tiny_libmaker.c
+ TK                         ?                   tcccoff.c c67-gen.c
+ Urs Janssen                YES
+ waddlesplash               YES
+ Christian Jullien          YES                 Windows Cygwin build and tests
+
+
+ ------------------------------------------------------------------------------
+
+ Please add yourself to the list above (rsp. replace the question mark)
+ and (after fetching the latest version) commit to the "mob" branch with
+ commit message:
+
+     Relicensing TinyCC
+
+ Thanks.
Index: EcnlProtoTool/trunk/tcc-0.9.27/TODO
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/TODO	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/TODO	(revision 331)
@@ -3,15 +3,7 @@
 Bugs:
 
-- fix macro substitution with nested definitions (ShangHongzhang)
+- i386 fastcall is mostly wrong
 - FPU st(0) is left unclean (kwisatz haderach). Incompatible with
   optimized gcc/msc code
-
-- constructors
-- cast bug (Peter Wang)
-- define incomplete type if defined several times (Peter Wang).
-- configure --cc=tcc (still one bug in libtcc1.c)
-- test binutils/gcc compile
-- tci patch + argument.
-- see -lxxx bug (Michael Charity).
 - see transparent union pb in /urs/include/sys/socket.h
 - precise behaviour of typeof with arrays ? (__put_user macro)
@@ -22,5 +14,4 @@
   (net/ipv4/ip_output.c)
 - fix function pointer type display
-- check lcc test suite -> fix bitfield binary operations
 - check section alignment in C
 - fix invalid cast in comparison 'if (v == (int8_t)v)'
@@ -28,11 +19,23 @@
 - fix static functions declared inside block
 - fix multiple unions init
-- sizeof, alignof, typeof can still generate code in some cases.
-- Fix the remaining libtcc memory leaks.
 - make libtcc fully reentrant (except for the compilation stage itself).
+- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
+- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
+- memory may be leaked after errors (longjmp).
+
+Portability:
+
+- it is assumed that int is 32-bit and sizeof(int) == 4
+- int is used when host or target size_t would make more sense
+- TCC handles target floating-point (fp) values using the host's fp
+  arithmetic, which is simple and fast but may lead to exceptions
+  and inaccuracy and wrong representations when cross-compiling
+
+Linking:
+
+- static linking (-static) does not work
 
 Bound checking:
 
-- '-b' bug.
 - fix bound exit on RedHat 7.3
 - setjmp is not supported properly in bound checking.
@@ -46,9 +49,8 @@
 - disable-asm and disable-bcheck options
 - __builtin_expect()
-- improve '-E' option.
 - atexit (Nigel Horne)
-- packed attribute
 - C99: add complex types (gcc 3.2 testsuite issue)
 - postfix compound literals (see 20010124-1.c)
+- interactive mode / integrated debugger
 
 Optimizations:
@@ -66,9 +68,7 @@
   boolean variable to tell if compound literal was already
   initialized).
-- add PowerPC or ARM code generator and improve codegen for RISC (need
+- add PowerPC generator and improve codegen for RISC (need
   to suppress VT_LOCAL and use a base register instead).
-- interactive mode / integrated debugger
 - fix preprocessor symbol redefinition
-- better constant opt (&&, ||, ?:)
 - add portable byte code generator and interpreter for other
   unsupported architectures.
@@ -77,4 +77,6 @@
   check exception code (exception filter func).
 - handle void (__attribute__() *ptr)()
+- VLAs are implemented in a way that is not compatible with signals:
+  http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
 
 Fixed (probably):
@@ -92,2 +94,7 @@
 - function pointers/lvalues in ? : (linux kernel net/core/dev.c)
 - win32: add __stdcall, check GetModuleHandle for dlls.
+- macro substitution with nested definitions (ShangHongzhang)
+- with "-run" and libtcc, a PLT is now built.
+- '-E' option was improved
+- packed attribute is now supported
+- ARM and ARM64 code generators have been added.
Index: EcnlProtoTool/trunk/tcc-0.9.27/VERSION
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/VERSION	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/VERSION	(revision 331)
@@ -1,1 +1,1 @@
-0.9.26
+0.9.27
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c	(revision 331)
@@ -0,0 +1,94 @@
+/*************************************************************/
+/*
+ *  ARM dummy assembler for TCC
+ *
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+#define CONFIG_TCC_ASM
+#define NB_ASM_REGS 16
+
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+
+/*************************************************************/
+#else
+/*************************************************************/
+
+#include "tcc.h"
+
+static void asm_error(void)
+{
+    tcc_error("ARM asm not implemented.");
+}
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+    int ind1;
+    if (nocode_wanted)
+        return;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+ST_FUNC void gen_le16 (int i)
+{
+    g(i);
+    g(i>>8);
+}
+
+ST_FUNC void gen_le32 (int i)
+{
+    gen_le16(i);
+    gen_le16(i>>16);
+}
+
+ST_FUNC void gen_expr32(ExprValue *pe)
+{
+    gen_le32(pe->v);
+}
+
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
+{
+    asm_error();
+}
+
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
+{
+    asm_error();
+}
+
+/* generate prolog and epilog code for asm statement */
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
+                         int nb_outputs, int is_output,
+                         uint8_t *clobber_regs,
+                         int out_reg)
+{
+}
+
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
+                                    int nb_operands, int nb_outputs,
+                                    const uint8_t *clobber_regs,
+                                    int *pout_reg)
+{
+}
+
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+    asm_error();
+}
+
+ST_FUNC int asm_parse_regvar (int t)
+{
+    asm_error();
+    return -1;
+}
+
+/*************************************************************/
+#endif /* ndef TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/arm-gen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c	(revision 331)
@@ -1,5 +1,5 @@
 /*
  *  ARMv4 code generator for TCC
- * 
+ *
  *  Copyright (c) 2003 Daniel Glöckner
  *  Copyright (c) 2012 Thomas Preud'homme
@@ -24,8 +24,6 @@
 #ifdef TARGET_DEFS_ONLY
 
-#ifdef TCC_ARM_EABI
-#ifndef TCC_ARM_VFP // Avoid useless warning
-#define TCC_ARM_VFP
-#endif
+#if defined(TCC_ARM_EABI) && !defined(TCC_ARM_VFP)
+#error "Currently TinyCC only supports float computation with VFP instructions"
 #endif
 
@@ -37,6 +35,6 @@
 #endif
 
-#ifndef TCC_ARM_VERSION
-# define TCC_ARM_VERSION 5
+#ifndef TCC_CPU_VERSION
+# define TCC_CPU_VERSION 5
 #endif
 
@@ -47,5 +45,5 @@
 #define RC_FLOAT   0x0002 /* generic float register */
 #define RC_R0      0x0004
-#define RC_R1      0x0008 
+#define RC_R1      0x0008
 #define RC_R2      0x0010
 #define RC_R3      0x0020
@@ -82,4 +80,6 @@
     TREG_F7,
 #endif
+    TREG_SP = 13,
+    TREG_LR,
 };
 
@@ -105,5 +105,5 @@
 /* defined if structures are passed as pointers. Otherwise structures
    are directly pushed on stack. */
-//#define FUNC_STRUCT_PARAM_AS_PTR
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
 
 /* pointer size, in bytes */
@@ -131,21 +131,9 @@
 
 /******************************************************/
-/* ELF defines */
-
-#define EM_TCC_TARGET EM_ARM
-
-/* relocation type for 32 bit data relocation */
-#define R_DATA_32   R_ARM_ABS32
-#define R_DATA_PTR  R_ARM_ABS32
-#define R_JMP_SLOT  R_ARM_JUMP_SLOT
-#define R_COPY      R_ARM_COPY
-
-#define ELF_START_ADDR 0x00008000
-#define ELF_PAGE_SIZE  0x1000
-
-/******************************************************/
 #else /* ! TARGET_DEFS_ONLY */
 /******************************************************/
 #include "tcc.h"
+
+enum float_abi float_abi;
 
 ST_DATA const int reg_classes[NB_REGS] = {
@@ -172,5 +160,5 @@
 #if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
 static CType float_type, double_type, func_float_type, func_double_type;
-ST_FUNC void arm_init_types(void)
+ST_FUNC void arm_init(struct TCCState *s)
 {
     float_type.t = VT_FLOAT;
@@ -180,4 +168,9 @@
     func_double_type.t = VT_FUNC;
     func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
+
+    float_abi = s->float_abi;
+#ifndef TCC_ARM_HARDFLOAT
+    tcc_warning("soft float ABI currently not supported: default to softfp");
+#endif
 }
 #else
@@ -185,5 +178,17 @@
 #define func_double_type func_old_type
 #define func_ldouble_type func_old_type
-ST_FUNC void arm_init_types(void) {}
+ST_FUNC void arm_init(struct TCCState *s)
+{
+#if 0
+#if !defined (TCC_ARM_VFP)
+    tcc_warning("Support for FPA is deprecated and will be removed in next"
+                " release");
+#endif
+#if !defined (TCC_ARM_EABI)
+    tcc_warning("Support for OABI is deprecated and will be removed in next"
+                " release");
+#endif
+#endif
+}
 #endif
 
@@ -198,9 +203,20 @@
 /******************************************************/
 
-void o(unsigned int i)
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+const char *default_elfinterp(struct TCCState *s)
+{
+    if (s->float_abi == ARM_HARD_FLOAT)
+        return "/lib/ld-linux-armhf.so.3";
+    else
+        return "/lib/ld-linux.so.3";
+}
+#endif
+
+void o(uint32_t i)
 {
   /* this is a good place to start adding big-endian support*/
   int ind1;
-
+  if (nocode_wanted)
+    return;
   ind1 = ind + 4;
   if (!cur_text_section)
@@ -212,5 +228,5 @@
   i>>=8;
   cur_text_section->data[ind++] = i&255;
-  i>>=8; 
+  i>>=8;
   cur_text_section->data[ind++] = i&255;
   i>>=8;
@@ -328,5 +344,5 @@
 }
 
-ST_FUNC uint32_t encbranch(int pos, int addr, int fail)
+uint32_t encbranch(int pos, int addr, int fail)
 {
   addr-=pos+8;
@@ -377,5 +393,5 @@
   if(r<TREG_F0 || r>TREG_F7)
     tcc_error("compiler error! register %i is no vfp register",r);
-  return r-5;
+  return r - TREG_F0;
 }
 #else
@@ -384,5 +400,5 @@
   if(r<TREG_F0 || r>TREG_F3)
     tcc_error("compiler error! register %i is no fpa register",r);
-  return r-5;
+  return r - TREG_F0;
 }
 #endif
@@ -390,9 +406,11 @@
 static uint32_t intr(int r)
 {
-  if(r==4)
+  if(r == TREG_R12)
     return 12;
-  if((r<0 || r>4) && r!=14)
-    tcc_error("compiler error! register %i is no int register",r);
-  return r;
+  if(r >= TREG_R0 && r <= TREG_R3)
+    return r - TREG_R0;
+  if (r >= TREG_SP && r <= TREG_LR)
+    return r + (13 - TREG_SP);
+  tcc_error("compiler error! register %i is no int register",r);
 }
 
@@ -499,5 +517,5 @@
   fr = sv->r;
   ft = sv->type.t;
-  fc = sv->c.ul;
+  fc = sv->c.i;
 
   if(fc>=0)
@@ -507,5 +525,5 @@
     fc=-fc;
   }
-  
+
   v = fr & VT_VALMASK;
   if (fr & VT_LVAL) {
@@ -514,6 +532,7 @@
       v1.type.t = VT_PTR;
       v1.r = VT_LOCAL | VT_LVAL;
-      v1.c.ul = sv->c.ul;
-      load(base=14 /* lr */, &v1);
+      v1.c.i = sv->c.i;
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
       fc=sign=0;
       v=VT_LOCAL;
@@ -521,7 +540,8 @@
       v1.type.t = VT_PTR;
       v1.r = fr&~VT_LVAL;
-      v1.c.ul = sv->c.ul;
+      v1.c.i = sv->c.i;
       v1.sym=sv->sym;
-      load(base=14, &v1);
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
       fc=sign=0;
       v=VT_LOCAL;
@@ -572,5 +592,5 @@
 	if(!sign)
 	  op|=0x800000;
-        if ((ft & VT_BTYPE) == VT_BYTE)
+        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
           op|=0x400000;
         o(op|(intr(r)<<12)|fc|(base<<16));
@@ -580,5 +600,5 @@
   } else {
     if (v == VT_CONST) {
-      op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul);
+      op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
       if (fr & VT_SYM || !op) {
         o(0xE59F0000|(intr(r)<<12));
@@ -586,10 +606,10 @@
         if(fr & VT_SYM)
 	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
-        o(sv->c.ul);
+        o(sv->c.i);
       } else
         o(op);
       return;
     } else if (v == VT_LOCAL) {
-      op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul);
+      op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
       if (fr & VT_SYM || !op) {
 	o(0xE59F0000|(intr(r)<<12));
@@ -597,5 +617,5 @@
 	if(fr & VT_SYM) // needed ?
 	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
-	o(sv->c.ul);
+	o(sv->c.i);
 	o(0xE08B0000|(intr(r)<<12)|intr(r));
       } else
@@ -603,6 +623,6 @@
       return;
     } else if(v == VT_CMP) {
-      o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12));
-      o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12));
+      o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
+      o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
       return;
     } else if (v == VT_JMP || v == VT_JMPI) {
@@ -611,5 +631,5 @@
       o(0xE3A00000|(intr(r)<<12)|t);
       o(0xEA000000);
-      gsym(sv->c.ul);
+      gsym(sv->c.i);
       o(0xE3A00000|(intr(r)<<12)|(t^1));
       return;
@@ -638,5 +658,5 @@
   fr = sv->r;
   ft = sv->type.t;
-  fc = sv->c.ul;
+  fc = sv->c.i;
 
   if(fc>=0)
@@ -646,8 +666,8 @@
     fc=-fc;
   }
-  
-  v = fr & VT_VALMASK; 
+
+  v = fr & VT_VALMASK;
   if (fr & VT_LVAL || fr == VT_LOCAL) {
-    uint32_t base = 0xb;
+    uint32_t base = 0xb; /* fp */
     if(v < VT_CONST) {
       base=intr(v);
@@ -657,9 +677,10 @@
       v1.type.t = ft;
       v1.r = fr&~VT_LVAL;
-      v1.c.ul = sv->c.ul;
+      v1.c.i = sv->c.i;
       v1.sym=sv->sym;
-      load(base=14, &v1);
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
       fc=sign=0;
-      v=VT_LOCAL;   
+      v=VT_LOCAL;
     }
     if(v == VT_LOCAL) {
@@ -668,7 +689,7 @@
 #ifdef TCC_ARM_VFP
         op=0xED000A00; /* fsts */
-        if(!sign) 
-          op|=0x800000; 
-        if ((ft & VT_BTYPE) != VT_FLOAT) 
+        if(!sign)
+          op|=0x800000;
+        if ((ft & VT_BTYPE) != VT_FLOAT)
           op|=0x100;   /* fsts -> fstd */
         o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
@@ -700,5 +721,5 @@
 	if(!sign)
 	  op|=0x800000;
-        if ((ft & VT_BTYPE) == VT_BYTE)
+        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
           op|=0x400000;
         o(op|(intr(r)<<12)|fc|(base<<16));
@@ -722,5 +743,5 @@
     uint32_t x;
     /* constant case */
-    x=encbranch(ind,ind+vtop->c.ul,0);
+    x=encbranch(ind,ind+vtop->c.i,0);
     if(x) {
       if (vtop->r & VT_SYM) {
@@ -736,5 +757,5 @@
       if (vtop->r & VT_SYM)
 	greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
-      o(vtop->c.ul);
+      o(vtop->c.i);
     }
   } else {
@@ -747,6 +768,19 @@
 }
 
-#ifdef TCC_ARM_HARDFLOAT
-static int is_float_hgen_aggr(CType *type)
+static int unalias_ldbl(int btype)
+{
+#if LDOUBLE_SIZE == 8
+    if (btype == VT_LDOUBLE)
+      btype = VT_DOUBLE;
+#endif
+    return btype;
+}
+
+/* Return whether a structure is an homogeneous float aggregate or not.
+   The answer is true if all the elements of the structure are of the same
+   primitive float type and there is less than 4 elements.
+
+   type: the type corresponding to the structure to be tested */
+static int is_hgen_float_aggr(CType *type)
 {
   if ((type->t & VT_BTYPE) == VT_STRUCT) {
@@ -754,8 +788,8 @@
     int btype, nb_fields = 0;
 
-    ref = type->ref;
-    btype = ref->type.t & VT_BTYPE;
+    ref = type->ref->next;
+    btype = unalias_ldbl(ref->type.t & VT_BTYPE);
     if (btype == VT_FLOAT || btype == VT_DOUBLE) {
-      for(; ref && btype == (ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
+      for(; ref && btype == unalias_ldbl(ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
       return !ref && nb_fields <= 4;
     }
@@ -765,16 +799,22 @@
 
 struct avail_regs {
-  /* worst case: f(float, double, 3 float struct, double, 3 float struct, double) */
-  signed char avail[3];
-  int first_hole;
-  int last_hole;
-  int first_free_reg;
+  signed char avail[3]; /* 3 holes max with only float and double alignments */
+  int first_hole; /* first available hole */
+  int last_hole; /* last available hole (none if equal to first_hole) */
+  int first_free_reg; /* next free register in the sequence, hole excluded */
 };
 
 #define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
 
-/* Assign a register for a CPRC param with correct size and alignment
- * size and align are in bytes, as returned by type_size */
-int assign_fpreg(struct avail_regs *avregs, int align, int size)
+/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC
+   param) according to the rules described in the procedure call standard for
+   the ARM architecture (AAPCS). If found, the registers are assigned to this
+   VFP CPRC parameter. Registers are allocated in sequence unless a hole exists
+   and the parameter is a single float.
+
+   avregs: opaque structure to keep track of available VFP co-processor regs
+   align: alignment constraints for the param, as returned by type_size()
+   size: size of the parameter, as returned by type_size() */
+int assign_vfpreg(struct avail_regs *avregs, int align, int size)
 {
   int first_reg = 0;
@@ -782,9 +822,11 @@
   if (avregs->first_free_reg == -1)
     return -1;
-  if (align >> 3) { // alignment needed (base type: double)
+  if (align >> 3) { /* double alignment */
     first_reg = avregs->first_free_reg;
+    /* alignment constraint not respected so use next reg and record hole */
     if (first_reg & 1)
       avregs->avail[avregs->last_hole++] = first_reg++;
-  } else {
+  } else { /* no special alignment (float or array of float) */
+    /* if single float and a hole is available, assign the param to it */
     if (size == 4 && avregs->first_hole != avregs->last_hole)
       return avregs->avail[avregs->first_hole++];
@@ -799,62 +841,130 @@
   return -1;
 }
-#endif
-
-/* Generate function call. The function address is pushed first, then
-   all the parameters in call order. This functions pops all the
-   parameters and the function address. */
-void gfunc_call(int nb_args)
-{
-  int size, align, r, args_size, i, ncrn, ncprn, argno, vfp_argno;
-  signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
-  SValue *before_stack = NULL; /* SValue before first on stack argument */
-  SValue *before_vfpreg_hfa = NULL; /* SValue before first in VFP reg hfa argument */
-#ifdef TCC_ARM_HARDFLOAT
+
+/* Returns whether all params need to be passed in core registers or not.
+   This is the case for function part of the runtime ABI. */
+int floats_in_core_regs(SValue *sval)
+{
+  if (!sval->sym)
+    return 0;
+
+  switch (sval->sym->v) {
+    case TOK___floatundisf:
+    case TOK___floatundidf:
+    case TOK___fixunssfdi:
+    case TOK___fixunsdfdi:
+#ifndef TCC_ARM_VFP
+    case TOK___fixunsxfdi:
+#endif
+    case TOK___floatdisf:
+    case TOK___floatdidf:
+    case TOK___fixsfdi:
+    case TOK___fixdfdi:
+      return 1;
+
+    default:
+      return 0;
+  }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+#ifdef TCC_ARM_EABI
+    int size, align;
+    size = type_size(vt, &align);
+    if (float_abi == ARM_HARD_FLOAT && !variadic &&
+        (is_float(vt->t) || is_hgen_float_aggr(vt))) {
+        *ret_align = 8;
+	*regsize = 8;
+        ret->ref = NULL;
+        ret->t = VT_DOUBLE;
+        return (size + 7) >> 3;
+    } else if (size <= 4) {
+        *ret_align = 4;
+	*regsize = 4;
+        ret->ref = NULL;
+        ret->t = VT_INT;
+        return 1;
+    } else
+        return 0;
+#else
+    return 0;
+#endif
+}
+
+/* Parameters are classified according to how they are copied to their final
+   destination for the function call. Because the copying is performed class
+   after class according to the order in the union below, it is important that
+   some constraints about the order of the members of this union are respected:
+   - CORE_STRUCT_CLASS must come after STACK_CLASS;
+   - CORE_CLASS must come after STACK_CLASS, CORE_STRUCT_CLASS and
+     VFP_STRUCT_CLASS;
+   - VFP_STRUCT_CLASS must come after VFP_CLASS.
+   See the comment for the main loop in copy_params() for the reason. */
+enum reg_class {
+	STACK_CLASS = 0,
+	CORE_STRUCT_CLASS,
+	VFP_CLASS,
+	VFP_STRUCT_CLASS,
+	CORE_CLASS,
+	NB_CLASSES
+};
+
+struct param_plan {
+    int start; /* first reg or addr used depending on the class */
+    int end; /* last reg used or next free addr depending on the class */
+    SValue *sval; /* pointer to SValue on the value stack */
+    struct param_plan *prev; /*  previous element in this class */
+};
+
+struct plan {
+    struct param_plan *pplans; /* array of all the param plans */
+    struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */
+};
+
+#define add_param_plan(plan,pplan,class)                        \
+    do {                                                        \
+        pplan.prev = plan->clsplans[class];                     \
+        plan->pplans[plan ## _nb] = pplan;                      \
+        plan->clsplans[class] = &plan->pplans[plan ## _nb++];   \
+    } while(0)
+
+/* Assign parameters to registers and stack with alignment according to the
+   rules in the procedure call standard for the ARM architecture (AAPCS).
+   The overall assignment is recorded in an array of per parameter structures
+   called parameter plans. The parameter plans are also further organized in a
+   number of linked lists, one per class of parameter (see the comment for the
+   definition of union reg_class).
+
+   nb_args: number of parameters of the function for which a call is generated
+   float_abi: float ABI in use for this function call
+   plan: the structure where the overall assignment is recorded
+   todo: a bitmap that record which core registers hold a parameter
+
+   Returns the amount of stack space needed for parameter passing
+
+   Note: this function allocated an array in plan->pplans with tcc_malloc. It
+   is the responsibility of the caller to free this array once used (ie not
+   before copy_params). */
+static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
+{
+  int i, size, align;
+  int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
+  int plan_nb = 0;
+  struct param_plan pplan;
   struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
-  signed char vfp_plan[16];
-  int plan2[4+16];
-  int variadic;
-#else
-  int plan2[4]={0,0,0,0};
-#endif
-  int vfp_todo=0;
-  int todo=0, keep;
-
-#ifdef TCC_ARM_HARDFLOAT
-  memset(vfp_plan, -1, sizeof(vfp_plan));
-  memset(plan2, 0, sizeof(plan2));
-  variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
-#endif
-  r = vtop->r & VT_VALMASK;
-  if (r == VT_CMP || (r & ~1) == VT_JMP)
-    gv(RC_INT);
-#ifdef TCC_ARM_EABI
-  if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT
-     && type_size(&vtop[-nb_args].type.ref->type, &align) <= 4) {
-    SValue tmp;
-    tmp=vtop[-nb_args];
-    vtop[-nb_args]=vtop[-nb_args+1];
-    vtop[-nb_args+1]=tmp;
-    --nb_args;
-  }
-  
-  vpushi(0), nb_args++;
-  vtop->type.t = VT_LLONG;
-#endif
-  ncrn = ncprn = argno = vfp_argno = args_size = 0;
-  /* Assign argument to registers and stack with alignment.
-     If, considering alignment constraints, enough registers of the correct type
-     (core or VFP) are free for the current argument, assign them to it, else
-     allocate on stack with correct alignment. Whenever a structure is allocated
-     in registers or on stack, it is always put on the stack at this stage. The
-     stack is divided in 3 zones. The zone are, from low addresses to high
-     addresses: structures to be loaded in core registers, structures to be
-     loaded in VFP registers, argument allocated to stack. SValue's representing
-     structures in the first zone are moved just after the SValue pointed by
-     before_vfpreg_hfa. SValue's representing structures in the second zone are
-     moved just after the SValue pointer by before_stack. */
+
+  ncrn = nsaa = 0;
+  *todo = 0;
+  plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
+  memset(plan->clsplans, 0, sizeof(plan->clsplans));
   for(i = nb_args; i-- ;) {
-    int j, assigned_vfpreg = 0;
-    size = type_size(&vtop[-i].type, &align);
+    int j, start_vfpreg = 0;
+    CType type = vtop[-i].type;
+    type.t &= ~VT_ARRAY;
+    size = type_size(&type, &align);
+    size = (size + 3) & ~3;
+    align = (align + 3) & ~3;
     switch(vtop[-i].type.t & VT_BTYPE) {
       case VT_STRUCT:
@@ -862,76 +972,42 @@
       case VT_DOUBLE:
       case VT_LDOUBLE:
-#ifdef TCC_ARM_HARDFLOAT
-      if (!variadic) {
-        int hfa = 0; /* Homogeneous float aggregate */
+      if (float_abi == ARM_HARD_FLOAT) {
+        int is_hfa = 0; /* Homogeneous float aggregate */
 
         if (is_float(vtop[-i].type.t)
-            || (hfa = is_float_hgen_aggr(&vtop[-i].type))) {
-          int end_reg;
-
-          assigned_vfpreg = assign_fpreg(&avregs, align, size);
-          end_reg = assigned_vfpreg + (size - 1) / 4;
-          if (assigned_vfpreg >= 0) {
-            vfp_plan[vfp_argno++]=TREG_F0 + assigned_vfpreg/2;
-            if (hfa) {
-              /* before_stack can only have been set because all core registers
-                 are assigned, so no need to care about before_vfpreg_hfa if
-                 before_stack is set */
-              if (before_stack) {
-	        vrote(&vtop[-i], &vtop[-i] - before_stack);
-                before_stack++;
-              } else if (!before_vfpreg_hfa)
-                before_vfpreg_hfa = &vtop[-i-1];
-              for (j = assigned_vfpreg; j <= end_reg; j++)
-                vfp_todo|=(1<<j);
-            }
+            || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
+          int end_vfpreg;
+
+          start_vfpreg = assign_vfpreg(&avregs, align, size);
+          end_vfpreg = start_vfpreg + ((size - 1) >> 2);
+          if (start_vfpreg >= 0) {
+            pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
+            if (is_hfa)
+              add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
+            else
+              add_param_plan(plan, pplan, VFP_CLASS);
             continue;
-          } else {
-            if (!hfa)
-              vfp_argno++;
-            /* No need to update before_stack as no more hfa can be allocated in
-               VFP regs */
-            if (!before_vfpreg_hfa)
-              before_vfpreg_hfa = &vtop[-i-1];
+          } else
             break;
-          }
         }
       }
-#endif
-      ncrn = (ncrn + (align-1)/4) & -(align/4);
-      size = (size + 3) & -4;
-      if (ncrn + size/4 <= 4 || (ncrn < 4 && assigned_vfpreg != -1)) {
-        /* Either there is HFA in VFP registers, or there is arguments on stack,
-           it cannot be both. Hence either before_stack already points after
-           the slot where the vtop[-i] SValue is moved, or before_stack will not
-           be used */
-        if (before_vfpreg_hfa) {
-	  vrote(&vtop[-i], &vtop[-i] - before_vfpreg_hfa);
-          before_vfpreg_hfa++;
-        }
+      ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1);
+      if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
+        /* The parameter is allocated both in core register and on stack. As
+	 * such, it can be of either class: it would either be the last of
+	 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
         for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
-          todo|=(1<<j);
-        ncrn+=size/4;
-        if (ncrn > 4) {
-          args_size = (ncrn - 4) * 4;
-          if (!before_stack)
-            before_stack = &vtop[-i-1];
-        }
-      }
-      else {
+          *todo|=(1<<j);
+        pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
+        add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
+        ncrn += size/4;
+        if (ncrn > 4)
+          nsaa = (ncrn - 4) * 4;
+      } else {
         ncrn = 4;
-        /* No need to set before_vfpreg_hfa if not set since there will no
-           longer be any structure assigned to core registers */
-        if (!before_stack)
-          before_stack = &vtop[-i-1];
         break;
       }
       continue;
       default:
-#ifdef TCC_ARM_EABI
-      if (!i) {
-        break;
-      }
-#endif
       if (ncrn < 4) {
         int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
@@ -939,205 +1015,253 @@
         if (is_long) {
           ncrn = (ncrn + 1) & -2;
-          if (ncrn == 4) {
-            argno++;
+          if (ncrn == 4)
             break;
+        }
+        pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
+        ncrn++;
+        if (is_long)
+          pplan.end = ncrn++;
+        add_param_plan(plan, pplan, CORE_CLASS);
+        continue;
+      }
+    }
+    nsaa = (nsaa + (align - 1)) & ~(align - 1);
+    pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
+    add_param_plan(plan, pplan, STACK_CLASS);
+    nsaa += size; /* size already rounded up before */
+  }
+  return nsaa;
+}
+
+#undef add_param_plan
+
+/* Copy parameters to their final destination (core reg, VFP reg or stack) for
+   function call.
+
+   nb_args: number of parameters the function take
+   plan: the overall assignment plan for parameters
+   todo: a bitmap indicating what core reg will hold a parameter
+
+   Returns the number of SValue added by this function on the value stack */
+static int copy_params(int nb_args, struct plan *plan, int todo)
+{
+  int size, align, r, i, nb_extra_sval = 0;
+  struct param_plan *pplan;
+  int pass = 0;
+
+   /* Several constraints require parameters to be copied in a specific order:
+      - structures are copied to the stack before being loaded in a reg;
+      - floats loaded to an odd numbered VFP reg are first copied to the
+        preceding even numbered VFP reg and then moved to the next VFP reg.
+
+      It is thus important that:
+      - structures assigned to core regs must be copied after parameters
+        assigned to the stack but before structures assigned to VFP regs because
+        a structure can lie partly in core registers and partly on the stack;
+      - parameters assigned to the stack and all structures be copied before
+        parameters assigned to a core reg since copying a parameter to the stack
+        require using a core reg;
+      - parameters assigned to VFP regs be copied before structures assigned to
+        VFP regs as the copy might use an even numbered VFP reg that already
+        holds part of a structure. */
+again:
+  for(i = 0; i < NB_CLASSES; i++) {
+    for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
+
+      if (pass
+          && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
+        continue;
+
+      vpushv(pplan->sval);
+      pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
+      switch(i) {
+        case STACK_CLASS:
+        case CORE_STRUCT_CLASS:
+        case VFP_STRUCT_CLASS:
+          if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
+            int padding = 0;
+            size = type_size(&pplan->sval->type, &align);
+            /* align to stack align size */
+            size = (size + 3) & ~3;
+            if (i == STACK_CLASS && pplan->prev)
+              padding = pplan->start - pplan->prev->end;
+            size += padding; /* Add padding if any */
+            /* allocate the necessary size on stack */
+            gadd_sp(-size);
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore(); /* memcpy to current sp + potential padding */
+
+            /* Homogeneous float aggregate are loaded to VFP registers
+               immediately since there is no way of loading data in multiple
+               non consecutive VFP registers as what is done for other
+               structures (see the use of todo). */
+            if (i == VFP_STRUCT_CLASS) {
+              int first = pplan->start, nb = pplan->end - first + 1;
+              /* vpop.32 {pplan->start, ..., pplan->end} */
+              o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
+              /* No need to write the register used to a SValue since VFP regs
+                 cannot be used for gcall_or_jmp */
+            }
+          } else {
+            if (is_float(pplan->sval->type.t)) {
+#ifdef TCC_ARM_VFP
+              r = vfpr(gv(RC_FLOAT)) << 12;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+              else {
+                size = 8;
+                r |= 0x101; /* vpush.32 -> vpush.64 */
+              }
+              o(0xED2D0A01 + r); /* vpush */
+#else
+              r = fpr(gv(RC_FLOAT)) << 12;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+              else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
+                size = 8;
+              else
+                size = LDOUBLE_SIZE;
+
+              if (size == 12)
+                r |= 0x400000;
+              else if(size == 8)
+                r|=0x8000;
+
+              o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
+#endif
+            } else {
+              /* simple type (currently always same size) */
+              /* XXX: implicit cast ? */
+              size=4;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+                lexpand_nr();
+                size = 8;
+                r = gv(RC_INT);
+                o(0xE52D0004|(intr(r)<<12)); /* push r */
+                vtop--;
+              }
+              r = gv(RC_INT);
+              o(0xE52D0004|(intr(r)<<12)); /* push r */
+            }
+            if (i == STACK_CLASS && pplan->prev)
+              gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
           }
+          break;
+
+        case VFP_CLASS:
+          gv(regmask(TREG_F0 + (pplan->start >> 1)));
+          if (pplan->start & 1) { /* Must be in upper part of double register */
+            o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
+            vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
+          }
+          break;
+
+        case CORE_CLASS:
+          if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+            lexpand_nr();
+            gv(regmask(pplan->end));
+            pplan->sval->r2 = vtop->r;
+            vtop--;
+          }
+          gv(regmask(pplan->start));
+          /* Mark register as used so that gcall_or_jmp use another one
+             (regs >=4 are free as never used to pass parameters) */
+          pplan->sval->r = vtop->r;
+          break;
+      }
+      vtop--;
+    }
+  }
+
+  /* second pass to restore registers that were saved on stack by accident.
+     Maybe redundant after the "lvalue_save" patch in tccgen.c:gv() */
+  if (++pass < 2)
+    goto again;
+
+  /* Manually free remaining registers since next parameters are loaded
+   * manually, without the help of gv(int). */
+  save_regs(nb_args);
+
+  if(todo) {
+    o(0xE8BD0000|todo); /* pop {todo} */
+    for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
+      int r;
+      pplan->sval->r = pplan->start;
+      /* An SValue can only pin 2 registers at best (r and r2) but a structure
+         can occupy more than 2 registers. Thus, we need to push on the value
+         stack some fake parameter to have on SValue for each registers used
+         by a structure (r2 is not used). */
+      for (r = pplan->start + 1; r <= pplan->end; r++) {
+        if (todo & (1 << r)) {
+          nb_extra_sval++;
+          vpushi(0);
+          vtop->r = r;
         }
-        plan[argno++][0]=ncrn++;
-        if (is_long) {
-          plan[argno-1][1]=ncrn++;
-        }
-        continue;
-      }
-      argno++;
-    }
+      }
+    }
+  }
+  return nb_extra_sval;
+}
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+  int r, args_size;
+  int def_float_abi = float_abi;
+  int todo;
+  struct plan plan;
+
 #ifdef TCC_ARM_EABI
-    if(args_size & (align-1)) {
-      vpushi(0);
-      vtop->type.t = VT_VOID; /* padding */
-      vrott(i+2);
-      args_size += 4;
-      nb_args++;
-      argno++;
-    }
-#endif
-    args_size += (size + 3) & -4;
-  }
+  int variadic;
+
+  if (float_abi == ARM_HARD_FLOAT) {
+    variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
+    if (variadic || floats_in_core_regs(&vtop[-nb_args]))
+      float_abi = ARM_SOFTFP_FLOAT;
+  }
+#endif
+  /* cannot let cpu flags if other instruction are generated. Also avoid leaving
+     VT_JMP anywhere except on the top of the stack because it would complicate
+     the code generator. */
+  r = vtop->r & VT_VALMASK;
+  if (r == VT_CMP || (r & ~1) == VT_JMP)
+    gv(RC_INT);
+
+  args_size = assign_regs(nb_args, float_abi, &plan, &todo);
+
 #ifdef TCC_ARM_EABI
-  vtop--, nb_args--;
-#endif
-  args_size = keep = 0;
-  for(i = 0;i < nb_args; i++) {
-    vrotb(keep+1);
-    if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
-      size = type_size(&vtop->type, &align);
-      /* align to stack align size */
-      size = (size + 3) & -4;
-      /* allocate the necessary size on stack */
-      gadd_sp(-size);
-      /* generate structure store */
-      r = get_reg(RC_INT);
-      o(0xE1A0000D|(intr(r)<<12));
-      vset(&vtop->type, r | VT_LVAL, 0);
-      vswap();
-      vstore();
-      vtop--;
-      args_size += size;
-    } else if (is_float(vtop->type.t)) {
-#ifdef TCC_ARM_HARDFLOAT
-      if (!variadic && --vfp_argno<16 && vfp_plan[vfp_argno]!=-1) {
-        plan2[keep++]=vfp_plan[vfp_argno];
-        continue;
-      }
-#endif
-#ifdef TCC_ARM_VFP
-      r=vfpr(gv(RC_FLOAT))<<12;
-      size=4;
-      if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
-      {
-        size=8;
-        r|=0x101; /* fstms -> fstmd */
-      }
-      o(0xED2D0A01+r);
-#else
-      r=fpr(gv(RC_FLOAT))<<12;
-      if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
-        size = 4;
-      else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
-        size = 8;
-      else
-        size = LDOUBLE_SIZE;
-      
-      if (size == 12)
-	r|=0x400000;
-      else if(size == 8)
-	r|=0x8000;
-
-      o(0xED2D0100|r|(size>>2));
-#endif
-      vtop--;
-      args_size += size;
-    } else {
-      int s;
-      /* simple type (currently always same size) */
-      /* XXX: implicit cast ? */
-      size=4;
-      if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
-	lexpand_nr();
-	s=-1;
-	if(--argno<4 && plan[argno][1]!=-1)
-	  s=plan[argno][1];
-	argno++;
-	size = 8;
-	if(s==-1) {
-	  r = gv(RC_INT);
-	  o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
-	  vtop--;
-	} else {
-	  size=0;
-	  plan2[keep]=s;
-	  keep++;
-          vswap();
-	}
-      }
-      s=-1;
-      if(--argno<4 && plan[argno][0]!=-1)
-        s=plan[argno][0];
-#ifdef TCC_ARM_EABI
-      if(vtop->type.t == VT_VOID) {
-        if(s == -1)
-          o(0xE24DD004); /* sub sp,sp,#4 */
-        vtop--;
-      } else
-#endif
-      if(s == -1) {
-	r = gv(RC_INT);
-	o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
-	vtop--;
-      } else {
-        size=0;
-	plan2[keep]=s;
-	keep++;
-      }
-      args_size += size;
-    }
-  }
-  for(i = 0; i < keep; i++) {
-    vrotb(keep);
-    gv(regmask(plan2[i]));
-#ifdef TCC_ARM_HARDFLOAT
-    /* arg is in s(2d+1): plan2[i]<plan2[i+1] => alignment occured (ex f,d,f) */
-    if (i < keep - 1 && is_float(vtop->type.t) && (plan2[i] <= plan2[i + 1])) {
-      o(0xEEF00A40|(vfpr(plan2[i])<<12)|vfpr(plan2[i]));
-    }
-#endif
-  }
-save_regs(keep); /* save used temporary registers */
-  keep++;
-  if(ncrn) {
-    int nb_regs=0;
-    if (ncrn>4)
-      ncrn=4;
-    todo&=((1<<ncrn)-1);
-    if(todo) {
-      int i;
-      o(0xE8BD0000|todo);
-      for(i=0;i<4;i++)
-	if(todo&(1<<i)) {
-	  vpushi(0);
-	  vtop->r=i;
-	  keep++;
-	  nb_regs++;
-	}
-    }
-    args_size-=nb_regs*4;
-  }
-  if(vfp_todo) {
-    int nb_fregs=0;
-
-    for(i=0;i<16;i++)
-      if(vfp_todo&(1<<i)) {
-        o(0xED9D0A00|(i&1)<<22|(i>>1)<<12|nb_fregs);
-        vpushi(0);
-        /* There might be 2 floats in a double VFP reg but that doesn't seem
-           to matter */
-        if (!(i%2))
-          vtop->r=TREG_F0+i/2;
-        keep++;
-        nb_fregs++;
-      }
-    if (nb_fregs) {
-      gadd_sp(nb_fregs*4);
-      args_size-=nb_fregs*4;
-    }
-  }
-  vrotb(keep);
+  if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
+    args_size = (args_size + 7) & ~7;
+    o(0xE24DD004); /* sub sp, sp, #4 */
+  }
+#endif
+
+  nb_args += copy_params(nb_args, &plan, todo);
+  tcc_free(plan.pplans);
+
+  /* Move fct SValue on top as required by gcall_or_jmp */
+  vrotb(nb_args + 1);
   gcall_or_jmp(0);
   if (args_size)
-      gadd_sp(args_size);
-#ifdef TCC_ARM_EABI
-  if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT
-     && type_size(&vtop->type.ref->type, &align) <= 4)
-  {
-    store(REG_IRET,vtop-keep);
-    ++keep;
-  }
-#ifdef TCC_ARM_VFP
-#ifdef TCC_ARM_HARDFLOAT
-  else if(variadic && is_float(vtop->type.ref->type.t)) {
-#else
-  else if(is_float(vtop->type.ref->type.t)) {
-#endif
+      gadd_sp(args_size); /* pop all parameters passed on the stack */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+  if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
     if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
-      o(0xEE000A10); /* fmsr s0,r0 */
+      o(0xEE000A10); /*vmov s0, r0 */
     } else {
-      o(0xEE000B10); /* fmdlr d0,r0 */
-      o(0xEE201B10); /* fmdhr d0,r1 */
-    }
-  }
-#endif
-#endif
-  vtop-=keep;
-  leaffunc = 0;
+      o(0xEE000B10); /* vmov.32 d0[0], r0 */
+      o(0xEE201B10); /* vmov.32 d0[1], r1 */
+    }
+  }
+#endif
+  vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
+  leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
+  float_abi = def_float_abi;
 }
 
@@ -1146,6 +1270,9 @@
 {
   Sym *sym,*sym2;
-  int n,nf,size,align, variadic, struct_ret = 0;
-#ifdef TCC_ARM_HARDFLOAT
+  int n, nf, size, align, rs, struct_ret = 0;
+  int addr, pn, sn; /* pn=core, sn=stack */
+  CType ret_type;
+
+#ifdef TCC_ARM_EABI
   struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
 #endif
@@ -1153,9 +1280,9 @@
   sym = func_type->ref;
   func_vt = sym->type;
+  func_var = (func_type->ref->f.func_type == FUNC_ELLIPSIS);
 
   n = nf = 0;
-  variadic = (func_type->ref->c == FUNC_ELLIPSIS);
-  if((func_vt.t & VT_BTYPE) == VT_STRUCT
-     && type_size(&func_vt,&align) > 4)
+  if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
+      !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
   {
     n++;
@@ -1163,10 +1290,11 @@
     func_vc = 12; /* Offset from fp of the place to store the result */
   }
-  for(sym2=sym->next;sym2 && (n<4 || nf<16);sym2=sym2->next) {
+  for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
     size = type_size(&sym2->type, &align);
-#ifdef TCC_ARM_HARDFLOAT
-    if (!variadic && (is_float(sym2->type.t)
-        || is_float_hgen_aggr(&sym2->type))) {
-      int tmpnf = assign_fpreg(&avregs, align, size) + 1;
+#ifdef TCC_ARM_EABI
+    if (float_abi == ARM_HARD_FLOAT && !func_var &&
+        (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
+      int tmpnf = assign_vfpreg(&avregs, align, size);
+      tmpnf += (size + 3) / 4;
       nf = (tmpnf > nf) ? tmpnf : nf;
     } else
@@ -1176,7 +1304,7 @@
   }
   o(0xE1A0C00D); /* mov ip,sp */
-  if(variadic)
+  if (func_var)
     n=4;
-  if(n) {
+  if (n) {
     if(n>4)
       n=4;
@@ -1195,47 +1323,47 @@
   o(0xE1A0B00D); /* mov fp, sp */
   func_sub_sp_offset = ind;
-  o(0xE1A00000); /* nop, leave space for stack adjustment in epilogue */
-  {
-    int addr, pn = struct_ret, sn = 0; /* pn=core, sn=stack */
-
-#ifdef TCC_ARM_HARDFLOAT
+  o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
+
+#ifdef TCC_ARM_EABI
+  if (float_abi == ARM_HARD_FLOAT) {
+    func_vc += nf * 4;
     avregs = AVAIL_REGS_INITIALIZER;
-#endif
-    while ((sym = sym->next)) {
-      CType *type;
-      type = &sym->type;
-      size = type_size(type, &align);
-      size = (size + 3) >> 2;
-      align = (align + 3) & ~3;
-#ifdef TCC_ARM_HARDFLOAT
-      if (!variadic && (is_float(sym->type.t)
-          || is_float_hgen_aggr(&sym->type))) {
-        int fpn = assign_fpreg(&avregs, align, size << 2);
-        if (fpn >= 0) {
-          addr = fpn * 4;
-        } else
-          goto from_stack;
-      } else
-#endif
-      if (pn < 4) {
+  }
+#endif
+  pn = struct_ret, sn = 0;
+  while ((sym = sym->next)) {
+    CType *type;
+    type = &sym->type;
+    size = type_size(type, &align);
+    size = (size + 3) >> 2;
+    align = (align + 3) & ~3;
+#ifdef TCC_ARM_EABI
+    if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
+        || is_hgen_float_aggr(&sym->type))) {
+      int fpn = assign_vfpreg(&avregs, align, size << 2);
+      if (fpn >= 0)
+        addr = fpn * 4;
+      else
+        goto from_stack;
+    } else
+#endif
+    if (pn < 4) {
 #ifdef TCC_ARM_EABI
         pn = (pn + (align-1)/4) & -(align/4);
 #endif
-        addr = (nf + pn) * 4;
-        pn += size;
-        if (!sn && pn > 4)
-          sn = (pn - 4);
-      } else {
-#ifdef TCC_ARM_HARDFLOAT
+      addr = (nf + pn) * 4;
+      pn += size;
+      if (!sn && pn > 4)
+        sn = (pn - 4);
+    } else {
+#ifdef TCC_ARM_EABI
 from_stack:
-#endif
-#ifdef TCC_ARM_EABI
         sn = (sn + (align-1)/4) & -(align/4);
 #endif
-        addr = (n + nf + sn) * 4;
-        sn += size;
-      }
-      sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr+12);
-    }
+      addr = (n + nf + sn) * 4;
+      sn += size;
+    }
+    sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
+             addr + 12);
   }
   last_itod_magic=0;
@@ -1249,8 +1377,8 @@
   uint32_t x;
   int diff;
-#ifdef TCC_ARM_EABI
-  /* Useless but harmless copy of the float result into main register(s) in case
-     of variadic function in the hardfloat variant */
-  if(is_float(func_vt.t)) {
+  /* Copy float return value to core register if base standard is used and
+     float computation is made with VFP */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+  if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
     if((func_vt.t & VT_BTYPE) == VT_FLOAT)
       o(0xEE100A10); /* fmrs r0, s0 */
@@ -1287,4 +1415,6 @@
 {
   int r;
+  if (nocode_wanted)
+    return t;
   r=ind;
   o(0xE0000000|encbranch(r,t,1));
@@ -1303,7 +1433,11 @@
   int v, r;
   uint32_t op;
+
   v = vtop->r & VT_VALMASK;
   r=ind;
-  if (v == VT_CMP) {
+
+  if (nocode_wanted) {
+    ;
+  } else if (v == VT_CMP) {
     op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
     op|=encbranch(r,t,1);
@@ -1332,27 +1466,4 @@
       gsym(vtop->c.i);
     }
-  } else {
-    if (is_float(vtop->type.t)) {
-      r=gv(RC_FLOAT);
-#ifdef TCC_ARM_VFP
-      o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */
-      o(0xEEF1FA10); /* fmstat */
-#else
-      o(0xEE90F118|(fpr(r)<<16));
-#endif
-      vtop->r = VT_CMP;
-      vtop->c.i = TOK_NE;
-      return gtst(inv, t);
-    } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-      /* constant jmp optimization */
-      if ((vtop->c.i != 0) != inv) 
-	t = gjmp(t);
-    } else {
-      v = gv(RC_INT);
-      o(0xE3300000|(intr(v)<<16));
-      vtop->r = VT_CMP;
-      vtop->c.i = TOK_NE;
-      return gtst(inv, t);
-    }   
   }
   vtop--;
@@ -1543,5 +1654,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
- *    two operands are guaranted to have the same floating point type */
+ *    two operands are guaranteed to have the same floating point type */
 void gen_opf(int op)
 {
@@ -1612,5 +1723,5 @@
         case TOK_UGT: op=TOK_GT; break;
       }
-      
+
       vtop->r = VT_CMP;
       vtop->c.i = op;
@@ -1673,5 +1784,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
-   two operands are guaranted to have the same floating point type */
+   two operands are guaranteed to have the same floating point type */
 void gen_opf(int op)
 {
@@ -1763,5 +1874,5 @@
 	vswap();
 	r2=fpr(gv(RC_FLOAT));
-      }     
+      }
       break;
     default:
@@ -1775,5 +1886,5 @@
 	  case TOK_ULE:
 	  case TOK_UGT:
-            tcc_error("unsigned comparision on floats?");
+            tcc_error("unsigned comparison on floats?");
 	    break;
 	  case TOK_LT:
@@ -2000,4 +2111,39 @@
 }
 
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    SValue v;
+    v.type.t = VT_PTR;
+    v.r = VT_LOCAL | VT_LVAL;
+    v.c.i = addr;
+    store(TREG_SP, &v);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    SValue v;
+    v.type.t = VT_PTR;
+    v.r = VT_LOCAL | VT_LVAL;
+    v.c.i = addr;
+    load(TREG_SP, &v);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    int r = intr(gv(RC_INT));
+    o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
+#ifdef TCC_ARM_EABI
+    if (align < 8)
+        align = 8;
+#else
+    if (align < 4)
+        align = 4;
+#endif
+    if (align & (align - 1))
+        tcc_error("alignment is not a power of 2: %i", align);
+    o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
+    vpop();
+}
+
 /* end of ARM code generator */
 /*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c	(revision 331)
@@ -0,0 +1,398 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_ARM
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_ARM_ABS32
+#define R_DATA_PTR  R_ARM_ABS32
+#define R_JMP_SLOT  R_ARM_JUMP_SLOT
+#define R_GLOB_DAT  R_ARM_GLOB_DAT
+#define R_COPY      R_ARM_COPY
+#define R_RELATIVE  R_ARM_RELATIVE
+
+#define R_NUM       R_ARM_NUM
+
+#define ELF_START_ADDR 0x00008000
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 0
+
+enum float_abi {
+    ARM_SOFTFP_FLOAT,
+    ARM_HARD_FLOAT,
+};
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_ARM_MOVT_ABS:
+	case R_ARM_MOVW_ABS_NC:
+	case R_ARM_THM_MOVT_ABS:
+	case R_ARM_THM_MOVW_ABS_NC:
+	case R_ARM_ABS32:
+	case R_ARM_REL32:
+	case R_ARM_GOTPC:
+	case R_ARM_GOTOFF:
+	case R_ARM_GOT32:
+	case R_ARM_COPY:
+	case R_ARM_GLOB_DAT:
+	case R_ARM_NONE:
+            return 0;
+
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+	case R_ARM_JUMP24:
+	case R_ARM_PLT32:
+	case R_ARM_THM_PC22:
+	case R_ARM_THM_JUMP24:
+	case R_ARM_PREL31:
+	case R_ARM_V4BX:
+	case R_ARM_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_ARM_NONE:
+	case R_ARM_COPY:
+	case R_ARM_GLOB_DAT:
+	case R_ARM_JUMP_SLOT:
+            return NO_GOTPLT_ENTRY;
+
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+	case R_ARM_JUMP24:
+	case R_ARM_PLT32:
+	case R_ARM_THM_PC22:
+	case R_ARM_THM_JUMP24:
+	case R_ARM_MOVT_ABS:
+	case R_ARM_MOVW_ABS_NC:
+	case R_ARM_THM_MOVT_ABS:
+	case R_ARM_THM_MOVW_ABS_NC:
+	case R_ARM_PREL31:
+	case R_ARM_ABS32:
+	case R_ARM_REL32:
+	case R_ARM_V4BX:
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_ARM_GOTPC:
+	case R_ARM_GOTOFF:
+            return BUILD_GOT_ONLY;
+
+	case R_ARM_GOT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    unsigned plt_offset;
+
+    /* when building a DLL, GOT entry accesses must be done relative to
+       start of GOT (see x86_64 example above)  */
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        tcc_error("DLLs unimplemented!");
+
+    /* empty PLT: create PLT0 entry that push address of call site and
+       jump to ld.so resolution routine (GOT + 8) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 20);
+        write32le(p,    0xe52de004); /* push {lr}         */
+        write32le(p+4,  0xe59fe004); /* ldr lr, [pc, #4] */
+        write32le(p+8,  0xe08fe00e); /* add lr, pc, lr    */
+        write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
+        /* p+16 is set in relocate_plt */
+    }
+    plt_offset = plt->data_offset;
+
+    if (attr->plt_thumb_stub) {
+        p = section_ptr_add(plt, 4);
+        write32le(p,   0x4778); /* bx pc */
+        write32le(p+2, 0x46c0); /* nop   */
+    }
+    p = section_ptr_add(plt, 16);
+    /* Jump to GOT entry where ld.so initially put address of PLT0 */
+    write32le(p,   0xe59fc004); /* ldr ip, [pc, #4] */
+    write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
+    write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
+    /* p + 12 contains offset to GOT entry once patched by relocate_plt */
+    write32le(p+12, got_offset);
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
+        write32le(s1->plt->data + 16, x - 16);
+        p += 20;
+        while (p < p_end) {
+            if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
+                p += 4;
+            add32le(p + 12, x + s1->plt->data - p);
+            p += 16;
+        }
+    }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    ElfW(Sym) *sym;
+    int sym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+    switch(type) {
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+        case R_ARM_JUMP24:
+        case R_ARM_PLT32:
+            {
+                int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
+                x = (*(int *) ptr) & 0xffffff;
+#ifdef DEBUG_RELOC
+		printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
+#endif
+                (*(int *)ptr) &= 0xff000000;
+                if (x & 0x800000)
+                    x -= 0x1000000;
+                x <<= 2;
+                blx_avail = (TCC_CPU_VERSION >= 5);
+                is_thumb = val & 1;
+                is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
+                is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
+                x += val - addr;
+#ifdef DEBUG_RELOC
+		printf (" newx=0x%x name=%s\n", x,
+			(char *) symtab_section->link->data + sym->st_name);
+#endif
+                h = x & 2;
+                th_ko = (x & 3) && (!blx_avail || !is_call);
+                if (th_ko || x >= 0x2000000 || x < -0x2000000)
+                    tcc_error("can't relocate value at %x,%d",addr, type);
+                x >>= 2;
+                x &= 0xffffff;
+                /* Only reached if blx is avail and it is a call */
+                if (is_thumb) {
+                    x |= h << 24;
+                    (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
+                }
+                (*(int *) ptr) |= x;
+            }
+            return;
+        /* Since these relocations only concern Thumb-2 and blx instruction was
+           introduced before Thumb-2, we can assume blx is available and not
+           guard its use */
+        case R_ARM_THM_PC22:
+        case R_ARM_THM_JUMP24:
+            {
+                int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
+                int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
+                Section *plt;
+
+                /* weak reference */
+                if (sym->st_shndx == SHN_UNDEF &&
+                    ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+                    return;
+
+                /* Get initial offset */
+                hi = (*(uint16_t *)ptr);
+                lo = (*(uint16_t *)(ptr+2));
+                s = (hi >> 10) & 1;
+                j1 = (lo >> 13) & 1;
+                j2 = (lo >> 11) & 1;
+                i1 = (j1 ^ s) ^ 1;
+                i2 = (j2 ^ s) ^ 1;
+                imm10 = hi & 0x3ff;
+                imm11 = lo & 0x7ff;
+                x = (s << 24) | (i1 << 23) | (i2 << 22) |
+                    (imm10 << 12) | (imm11 << 1);
+                if (x & 0x01000000)
+                    x -= 0x02000000;
+
+                /* Relocation infos */
+                to_thumb = val & 1;
+                plt = s1->plt;
+                to_plt = (val >= plt->sh_addr) &&
+                         (val < plt->sh_addr + plt->data_offset);
+                is_call = (type == R_ARM_THM_PC22);
+
+                if (!to_thumb && !to_plt && !is_call) {
+                    int index;
+                    uint8_t *p;
+                    char *name, buf[1024];
+                    Section *text_section;
+
+                    name = (char *) symtab_section->link->data + sym->st_name;
+                    text_section = s1->sections[sym->st_shndx];
+                    /* Modify reloc to target a thumb stub to switch to ARM */
+                    snprintf(buf, sizeof(buf), "%s_from_thumb", name);
+                    index = put_elf_sym(symtab_section,
+                                        text_section->data_offset + 1,
+                                        sym->st_size, sym->st_info, 0,
+                                        sym->st_shndx, buf);
+                    to_thumb = 1;
+                    val = text_section->data_offset + 1;
+                    rel->r_info = ELFW(R_INFO)(index, type);
+                    /* Create a thumb stub function to switch to ARM mode */
+                    put_elf_reloc(symtab_section, text_section,
+                                  text_section->data_offset + 4, R_ARM_JUMP24,
+                                  sym_index);
+                    p = section_ptr_add(text_section, 8);
+                    write32le(p,   0x4778); /* bx pc */
+                    write32le(p+2, 0x46c0); /* nop   */
+                    write32le(p+4, 0xeafffffe); /* b $sym */
+                }
+
+                /* Compute final offset */
+                x += val - addr;
+                if (!to_thumb && is_call) {
+                    blx_bit = 0; /* bl -> blx */
+                    x = (x + 3) & -4; /* Compute offset from aligned PC */
+                }
+
+                /* Check that relocation is possible
+                   * offset must not be out of range
+                   * if target is to be entered in arm mode:
+                     - bit 1 must not set
+                     - instruction must be a call (bl) or a jump to PLT */
+                if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
+                    if (to_thumb || (val & 2) || (!is_call && !to_plt))
+                        tcc_error("can't relocate value at %x,%d",addr, type);
+
+                /* Compute and store final offset */
+                s = (x >> 24) & 1;
+                i1 = (x >> 23) & 1;
+                i2 = (x >> 22) & 1;
+                j1 = s ^ (i1 ^ 1);
+                j2 = s ^ (i2 ^ 1);
+                imm10 = (x >> 12) & 0x3ff;
+                imm11 = (x >> 1) & 0x7ff;
+                (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
+                                     (s << 10) | imm10);
+                (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
+                                (j1 << 13) | blx_bit | (j2 << 11) |
+                                imm11);
+            }
+            return;
+        case R_ARM_MOVT_ABS:
+        case R_ARM_MOVW_ABS_NC:
+            {
+                int x, imm4, imm12;
+                if (type == R_ARM_MOVT_ABS)
+                    val >>= 16;
+                imm12 = val & 0xfff;
+                imm4 = (val >> 12) & 0xf;
+                x = (imm4 << 16) | imm12;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    *(int *)ptr |= x;
+                else
+                    *(int *)ptr += x;
+            }
+            return;
+        case R_ARM_THM_MOVT_ABS:
+        case R_ARM_THM_MOVW_ABS_NC:
+            {
+                int x, i, imm4, imm3, imm8;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    val >>= 16;
+                imm8 = val & 0xff;
+                imm3 = (val >> 8) & 0x7;
+                i = (val >> 11) & 1;
+                imm4 = (val >> 12) & 0xf;
+                x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    *(int *)ptr |= x;
+                else
+                    *(int *)ptr += x;
+            }
+            return;
+        case R_ARM_PREL31:
+            {
+                int x;
+                x = (*(int *)ptr) & 0x7fffffff;
+                (*(int *)ptr) &= 0x80000000;
+                x = (x * 2) / 2;
+                x += val - addr;
+                if((x^(x>>1))&0x40000000)
+                    tcc_error("can't relocate value at %x,%d",addr, type);
+                (*(int *)ptr) |= x & 0x7fffffff;
+            }
+        case R_ARM_ABS32:
+            *(int *)ptr += val;
+            return;
+        case R_ARM_REL32:
+            *(int *)ptr += val - addr;
+            return;
+        case R_ARM_GOTPC:
+            *(int *)ptr += s1->got->sh_addr - addr;
+            return;
+        case R_ARM_GOTOFF:
+            *(int *)ptr += val - s1->got->sh_addr;
+            return;
+        case R_ARM_GOT32:
+            /* we load the got offset */
+            *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
+            return;
+        case R_ARM_COPY:
+            return;
+        case R_ARM_V4BX:
+            /* trade Thumb support for ARMv4 support */
+            if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
+                *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
+            return;
+        case R_ARM_GLOB_DAT:
+        case R_ARM_JUMP_SLOT:
+            *(addr_t *)ptr = val;
+            return;
+        case R_ARM_NONE:
+            /* Nothing to do.  Normally used to indicate a dependency
+               on a certain symbol (like for exception handling under EABI).  */
+            return;
+        case R_ARM_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+                type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c	(revision 331)
@@ -0,0 +1,1837 @@
+/*
+ *  A64 code generator for TCC
+ *
+ *  Copyright (c) 2014-2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+// Number of registers available to allocator:
+#define NB_REGS 28 // x0-x18, x30, v0-v7
+
+#define TREG_R(x) (x) // x = 0..18
+#define TREG_R30  19
+#define TREG_F(x) (x + 20) // x = 0..7
+
+// Register classes sorted from more general to more precise:
+#define RC_INT (1 << 0)
+#define RC_FLOAT (1 << 1)
+#define RC_R(x) (1 << (2 + (x))) // x = 0..18
+#define RC_R30  (1 << 21)
+#define RC_F(x) (1 << (22 + (x))) // x = 0..7
+
+#define RC_IRET (RC_R(0)) // int return register class
+#define RC_FRET (RC_F(0)) // float return register class
+
+#define REG_IRET (TREG_R(0)) // int return register number
+#define REG_FRET (TREG_F(0)) // float return register number
+
+#define PTR_SIZE 8
+
+#define LDOUBLE_SIZE 16
+#define LDOUBLE_ALIGN 16
+
+#define MAX_ALIGN 16
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+  RC_INT | RC_R(0),
+  RC_INT | RC_R(1),
+  RC_INT | RC_R(2),
+  RC_INT | RC_R(3),
+  RC_INT | RC_R(4),
+  RC_INT | RC_R(5),
+  RC_INT | RC_R(6),
+  RC_INT | RC_R(7),
+  RC_INT | RC_R(8),
+  RC_INT | RC_R(9),
+  RC_INT | RC_R(10),
+  RC_INT | RC_R(11),
+  RC_INT | RC_R(12),
+  RC_INT | RC_R(13),
+  RC_INT | RC_R(14),
+  RC_INT | RC_R(15),
+  RC_INT | RC_R(16),
+  RC_INT | RC_R(17),
+  RC_INT | RC_R(18),
+  RC_R30, // not in RC_INT as we make special use of x30
+  RC_FLOAT | RC_F(0),
+  RC_FLOAT | RC_F(1),
+  RC_FLOAT | RC_F(2),
+  RC_FLOAT | RC_F(3),
+  RC_FLOAT | RC_F(4),
+  RC_FLOAT | RC_F(5),
+  RC_FLOAT | RC_F(6),
+  RC_FLOAT | RC_F(7)
+};
+
+#define IS_FREG(x) ((x) >= TREG_F(0))
+
+static uint32_t intr(int r)
+{
+    assert(TREG_R(0) <= r && r <= TREG_R30);
+    return r < TREG_R30 ? r : 30;
+}
+
+static uint32_t fltr(int r)
+{
+    assert(TREG_F(0) <= r && r <= TREG_F(7));
+    return r - TREG_F(0);
+}
+
+// Add an instruction to text section:
+ST_FUNC void o(unsigned int c)
+{
+    int ind1 = ind + 4;
+    if (nocode_wanted)
+        return;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    write32le(cur_text_section->data + ind, c);
+    ind = ind1;
+}
+
+static int arm64_encode_bimm64(uint64_t x)
+{
+    int neg = x & 1;
+    int rep, pos, len;
+
+    if (neg)
+        x = ~x;
+    if (!x)
+        return -1;
+
+    if (x >> 2 == (x & (((uint64_t)1 << (64 - 2)) - 1)))
+        rep = 2, x &= ((uint64_t)1 << 2) - 1;
+    else if (x >> 4 == (x & (((uint64_t)1 << (64 - 4)) - 1)))
+        rep = 4, x &= ((uint64_t)1 <<  4) - 1;
+    else if (x >> 8 == (x & (((uint64_t)1 << (64 - 8)) - 1)))
+        rep = 8, x &= ((uint64_t)1 <<  8) - 1;
+    else if (x >> 16 == (x & (((uint64_t)1 << (64 - 16)) - 1)))
+        rep = 16, x &= ((uint64_t)1 << 16) - 1;
+    else if (x >> 32 == (x & (((uint64_t)1 << (64 - 32)) - 1)))
+        rep = 32, x &= ((uint64_t)1 << 32) - 1;
+    else
+        rep = 64;
+
+    pos = 0;
+    if (!(x & (((uint64_t)1 << 32) - 1))) x >>= 32, pos += 32;
+    if (!(x & (((uint64_t)1 << 16) - 1))) x >>= 16, pos += 16;
+    if (!(x & (((uint64_t)1 <<  8) - 1))) x >>= 8, pos += 8;
+    if (!(x & (((uint64_t)1 <<  4) - 1))) x >>= 4, pos += 4;
+    if (!(x & (((uint64_t)1 <<  2) - 1))) x >>= 2, pos += 2;
+    if (!(x & (((uint64_t)1 <<  1) - 1))) x >>= 1, pos += 1;
+
+    len = 0;
+    if (!(~x & (((uint64_t)1 << 32) - 1))) x >>= 32, len += 32;
+    if (!(~x & (((uint64_t)1 << 16) - 1))) x >>= 16, len += 16;
+    if (!(~x & (((uint64_t)1 << 8) - 1))) x >>= 8, len += 8;
+    if (!(~x & (((uint64_t)1 << 4) - 1))) x >>= 4, len += 4;
+    if (!(~x & (((uint64_t)1 << 2) - 1))) x >>= 2, len += 2;
+    if (!(~x & (((uint64_t)1 << 1) - 1))) x >>= 1, len += 1;
+
+    if (x)
+        return -1;
+    if (neg) {
+        pos = (pos + len) & (rep - 1);
+        len = rep - len;
+    }
+    return ((0x1000 & rep << 6) | (((rep - 1) ^ 31) << 1 & 63) |
+            ((rep - pos) & (rep - 1)) << 6 | (len - 1));
+}
+
+static uint32_t arm64_movi(int r, uint64_t x)
+{
+    uint64_t m = 0xffff;
+    int e;
+    if (!(x & ~m))
+        return 0x52800000 | r | x << 5; // movz w(r),#(x)
+    if (!(x & ~(m << 16)))
+        return 0x52a00000 | r | x >> 11; // movz w(r),#(x >> 16),lsl #16
+    if (!(x & ~(m << 32)))
+        return 0xd2c00000 | r | x >> 27; // movz x(r),#(x >> 32),lsl #32
+    if (!(x & ~(m << 48)))
+        return 0xd2e00000 | r | x >> 43; // movz x(r),#(x >> 48),lsl #48
+    if ((x & ~m) == m << 16)
+        return (0x12800000 | r |
+                (~x << 5 & 0x1fffe0)); // movn w(r),#(~x)
+    if ((x & ~(m << 16)) == m)
+        return (0x12a00000 | r |
+                (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16
+    if (!~(x | m))
+        return (0x92800000 | r |
+                (~x << 5 & 0x1fffe0)); // movn x(r),#(~x)
+    if (!~(x | m << 16))
+        return (0x92a00000 | r |
+                (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16
+    if (!~(x | m << 32))
+        return (0x92c00000 | r |
+                (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+    if (!~(x | m << 48))
+        return (0x92e00000 | r |
+                (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+    if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0)
+        return 0x320003e0 | r | (uint32_t)e << 10; // movi w(r),#(x)
+    if ((e = arm64_encode_bimm64(x)) >= 0)
+        return 0xb20003e0 | r | (uint32_t)e << 10; // movi x(r),#(x)
+    return 0;
+}
+
+static void arm64_movimm(int r, uint64_t x)
+{
+    uint32_t i;
+    if ((i = arm64_movi(r, x)))
+        o(i); // a single MOV
+    else {
+        // MOVZ/MOVN and 1-3 MOVKs
+        int z = 0, m = 0;
+        uint32_t mov1 = 0xd2800000; // movz
+        uint64_t x1 = x;
+        for (i = 0; i < 64; i += 16) {
+            z += !(x >> i & 0xffff);
+            m += !(~x >> i & 0xffff);
+        }
+        if (m > z) {
+            x1 = ~x;
+            mov1 = 0x92800000; // movn
+        }
+        for (i = 0; i < 64; i += 16)
+            if (x1 >> i & 0xffff) {
+                o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
+                // movz/movn x(r),#(*),lsl #(i)
+                break;
+            }
+        for (i += 16; i < 64; i += 16)
+            if (x1 >> i & 0xffff)
+                o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
+                // movk x(r),#(*),lsl #(i)
+    }
+}
+
+// Patch all branches in list pointed to by t to branch to a:
+ST_FUNC void gsym_addr(int t_, int a_)
+{
+    uint32_t t = t_;
+    uint32_t a = a_;
+    while (t) {
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t next = read32le(ptr);
+        if (a - t + 0x8000000 >= 0x10000000)
+            tcc_error("branch out of range");
+        write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
+                        0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
+        t = next;
+    }
+}
+
+// Patch all branches in list pointed to by t to branch to current location:
+ST_FUNC void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+static int arm64_type_size(int t)
+{
+    switch (t & VT_BTYPE) {
+    case VT_INT: return 2;
+    case VT_BYTE: return 0;
+    case VT_SHORT: return 1;
+    case VT_PTR: return 3;
+    case VT_FUNC: return 3;
+    case VT_FLOAT: return 2;
+    case VT_DOUBLE: return 3;
+    case VT_LDOUBLE: return 4;
+    case VT_BOOL: return 0;
+    case VT_LLONG: return 3;
+    }
+    assert(0);
+    return 0;
+}
+
+static void arm64_spoff(int reg, uint64_t off)
+{
+    uint32_t sub = off >> 63;
+    if (sub)
+        off = -off;
+    if (off < 4096)
+        o(0x910003e0 | sub << 30 | reg | off << 10);
+        // (add|sub) x(reg),sp,#(off)
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
+    }
+}
+
+static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (sz >= 2)
+        sg = 0;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x39400000 | dst | bas << 5 | off << (10 - sz) |
+          (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |
+          (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |
+          (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |
+          (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_ldrs(int reg_, int size)
+{
+    uint32_t reg = reg_;
+    // Use x30 for intermediate value in some cases.
+    switch (size) {
+    default: assert(0); break;
+    case 1:
+        arm64_ldrx(0, 0, reg, reg, 0);
+        break;
+    case 2:
+        arm64_ldrx(0, 1, reg, reg, 0);
+        break;
+    case 3:
+        arm64_ldrx(0, 1, 30, reg, 0);
+        arm64_ldrx(0, 0, reg, reg, 2);
+        o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16
+        break;
+    case 4:
+        arm64_ldrx(0, 2, reg, reg, 0);
+        break;
+    case 5:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 0, reg, reg, 4);
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 6:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 1, reg, reg, 4);
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 7:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 2, reg, reg, 3);
+        o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 8:
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 9:
+        arm64_ldrx(0, 0, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 10:
+        arm64_ldrx(0, 1, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 11:
+        arm64_ldrx(0, 2, reg + 1, reg, 7);
+        o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 12:
+        arm64_ldrx(0, 2, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 13:
+        arm64_ldrx(0, 3, reg + 1, reg, 5);
+        o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 14:
+        arm64_ldrx(0, 3, reg + 1, reg, 6);
+        o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 15:
+        arm64_ldrx(0, 3, reg + 1, reg, 7);
+        o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 16:
+        o(0xa9400000 | reg | (reg+1) << 10 | reg << 5);
+        // ldp x(reg),x(reg+1),[x(reg)]
+        break;
+    }
+}
+
+static void arm64_strx(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
+        // str(*) x(dst),[x(bas],#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);
+        // stur(*) x(dst),[x(bas],#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
+        // str(*) x(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |
+          (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 |
+          (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_sym(int r, Sym *sym, unsigned long addend)
+{
+    // Currently TCC's linker does not generate COPY relocations for
+    // STT_OBJECTs when tcc is invoked with "-run". This typically
+    // results in "R_AARCH64_ADR_PREL_PG_HI21 relocation failed" when
+    // a program refers to stdin. A workaround is to avoid that
+    // relocation and use only relocations with unlimited range.
+    int avoid_adrp = 1;
+
+    if (avoid_adrp || sym->a.weak) {
+        // (GCC uses a R_AARCH64_ABS64 in this case.)
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend);
+        o(0xd2800000 | r); // mov x(rt),#0,lsl #0
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend);
+        o(0xf2a00000 | r); // movk x(rt),#0,lsl #16
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend);
+        o(0xf2c00000 | r); // movk x(rt),#0,lsl #32
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend);
+        o(0xf2e00000 | r); // movk x(rt),#0,lsl #48
+    }
+    else {
+        greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend);
+        o(0x90000000 | r);
+        greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend);
+        o(0x91000000 | r | r << 5);
+    }
+}
+
+ST_FUNC void load(int r, SValue *sv)
+{
+    int svtt = sv->type.t;
+    int svr = sv->r & ~VT_LVAL_TYPE;
+    int svrv = svr & VT_VALMASK;
+    uint64_t svcul = (uint32_t)sv->c.i;
+    svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+    if (svr == (VT_LOCAL | VT_LVAL)) {
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 29, svcul);
+        return;
+    }
+
+    if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), intr(svrv), 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+        arm64_sym(30, sv->sym, svcul); // use x30 for address
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 30, 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_SYM)) {
+        arm64_sym(intr(r), sv->sym, svcul);
+        return;
+    }
+
+    if (svr == VT_CONST) {
+        if ((svtt & VT_BTYPE) != VT_VOID)
+            arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ?
+                         sv->c.i : (uint32_t)svcul);
+        return;
+    }
+
+    if (svr < VT_CONST) {
+        if (IS_FREG(r) && IS_FREG(svr))
+            if (svtt == VT_LDOUBLE)
+                o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);
+                    // mov v(r).16b,v(svr).16b
+            else
+                o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
+        else if (!IS_FREG(r) && !IS_FREG(svr))
+            o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)
+        else
+            assert(0);
+      return;
+    }
+
+    if (svr == VT_LOCAL) {
+        if (-svcul < 0x1000)
+            o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...
+        else {
+            arm64_movimm(30, -svcul); // use x30 for offset
+            o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30
+        }
+        return;
+    }
+
+    if (svr == VT_JMP || svr == VT_JMPI) {
+        int t = (svr == VT_JMPI);
+        arm64_movimm(intr(r), t);
+        o(0x14000002); // b .+8
+        gsym(svcul);
+        arm64_movimm(intr(r), t ^ 1);
+        return;
+    }
+
+    if (svr == (VT_LLOCAL | VT_LVAL)) {
+        arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 30, 0);
+        return;
+    }
+
+    printf("load(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+    assert(0);
+}
+
+ST_FUNC void store(int r, SValue *sv)
+{
+    int svtt = sv->type.t;
+    int svr = sv->r & ~VT_LVAL_TYPE;
+    int svrv = svr & VT_VALMASK;
+    uint64_t svcul = (uint32_t)sv->c.i;
+    svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+    if (svr == (VT_LOCAL | VT_LVAL)) {
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul);
+        return;
+    }
+
+    if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+        arm64_sym(30, sv->sym, svcul); // use x30 for address
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), 30, 0);
+        return;
+    }
+
+    printf("store(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+    assert(0);
+}
+
+static void arm64_gen_bl_or_b(int b)
+{
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        assert(!b && (vtop->r & VT_SYM));
+	greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
+	o(0x94000000); // bl .
+    }
+    else
+        o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr
+}
+
+static int arm64_hfa_aux(CType *type, int *fsize, int num)
+{
+    if (is_float(type->t)) {
+        int a, n = type_size(type, &a);
+        if (num >= 4 || (*fsize && *fsize != n))
+            return -1;
+        *fsize = n;
+        return num + 1;
+    }
+    else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+        int is_struct = 0; // rather than union
+        Sym *field;
+        for (field = type->ref->next; field; field = field->next)
+            if (field->c) {
+                is_struct = 1;
+                break;
+            }
+        if (is_struct) {
+            int num0 = num;
+            for (field = type->ref->next; field; field = field->next) {
+                if (field->c != (num - num0) * *fsize)
+                    return -1;
+                num = arm64_hfa_aux(&field->type, fsize, num);
+                if (num == -1)
+                    return -1;
+            }
+            if (type->ref->c != (num - num0) * *fsize)
+                return -1;
+            return num;
+        }
+        else { // union
+            int num0 = num;
+            for (field = type->ref->next; field; field = field->next) {
+                int num1 = arm64_hfa_aux(&field->type, fsize, num0);
+                if (num1 == -1)
+                    return -1;
+                num = num1 < num ? num : num1;
+            }
+            if (type->ref->c != (num - num0) * *fsize)
+                return -1;
+            return num;
+        }
+    }
+    else if (type->t & VT_ARRAY) {
+        int num1;
+        if (!type->ref->c)
+            return num;
+        num1 = arm64_hfa_aux(&type->ref->type, fsize, num);
+        if (num1 == -1 || (num1 != num && type->ref->c > 4))
+            return -1;
+        num1 = num + type->ref->c * (num1 - num);
+        if (num1 > 4)
+            return -1;
+        return num1;
+    }
+    return -1;
+}
+
+static int arm64_hfa(CType *type, int *fsize)
+{
+    if ((type->t & VT_BTYPE) == VT_STRUCT || (type->t & VT_ARRAY)) {
+        int sz = 0;
+        int n = arm64_hfa_aux(type, &sz, 0);
+        if (0 < n && n <= 4) {
+            if (fsize)
+                *fsize = sz;
+            return n;
+        }
+    }
+    return 0;
+}
+
+static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a)
+{
+    int nx = 0; // next integer register
+    int nv = 0; // next vector register
+    unsigned long ns = 32; // next stack offset
+    int i;
+
+    for (i = 0; i < n; i++) {
+        int hfa = arm64_hfa(type[i], 0);
+        int size, align;
+
+        if ((type[i]->t & VT_ARRAY) ||
+            (type[i]->t & VT_BTYPE) == VT_FUNC)
+            size = align = 8;
+        else
+            size = type_size(type[i], &align);
+
+        if (hfa)
+            // B.2
+            ;
+        else if (size > 16) {
+            // B.3: replace with pointer
+            if (nx < 8)
+                a[i] = nx++ << 1 | 1;
+            else {
+                ns = (ns + 7) & ~7;
+                a[i] = ns | 1;
+                ns += 8;
+            }
+            continue;
+        }
+        else if ((type[i]->t & VT_BTYPE) == VT_STRUCT)
+            // B.4
+            size = (size + 7) & ~7;
+
+        // C.1
+        if (is_float(type[i]->t) && nv < 8) {
+            a[i] = 16 + (nv++ << 1);
+            continue;
+        }
+
+        // C.2
+        if (hfa && nv + hfa <= 8) {
+            a[i] = 16 + (nv << 1);
+            nv += hfa;
+            continue;
+        }
+
+        // C.3
+        if (hfa) {
+            nv = 8;
+            size = (size + 7) & ~7;
+        }
+
+        // C.4
+        if (hfa || (type[i]->t & VT_BTYPE) == VT_LDOUBLE) {
+            ns = (ns + 7) & ~7;
+            ns = (ns + align - 1) & -align;
+        }
+
+        // C.5
+        if ((type[i]->t & VT_BTYPE) == VT_FLOAT)
+            size = 8;
+
+        // C.6
+        if (hfa || is_float(type[i]->t)) {
+            a[i] = ns;
+            ns += size;
+            continue;
+        }
+
+        // C.7
+        if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size <= 8 && nx < 8) {
+            a[i] = nx++ << 1;
+            continue;
+        }
+
+        // C.8
+        if (align == 16)
+            nx = (nx + 1) & ~1;
+
+        // C.9
+        if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size == 16 && nx < 7) {
+            a[i] = nx << 1;
+            nx += 2;
+            continue;
+        }
+
+        // C.10
+        if ((type[i]->t & VT_BTYPE) == VT_STRUCT && size <= (8 - nx) * 8) {
+            a[i] = nx << 1;
+            nx += (size + 7) >> 3;
+            continue;
+        }
+
+        // C.11
+        nx = 8;
+
+        // C.12
+        ns = (ns + 7) & ~7;
+        ns = (ns + align - 1) & -align;
+
+        // C.13
+        if ((type[i]->t & VT_BTYPE) == VT_STRUCT) {
+            a[i] = ns;
+            ns += size;
+            continue;
+        }
+
+        // C.14
+        if (size < 8)
+            size = 8;
+
+        // C.15
+        a[i] = ns;
+        ns += size;
+    }
+
+    return ns - 32;
+}
+
+static unsigned long arm64_pcs(int n, CType **type, unsigned long *a)
+{
+    unsigned long stack;
+
+    // Return type:
+    if ((type[0]->t & VT_BTYPE) == VT_VOID)
+        a[0] = -1;
+    else {
+        arm64_pcs_aux(1, type, a);
+        assert(a[0] == 0 || a[0] == 1 || a[0] == 16);
+    }
+
+    // Argument types:
+    stack = arm64_pcs_aux(n, type + 1, a + 1);
+
+    if (0) {
+        int i;
+        for (i = 0; i <= n; i++) {
+            if (!i)
+                printf("arm64_pcs return: ");
+            else
+                printf("arm64_pcs arg %d: ", i);
+            if (a[i] == (unsigned long)-1)
+                printf("void\n");
+            else if (a[i] == 1 && !i)
+                printf("X8 pointer\n");
+            else if (a[i] < 16)
+                printf("X%lu%s\n", a[i] / 2, a[i] & 1 ? " pointer" : "");
+            else if (a[i] < 32)
+                printf("V%lu\n", a[i] / 2 - 8);
+            else
+                printf("stack %lu%s\n",
+                       (a[i] - 32) & ~1, a[i] & 1 ? " pointer" : "");
+        }
+    }
+
+    return stack;
+}
+
+ST_FUNC void gfunc_call(int nb_args)
+{
+    CType *return_type;
+    CType **t;
+    unsigned long *a, *a1;
+    unsigned long stack;
+    int i;
+
+    return_type = &vtop[-nb_args].type.ref->type;
+    if ((return_type->t & VT_BTYPE) == VT_STRUCT)
+        --nb_args;
+
+    t = tcc_malloc((nb_args + 1) * sizeof(*t));
+    a = tcc_malloc((nb_args + 1) * sizeof(*a));
+    a1 = tcc_malloc((nb_args + 1) * sizeof(*a1));
+
+    t[0] = return_type;
+    for (i = 0; i < nb_args; i++)
+        t[nb_args - i] = &vtop[-i].type;
+
+    stack = arm64_pcs(nb_args, t, a);
+
+    // Allocate space for structs replaced by pointer:
+    for (i = nb_args; i; i--)
+        if (a[i] & 1) {
+            SValue *arg = &vtop[i - nb_args];
+            int align, size = type_size(&arg->type, &align);
+            assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
+            stack = (stack + align - 1) & -align;
+            a1[i] = stack;
+            stack += size;
+        }
+
+    stack = (stack + 15) >> 4 << 4;
+
+    assert(stack < 0x1000);
+    if (stack)
+        o(0xd10003ff | stack << 10); // sub sp,sp,#(n)
+
+    // First pass: set all values on stack
+    for (i = nb_args; i; i--) {
+        vpushv(vtop - nb_args + i);
+
+        if (a[i] & 1) {
+            // struct replaced by pointer
+            int r = get_reg(RC_INT);
+            arm64_spoff(intr(r), a1[i]);
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore();
+            if (a[i] >= 32) {
+                // pointer on stack
+                r = get_reg(RC_INT);
+                arm64_spoff(intr(r), a1[i]);
+                arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1);
+            }
+        }
+        else if (a[i] >= 32) {
+            // value on stack
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                int r = get_reg(RC_INT);
+                arm64_spoff(intr(r), a[i] - 32);
+                vset(&vtop->type, r | VT_LVAL, 0);
+                vswap();
+                vstore();
+            }
+            else if (is_float(vtop->type.t)) {
+                gv(RC_FLOAT);
+                arm64_strv(arm64_type_size(vtop[0].type.t),
+                           fltr(vtop[0].r), 31, a[i] - 32);
+            }
+            else {
+                gv(RC_INT);
+                arm64_strx(arm64_type_size(vtop[0].type.t),
+                           intr(vtop[0].r), 31, a[i] - 32);
+            }
+        }
+
+        --vtop;
+    }
+
+    // Second pass: assign values to registers
+    for (i = nb_args; i; i--, vtop--) {
+        if (a[i] < 16 && !(a[i] & 1)) {
+            // value in general-purpose registers
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                int align, size = type_size(&vtop->type, &align);
+                vtop->type.t = VT_PTR;
+                gaddrof();
+                gv(RC_R(a[i] / 2));
+                arm64_ldrs(a[i] / 2, size);
+            }
+            else
+                gv(RC_R(a[i] / 2));
+        }
+        else if (a[i] < 16)
+            // struct replaced by pointer in register
+            arm64_spoff(a[i] / 2, a1[i]);
+        else if (a[i] < 32) {
+            // value in floating-point registers
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+                vtop->type.t = VT_PTR;
+                gaddrof();
+                gv(RC_R30);
+                for (j = 0; j < n; j++)
+                    o(0x3d4003c0 |
+                      (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      (a[i] / 2 - 8 + j) |
+                      j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]
+            }
+            else
+                gv(RC_F(a[i] / 2 - 8));
+        }
+    }
+
+    if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
+        if (a[0] == 1) {
+            // indirect return: set x8 and discard the stack value
+            gv(RC_R(8));
+            --vtop;
+        }
+        else
+            // return in registers: keep the address for after the call
+            vswap();
+    }
+
+    save_regs(0);
+    arm64_gen_bl_or_b(0);
+    --vtop;
+    if (stack)
+        o(0x910003ff | stack << 10); // add sp,sp,#(n)
+
+    {
+        int rt = return_type->t;
+        int bt = rt & VT_BTYPE;
+        if (bt == VT_BYTE || bt == VT_SHORT)
+            // Promote small integers:
+            o(0x13001c00 | (bt == VT_SHORT) << 13 |
+              (uint32_t)!!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0
+        else if (bt == VT_STRUCT && !(a[0] & 1)) {
+            // A struct was returned in registers, so write it out:
+            gv(RC_R(8));
+            --vtop;
+            if (a[0] == 0) {
+                int align, size = type_size(return_type, &align);
+                assert(size <= 16);
+                if (size > 8)
+                    o(0xa9000500); // stp x0,x1,[x8]
+                else if (size)
+                    arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);
+
+            }
+            else if (a[0] == 16) {
+                uint32_t j, sz, n = arm64_hfa(return_type, &sz);
+                for (j = 0; j < n; j++)
+                    o(0x3d000100 |
+                      (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      (a[i] / 2 - 8 + j) |
+                      j << 10); // str ([sdq])(*),[x8,#(j * sz)]
+            }
+        }
+    }
+
+    tcc_free(a1);
+    tcc_free(a);
+    tcc_free(t);
+}
+
+static unsigned long arm64_func_va_list_stack;
+static int arm64_func_va_list_gr_offs;
+static int arm64_func_va_list_vr_offs;
+static int arm64_func_sub_sp_offset;
+
+ST_FUNC void gfunc_prolog(CType *func_type)
+{
+    int n = 0;
+    int i = 0;
+    Sym *sym;
+    CType **t;
+    unsigned long *a;
+
+    // Why doesn't the caller (gen_function) set func_vt?
+    func_vt = func_type->ref->type;
+    func_vc = 144; // offset of where x8 is stored
+
+    for (sym = func_type->ref; sym; sym = sym->next)
+        ++n;
+    t = tcc_malloc(n * sizeof(*t));
+    a = tcc_malloc(n * sizeof(*a));
+
+    for (sym = func_type->ref; sym; sym = sym->next)
+        t[i++] = &sym->type;
+
+    arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
+
+    o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
+    o(0xad0087e0); // stp q0,q1,[sp,#16]
+    o(0xad018fe2); // stp q2,q3,[sp,#48]
+    o(0xad0297e4); // stp q4,q5,[sp,#80]
+    o(0xad039fe6); // stp q6,q7,[sp,#112]
+    o(0xa90923e8); // stp x8,x8,[sp,#144]
+    o(0xa90a07e0); // stp x0,x1,[sp,#160]
+    o(0xa90b0fe2); // stp x2,x3,[sp,#176]
+    o(0xa90c17e4); // stp x4,x5,[sp,#192]
+    o(0xa90d1fe6); // stp x6,x7,[sp,#208]
+
+    arm64_func_va_list_gr_offs = -64;
+    arm64_func_va_list_vr_offs = -128;
+
+    for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) {
+        int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :
+                   a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :
+                   224 + ((a[i] - 32) >> 1 << 1));
+        sym_push(sym->v & ~SYM_FIELD, &sym->type,
+                 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | lvalue_type(sym->type.t),
+                 off);
+
+        if (a[i] < 16) {
+            int align, size = type_size(&sym->type, &align);
+            arm64_func_va_list_gr_offs = (a[i] / 2 - 7 +
+                                          (!(a[i] & 1) && size > 8)) * 8;
+        }
+        else if (a[i] < 32) {
+            uint32_t hfa = arm64_hfa(&sym->type, 0);
+            arm64_func_va_list_vr_offs = (a[i] / 2 - 16 +
+                                          (hfa ? hfa : 1)) * 16;
+        }
+
+        // HFAs of float and double need to be written differently:
+        if (16 <= a[i] && a[i] < 32 && (sym->type.t & VT_BTYPE) == VT_STRUCT) {
+            uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
+            if (sz < 16)
+                for (j = 0; j < k; j++) {
+                    o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);
+                    // str ([sdq])(*),[sp,#(j * sz)]
+                }
+        }
+    }
+
+    tcc_free(a);
+    tcc_free(t);
+
+    o(0x910003fd); // mov x29,sp
+    arm64_func_sub_sp_offset = ind;
+    // In gfunc_epilog these will be replaced with code to decrement SP:
+    o(0xd503201f); // nop
+    o(0xd503201f); // nop
+    loc = 0;
+}
+
+ST_FUNC void gen_va_start(void)
+{
+    int r;
+    --vtop; // we don't need the "arg"
+    gaddrof();
+    r = intr(gv(RC_INT));
+
+    if (arm64_func_va_list_stack) {
+        //xx could use add (immediate) here
+        arm64_movimm(30, arm64_func_va_list_stack + 224);
+        o(0x8b1e03be); // add x30,x29,x30
+    }
+    else
+        o(0x910383be); // add x30,x29,#224
+    o(0xf900001e | r << 5); // str x30,[x(r)]
+
+    if (arm64_func_va_list_gr_offs) {
+        if (arm64_func_va_list_stack)
+            o(0x910383be); // add x30,x29,#224
+        o(0xf900041e | r << 5); // str x30,[x(r),#8]
+    }
+
+    if (arm64_func_va_list_vr_offs) {
+        o(0x910243be); // add x30,x29,#144
+        o(0xf900081e | r << 5); // str x30,[x(r),#16]
+    }
+
+    arm64_movimm(30, arm64_func_va_list_gr_offs);
+    o(0xb900181e | r << 5); // str w30,[x(r),#24]
+
+    arm64_movimm(30, arm64_func_va_list_vr_offs);
+    o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
+
+    --vtop;
+}
+
+ST_FUNC void gen_va_arg(CType *t)
+{
+    int align, size = type_size(t, &align);
+    int fsize, hfa = arm64_hfa(t, &fsize);
+    uint32_t r0, r1;
+
+    if (is_float(t->t)) {
+        hfa = 1;
+        fsize = size;
+    }
+
+    gaddrof();
+    r0 = intr(gv(RC_INT));
+    r1 = get_reg(RC_INT);
+    vtop[0].r = r1 | lvalue_type(t->t);
+    r1 = intr(r1);
+
+    if (!hfa) {
+        uint32_t n = size > 16 ? 8 : (size + 7) & -8;
+        o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
+        if (align == 16) {
+            assert(0); // this path untested but needed for __uint128_t
+            o(0x11003fde); // add w30,w30,#15
+            o(0x121c6fde); // and w30,w30,#-16
+        }
+        o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
+        o(0x540000ad); // b.le .+20
+        o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+        o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
+        o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+        o(0x14000004); // b .+16
+        o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
+        o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
+        o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+        if (size > 16)
+            o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
+    }
+    else {
+        uint32_t rsz = hfa << 4;
+        uint32_t ssz = (size + 7) & -(uint32_t)8;
+        uint32_t b1, b2;
+        o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
+        o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
+        b1 = ind; o(0x5400000d); // b.le lab1
+        o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+        if (fsize == 16) {
+            o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
+            o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
+        }
+        o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
+        o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+        b2 = ind; o(0x14000000); // b lab2
+        // lab1:
+        write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
+        o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
+        o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
+        if (hfa == 1 || fsize == 16)
+            o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+        else {
+            // We need to change the layout of this HFA.
+            // Get some space on the stack using global variable "loc":
+            loc = (loc - size) & -(uint32_t)align;
+            o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
+            arm64_movimm(r1, loc);
+            o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
+            o(0x4c402bdc | (uint32_t)fsize << 7 |
+              (uint32_t)(hfa == 2) << 15 |
+              (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
+            o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
+              (uint32_t)(hfa != 2) << 13 |
+              (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
+        }
+        // lab2:
+        write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
+    }
+}
+
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
+                       int *align, int *regsize)
+{
+    return 0;
+}
+
+ST_FUNC void gfunc_return(CType *func_type)
+{
+    CType *t = func_type;
+    unsigned long a;
+
+    arm64_pcs(0, &t, &a);
+    switch (a) {
+    case -1:
+        break;
+    case 0:
+        if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+            int align, size = type_size(func_type, &align);
+            gaddrof();
+            gv(RC_R(0));
+            arm64_ldrs(0, size);
+        }
+        else
+            gv(RC_IRET);
+        break;
+    case 1: {
+        CType type = *func_type;
+        mk_pointer(&type);
+        vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+        indir();
+        vswap();
+        vstore();
+        break;
+    }
+    case 16:
+        if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+          uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+          gaddrof();
+          gv(RC_R(0));
+          for (j = 0; j < n; j++)
+              o(0x3d400000 |
+                (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]
+        }
+        else
+            gv(RC_FRET);
+        break;
+    default:
+      assert(0);
+    }
+    vtop--;
+}
+
+ST_FUNC void gfunc_epilog(void)
+{
+    if (loc) {
+        // Insert instructions to subtract size of stack frame from SP.
+        unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
+        uint64_t diff = (-loc + 15) & ~15;
+        if (!(diff >> 24)) {
+            if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
+                write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
+            if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12
+                write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10);
+        }
+        else {
+            // In this case we may subtract more than necessary,
+            // but always less than 17/16 of what we were aiming for.
+            int i = 0;
+            int j = 0;
+            while (diff >> 20) {
+                diff = (diff + 0xffff) >> 16;
+                ++i;
+            }
+            while (diff >> 16) {
+                diff = (diff + 1) >> 1;
+                ++j;
+            }
+            write32le(ptr, 0xd2800010 | diff << 5 | i << 21);
+            // mov x16,#(diff),lsl #(16 * i)
+            write32le(ptr + 4, 0xcb3063ff | j << 10);
+            // sub sp,sp,x16,lsl #(j)
+        }
+    }
+    o(0x910003bf); // mov sp,x29
+    o(0xa8ce7bfd); // ldp x29,x30,[sp],#224
+
+    o(0xd65f03c0); // ret
+}
+
+// Generate forward branch to label:
+ST_FUNC int gjmp(int t)
+{
+    int r = ind;
+    if (nocode_wanted)
+        return t;
+    o(t);
+    return r;
+}
+
+// Generate branch to known address:
+ST_FUNC void gjmp_addr(int a)
+{
+    assert(a - ind + 0x8000000 < 0x10000000);
+    o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));
+}
+
+ST_FUNC int gtst(int inv, int t)
+{
+    int bt = vtop->type.t & VT_BTYPE;
+    if (bt == VT_LDOUBLE) {
+        uint32_t a, b, f = fltr(gv(RC_FLOAT));
+        a = get_reg(RC_INT);
+        vpushi(0);
+        vtop[0].r = a;
+        b = get_reg(RC_INT);
+        a = intr(a);
+        b = intr(b);
+        o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]
+        o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
+        o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
+        o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
+        --vtop;
+    }
+    else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
+        uint32_t a = fltr(gv(RC_FLOAT));
+        o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
+        o(0x54000040 | !!inv); // b.eq/b.ne .+8
+    }
+    else {
+        uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
+        uint32_t a = intr(gv(RC_INT));
+        o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
+    }
+    --vtop;
+    return gjmp(t);
+}
+
+static int arm64_iconst(uint64_t *val, SValue *sv)
+{
+    if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        return 0;
+    if (val) {
+        int t = sv->type.t;
+	int bt = t & VT_BTYPE;
+        *val = ((bt == VT_LLONG || bt == VT_PTR) ? sv->c.i :
+                (uint32_t)sv->c.i |
+                (t & VT_UNSIGNED ? 0 : -(sv->c.i & 0x80000000)));
+    }
+    return 1;
+}
+
+static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val,
+                          uint32_t x, uint32_t a)
+{
+    if (op == '-' && !rev) {
+        val = -val;
+        op = '+';
+    }
+    val = l ? val : (uint32_t)val;
+
+    switch (op) {
+
+    case '+': {
+        uint32_t s = l ? val >> 63 : val >> 31;
+        val = s ? -val : val;
+        val = l ? val : (uint32_t)val;
+        if (!(val & ~(uint64_t)0xfff))
+            o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
+        else if (!(val & ~(uint64_t)0xfff000))
+            o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
+        else {
+            arm64_movimm(30, val); // use x30
+            o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5);
+        }
+        return 1;
+      }
+
+    case '-':
+        if (!val)
+            o(0x4b0003e0 | l << 31 | x | a << 16); // neg
+        else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))
+            o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+        else {
+            arm64_movimm(30, val); // use x30
+            o(0x4b0003c0 | l << 31 | x | a << 16); // sub
+        }
+        return 1;
+
+    case '^':
+        if (val == -1 || (val == 0xffffffff && !l)) {
+            o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+            return 1;
+        }
+        // fall through
+    case '&':
+    case '|': {
+        int e = arm64_encode_bimm64(l ? val : val | val << 32);
+        if (e < 0)
+            return 0;
+        o((op == '&' ? 0x12000000 :
+           op == '|' ? 0x32000000 : 0x52000000) |
+          l << 31 | x | a << 5 | (uint32_t)e << 10);
+        return 1;
+    }
+
+    case TOK_SAR:
+    case TOK_SHL:
+    case TOK_SHR: {
+        uint32_t n = 32 << l;
+        val = val & (n - 1);
+        if (rev)
+            return 0;
+        if (!val)
+            assert(0);
+        else if (op == TOK_SHL)
+            o(0x53000000 | l << 31 | l << 22 | x | a << 5 |
+              (n - val) << 16 | (n - 1 - val) << 10); // lsl
+        else
+            o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |
+              x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr
+        return 1;
+    }
+
+    }
+    return 0;
+}
+
+static void arm64_gen_opil(int op, uint32_t l)
+{
+    uint32_t x, a, b;
+
+    // Special treatment for operations with a constant operand:
+    {
+        uint64_t val;
+        int rev = 1;
+
+        if (arm64_iconst(0, &vtop[0])) {
+            vswap();
+            rev = 0;
+        }
+        if (arm64_iconst(&val, &vtop[-1])) {
+            gv(RC_INT);
+            a = intr(vtop[0].r);
+            --vtop;
+            x = get_reg(RC_INT);
+            ++vtop;
+            if (arm64_gen_opic(op, l, rev, val, intr(x), a)) {
+                vtop[0].r = x;
+                vswap();
+                --vtop;
+                return;
+            }
+        }
+        if (!rev)
+            vswap();
+    }
+
+    gv2(RC_INT, RC_INT);
+    assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+    a = intr(vtop[-1].r);
+    b = intr(vtop[0].r);
+    vtop -= 2;
+    x = get_reg(RC_INT);
+    ++vtop;
+    vtop[0].r = x;
+    x = intr(x);
+
+    switch (op) {
+    case '%':
+        // Use x30 for quotient:
+        o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
+        o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+          b << 16 | a << 10); // msub
+        break;
+    case '&':
+        o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
+        break;
+    case '*':
+        o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul
+        break;
+    case '+':
+        o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add
+        break;
+    case '-':
+        o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub
+        break;
+    case '/':
+        o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv
+        break;
+    case '^':
+        o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor
+        break;
+    case '|':
+        o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr
+        break;
+    case TOK_EQ:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f17e0 | x); // cset wA,eq
+        break;
+    case TOK_GE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fb7e0 | x); // cset wA,ge
+        break;
+    case TOK_GT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fd7e0 | x); // cset wA,gt
+        break;
+    case TOK_LE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fc7e0 | x); // cset wA,le
+        break;
+    case TOK_LT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fa7e0 | x); // cset wA,lt
+        break;
+    case TOK_NE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f07e0 | x); // cset wA,ne
+        break;
+    case TOK_SAR:
+        o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr
+        break;
+    case TOK_SHL:
+        o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl
+        break;
+    case TOK_SHR:
+        o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr
+        break;
+    case TOK_UDIV:
+    case TOK_PDIV:
+        o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv
+        break;
+    case TOK_UGE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f37e0 | x); // cset wA,cs
+        break;
+    case TOK_UGT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f97e0 | x); // cset wA,hi
+        break;
+    case TOK_ULT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f27e0 | x); // cset wA,cc
+        break;
+    case TOK_ULE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f87e0 | x); // cset wA,ls
+        break;
+    case TOK_UMOD:
+        // Use x30 for quotient:
+        o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
+        o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+          b << 16 | a << 10); // msub
+        break;
+    default:
+        assert(0);
+    }
+}
+
+ST_FUNC void gen_opi(int op)
+{
+    arm64_gen_opil(op, 0);
+}
+
+ST_FUNC void gen_opl(int op)
+{
+    arm64_gen_opil(op, 1);
+}
+
+ST_FUNC void gen_opf(int op)
+{
+    uint32_t x, a, b, dbl;
+
+    if (vtop[0].type.t == VT_LDOUBLE) {
+        CType type = vtop[0].type;
+        int func = 0;
+        int cond = -1;
+        switch (op) {
+        case '*': func = TOK___multf3; break;
+        case '+': func = TOK___addtf3; break;
+        case '-': func = TOK___subtf3; break;
+        case '/': func = TOK___divtf3; break;
+        case TOK_EQ: func = TOK___eqtf2; cond = 1; break;
+        case TOK_NE: func = TOK___netf2; cond = 0; break;
+        case TOK_LT: func = TOK___lttf2; cond = 10; break;
+        case TOK_GE: func = TOK___getf2; cond = 11; break;
+        case TOK_LE: func = TOK___letf2; cond = 12; break;
+        case TOK_GT: func = TOK___gttf2; cond = 13; break;
+        default: assert(0); break;
+        }
+        vpush_global_sym(&func_old_type, func);
+        vrott(3);
+        gfunc_call(2);
+        vpushi(0);
+        vtop->r = cond < 0 ? REG_FRET : REG_IRET;
+        if (cond < 0)
+            vtop->type = type;
+        else {
+            o(0x7100001f); // cmp w0,#0
+            o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
+        }
+        return;
+    }
+
+    dbl = vtop[0].type.t != VT_FLOAT;
+    gv2(RC_FLOAT, RC_FLOAT);
+    assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+    a = fltr(vtop[-1].r);
+    b = fltr(vtop[0].r);
+    vtop -= 2;
+    switch (op) {
+    case TOK_EQ: case TOK_NE:
+    case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
+        x = get_reg(RC_INT);
+        ++vtop;
+        vtop[0].r = x;
+        x = intr(x);
+        break;
+    default:
+        x = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = x;
+        x = fltr(x);
+        break;
+    }
+
+    switch (op) {
+    case '*':
+        o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul
+        break;
+    case '+':
+        o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd
+        break;
+    case '-':
+        o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub
+        break;
+    case '/':
+        o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv
+        break;
+    case TOK_EQ:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f17e0 | x); // cset w(x),eq
+        break;
+    case TOK_GE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9fb7e0 | x); // cset w(x),ge
+        break;
+    case TOK_GT:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9fd7e0 | x); // cset w(x),gt
+        break;
+    case TOK_LE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f87e0 | x); // cset w(x),ls
+        break;
+    case TOK_LT:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f57e0 | x); // cset w(x),mi
+        break;
+    case TOK_NE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f07e0 | x); // cset w(x),ne
+        break;
+    default:
+        assert(0);
+    }
+}
+
+// Generate sign extension from 32 to 64 bits:
+ST_FUNC void gen_cvt_sxtw(void)
+{
+    uint32_t r = intr(gv(RC_INT));
+    o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
+}
+
+ST_FUNC void gen_cvt_itof(int t)
+{
+    if (t == VT_LDOUBLE) {
+        int f = vtop->type.t;
+        int func = (f & VT_BTYPE) == VT_LLONG ?
+          (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
+          (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_FRET;
+        return;
+    }
+    else {
+        int d, n = intr(gv(RC_INT));
+        int s = !(vtop->type.t & VT_UNSIGNED);
+        uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
+        --vtop;
+        d = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = d;
+        o(0x1e220000 | (uint32_t)!s << 16 |
+          (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
+          l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
+    }
+}
+
+ST_FUNC void gen_cvt_ftoi(int t)
+{
+    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+        int func = (t & VT_BTYPE) == VT_LLONG ?
+          (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
+          (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_IRET;
+        return;
+    }
+    else {
+        int d, n = fltr(gv(RC_FLOAT));
+        uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
+        --vtop;
+        d = get_reg(RC_INT);
+        ++vtop;
+        vtop[0].r = d;
+        o(0x1e380000 |
+          (uint32_t)!!(t & VT_UNSIGNED) << 16 |
+          (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
+          l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
+    }
+}
+
+ST_FUNC void gen_cvt_ftof(int t)
+{
+    int f = vtop[0].type.t;
+    assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
+    assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
+    if (t == f)
+        return;
+
+    if (t == VT_LDOUBLE || f == VT_LDOUBLE) {
+        int func = (t == VT_LDOUBLE) ?
+            (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
+            (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_FRET;
+    }
+    else {
+        int x, a;
+        gv(RC_FLOAT);
+        assert(vtop[0].r < VT_CONST);
+        a = fltr(vtop[0].r);
+        --vtop;
+        x = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = x;
+        x = fltr(x);
+
+        if (f == VT_FLOAT)
+            o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a)
+        else
+            o(0x1e624000 | x | a << 5); // fcvt s(x),d(a)
+    }
+}
+
+ST_FUNC void ggoto(void)
+{
+    arm64_gen_bl_or_b(1);
+    --vtop;
+}
+
+ST_FUNC void gen_clear_cache(void)
+{
+    uint32_t beg, end, dsz, isz, p, lab1, b1;
+    gv2(RC_INT, RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    beg = intr(vtop[-4].r); // x0
+    end = intr(vtop[-3].r); // x1
+    dsz = intr(vtop[-2].r); // x2
+    isz = intr(vtop[-1].r); // x3
+    p = intr(vtop[0].r);    // x4
+    vtop -= 5;
+
+    o(0xd53b0020 | isz); // mrs x(isz),ctr_el0
+    o(0x52800080 | p); // mov w(p),#4
+    o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4
+    o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)
+    o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15
+    o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
+    o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
+    o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+    b1 = ind; o(0x14000000); // b
+    lab1 = ind;
+    o(0xd50b7b20 | p); // dc cvau,x(p)
+    o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
+    write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+    o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+    o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+    o(0xd5033b9f); // dsb ish
+    o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
+    o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+    b1 = ind; o(0x14000000); // b
+    lab1 = ind;
+    o(0xd50b7520 | p); // ic ivau,x(p)
+    o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
+    write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+    o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+    o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+    o(0xd5033b9f); // dsb ish
+    o(0xd5033fdf); // isb
+}
+
+ST_FUNC void gen_vla_sp_save(int addr) {
+    uint32_t r = intr(get_reg(RC_INT));
+    o(0x910003e0 | r); // mov x(r),sp
+    arm64_strx(3, r, 29, addr);
+}
+
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    // Use x30 because this function can be called when there
+    // is a live return value in x0 but there is nothing on
+    // the value stack to prevent get_reg from returning x0.
+    uint32_t r = 30;
+    arm64_ldrx(0, 3, r, 29, addr);
+    o(0x9100001f | r << 5); // mov sp,x(r)
+}
+
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    uint32_t r = intr(gv(RC_INT));
+    o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
+    o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
+    o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
+    vpop();
+}
+
+/* end of A64 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c	(revision 331)
@@ -0,0 +1,256 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_AARCH64
+
+#define R_DATA_32  R_AARCH64_ABS32
+#define R_DATA_PTR R_AARCH64_ABS64
+#define R_JMP_SLOT R_AARCH64_JUMP_SLOT
+#define R_GLOB_DAT R_AARCH64_GLOB_DAT
+#define R_COPY     R_AARCH64_COPY
+#define R_RELATIVE R_AARCH64_RELATIVE
+
+#define R_NUM      R_AARCH64_NUM
+
+#define ELF_START_ADDR 0x00400000
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_AARCH64_ABS32:
+        case R_AARCH64_ABS64:
+	case R_AARCH64_PREL32:
+        case R_AARCH64_MOVW_UABS_G0_NC:
+        case R_AARCH64_MOVW_UABS_G1_NC:
+        case R_AARCH64_MOVW_UABS_G2_NC:
+        case R_AARCH64_MOVW_UABS_G3:
+        case R_AARCH64_ADR_PREL_PG_HI21:
+        case R_AARCH64_ADD_ABS_LO12_NC:
+        case R_AARCH64_ADR_GOT_PAGE:
+        case R_AARCH64_LD64_GOT_LO12_NC:
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_COPY:
+            return 0;
+
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+        case R_AARCH64_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_AARCH64_PREL32:
+        case R_AARCH64_MOVW_UABS_G0_NC:
+        case R_AARCH64_MOVW_UABS_G1_NC:
+        case R_AARCH64_MOVW_UABS_G2_NC:
+        case R_AARCH64_MOVW_UABS_G3:
+        case R_AARCH64_ADR_PREL_PG_HI21:
+        case R_AARCH64_ADD_ABS_LO12_NC:
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_JUMP_SLOT:
+        case R_AARCH64_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_AARCH64_ABS32:
+        case R_AARCH64_ABS64:
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+            return AUTO_GOTPLT_ENTRY;
+
+        case R_AARCH64_ADR_GOT_PAGE:
+        case R_AARCH64_LD64_GOT_LO12_NC:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    unsigned plt_offset;
+
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        tcc_error("DLLs unimplemented!");
+
+    if (plt->data_offset == 0) {
+        section_ptr_add(plt, 32);
+    }
+    plt_offset = plt->data_offset;
+
+    p = section_ptr_add(plt, 16);
+    write32le(p, got_offset);
+    write32le(p + 4, (uint64_t) got_offset >> 32);
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        uint64_t plt = s1->plt->sh_addr;
+        uint64_t got = s1->got->sh_addr;
+        uint64_t off = (got >> 12) - (plt >> 12);
+        if ((off + ((uint32_t)1 << 20)) >> 21)
+            tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
+        write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
+        write32le(p + 4, (0x90000010 | // adrp x16,...
+			  (off & 0x1ffffc) << 3 | (off & 3) << 29));
+        write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
+			  (got & 0xff8) << 7));
+        write32le(p + 12, (0x91000210 | // add x16,x16,#...
+			   (got & 0xfff) << 10));
+        write32le(p + 16, 0xd61f0220); // br x17
+        write32le(p + 20, 0xd503201f); // nop
+        write32le(p + 24, 0xd503201f); // nop
+        write32le(p + 28, 0xd503201f); // nop
+        p += 32;
+        while (p < p_end) {
+            uint64_t pc = plt + (p - s1->plt->data);
+            uint64_t addr = got + read64le(p);
+            uint64_t off = (addr >> 12) - (pc >> 12);
+            if ((off + ((uint32_t)1 << 20)) >> 21)
+                tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
+            write32le(p, (0x90000010 | // adrp x16,...
+			  (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
+			      (addr & 0xff8) << 7));
+            write32le(p + 8, (0x91000210 | // add x16,x16,#...
+			      (addr & 0xfff) << 10));
+            write32le(p + 12, 0xd61f0220); // br x17
+            p += 16;
+        }
+    }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index = ELFW(R_SYM)(rel->r_info);
+#ifdef DEBUG_RELOC
+    ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+#endif
+
+    switch(type) {
+        case R_AARCH64_ABS64:
+            write64le(ptr, val);
+            return;
+        case R_AARCH64_ABS32:
+            write32le(ptr, val);
+            return;
+	case R_AARCH64_PREL32:
+	    write32le(ptr, val - addr);
+	    return;
+        case R_AARCH64_MOVW_UABS_G0_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G1_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 16 & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G2_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 32 & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G3:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 48 & 0xffff) << 5));
+            return;
+        case R_AARCH64_ADR_PREL_PG_HI21: {
+            uint64_t off = (val >> 12) - (addr >> 12);
+            if ((off + ((uint64_t)1 << 20)) >> 21)
+                tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
+            write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+                            (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            return;
+        }
+        case R_AARCH64_ADD_ABS_LO12_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
+                            (val & 0xfff) << 10));
+            return;
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+#ifdef DEBUG_RELOC
+	    printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
+		    (char *) symtab_section->link->data + sym->st_name);
+#endif
+            if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
+                tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
+                          " (val=%lx, addr=%lx)", val, addr);
+            write32le(ptr, (0x14000000 |
+                            (uint32_t)(type == R_AARCH64_CALL26) << 31 |
+                            ((val - addr) >> 2 & 0x3ffffff)));
+            return;
+        case R_AARCH64_ADR_GOT_PAGE: {
+            uint64_t off =
+                (((s1->got->sh_addr +
+                   s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
+            if ((off + ((uint64_t)1 << 20)) >> 21)
+                tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
+            write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+                            (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            return;
+        }
+        case R_AARCH64_LD64_GOT_LO12_NC:
+            write32le(ptr,
+                      ((read32le(ptr) & 0xfff803ff) |
+                       ((s1->got->sh_addr +
+                         s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
+            return;
+        case R_AARCH64_COPY:
+            return;
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_JUMP_SLOT:
+            /* They don't need addend */
+#ifdef DEBUG_RELOC
+	    printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
+		    val - rel->r_addend,
+		    (char *) symtab_section->link->data + sym->st_name);
+#endif
+            write64le(ptr, val - rel->r_addend);
+            return;
+        case R_AARCH64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        default:
+            fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
+                    type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/c67-gen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c	(revision 331)
@@ -21,5 +21,5 @@
 #ifdef TARGET_DEFS_ONLY
 
-//#define ASSEMBLY_LISTING_C67
+/* #define ASSEMBLY_LISTING_C67 */
 
 /* number of available registers */
@@ -94,9 +94,9 @@
 
 /* defined if function parameters must be evaluated in reverse order */
-//#define INVERT_FUNC_PARAMS
+/* #define INVERT_FUNC_PARAMS */
 
 /* defined if structures are passed as pointers. Otherwise structures
    are directly pushed on stack. */
-//#define FUNC_STRUCT_PARAM_AS_PTR
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
 
 /* pointer size, in bytes */
@@ -108,18 +108,4 @@
 /* maximum alignment (for aligned attribute support) */
 #define MAX_ALIGN     8
-
-/******************************************************/
-/* ELF defines */
-
-#define EM_TCC_TARGET EM_C60
-
-/* relocation type for 32 bit data relocation */
-#define R_DATA_32   R_C60_32
-#define R_DATA_PTR  R_C60_32
-#define R_JMP_SLOT  R_C60_JMP_SLOT
-#define R_COPY      R_C60_COPY
-
-#define ELF_START_ADDR 0x00000400
-#define ELF_PAGE_SIZE  0x1000
 
 /******************************************************/
@@ -197,5 +183,6 @@
 {
     int ind1;
-
+    if (nocode_wanted)
+        return;
 #ifdef ASSEMBLY_LISTING_C67
     fprintf(f, " %08X", c);
@@ -246,6 +233,6 @@
 
 // these are regs that tcc doesn't really know about, 
-// but asign them unique values so the mapping routines
-// can distinquish them
+// but assign them unique values so the mapping routines
+// can distinguish them
 
 #define C67_A0 105
@@ -254,5 +241,5 @@
 #define C67_FP 108
 #define C67_B2 109
-#define C67_CREG_ZERO -1	// Special code for no condition reg test
+#define C67_CREG_ZERO -1	/* Special code for no condition reg test */
 
 
@@ -1568,5 +1555,5 @@
     fr = sv->r;
     ft = sv->type.t;
-    fc = sv->c.ul;
+    fc = sv->c.i;
 
     v = fr & VT_VALMASK;
@@ -1575,5 +1562,5 @@
 	    v1.type.t = VT_INT;
 	    v1.r = VT_LOCAL | VT_LVAL;
-	    v1.c.ul = fc;
+	    v1.c.i = fc;
 	    load(r, &v1);
 	    fr = r;
@@ -1727,5 +1714,5 @@
 
     ft = v->type.t;
-    fc = v->c.ul;
+    fc = v->c.i;
     fr = v->r & VT_VALMASK;
     bt = ft & VT_BTYPE;
@@ -1880,4 +1867,11 @@
 }
 
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    return 0;
+}
+
 /* generate function call with address in (vtop->t, vtop->c) and free function
    context. Stack entry is popped */
@@ -1894,6 +1888,4 @@
     for (i = 0; i < nb_args; i++) {
 	if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
-	    ALWAYS_ASSERT(FALSE);
-	} else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
 	    ALWAYS_ASSERT(FALSE);
 	} else {
@@ -1960,9 +1952,10 @@
 
     sym = func_type->ref;
-    func_call = sym->r;
+    func_call = sym->f.func_call;
     addr = 8;
     /* if the function returns a structure, then add an
        implicit pointer parameter */
     func_vt = sym->type;
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
 	func_vc = addr;
@@ -2047,4 +2040,6 @@
 {
     int ind1 = ind;
+    if (nocode_wanted)
+        return t;
 
     C67_MVKL(C67_A0, t);	//r=reg to load,  constant
@@ -2079,5 +2074,7 @@
 
     v = vtop->r & VT_VALMASK;
-    if (v == VT_CMP) {
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
 	/* fast case : can jump directly since flags are set */
 	// C67 uses B2 sort of as flags register
@@ -2101,5 +2098,4 @@
 	if ((v & 1) == inv) {
 	    /* insert vtop->c jump list in t */
-	    p = &vtop->c.i;
 
 	    // I guess the idea is to traverse to the
@@ -2107,5 +2103,5 @@
 	    // there
 
-	    n = *p;
+	    n = vtop->c.i;
 	    while (n != 0) {
 		p = (int *) (cur_text_section->data + n);
@@ -2122,35 +2118,4 @@
 	    t = gjmp(t);
 	    gsym(vtop->c.i);
-	}
-    } else {
-	if (is_float(vtop->type.t)) {
-	    vpushi(0);
-	    gen_op(TOK_NE);
-	}
-	if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-	    /* constant jmp optimization */
-	    if ((vtop->c.i != 0) != inv)
-		t = gjmp(t);
-	} else {
-	    // I think we need to get the value on the stack
-	    // into a register, test it, and generate a branch
-	    // return the address of the branch, so it can be
-	    // later patched
-
-	    v = gv(RC_INT);	// get value into a reg 
-	    ind1 = ind;
-	    C67_MVKL(C67_A0, t);	//r=reg to load, constant
-	    C67_MVKH(C67_A0, t);	//r=reg to load, constant
-
-	    if (v != TREG_EAX &&	// check if not already in a conditional test reg
-		v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
-		C67_MV(v, C67_B2);
-		v = C67_B2;
-	    }
-
-	    C67_IREG_B_REG(inv, v, C67_A0);	// [!R] B.S2x  A0
-	    C67_NOP(5);
-	    t = ind1;		//return where we need to patch
-	    ind1 = ind;
 	}
     }
@@ -2261,5 +2226,5 @@
 	fr = vtop[0].r;
 	vtop--;
-	C67_MPYI(fr, r);	// 32 bit bultiply  fr,r,fr
+	C67_MPYI(fr, r);	// 32 bit multiply  fr,r,fr
 	C67_NOP(8);		// NOP 8 for worst case
 	break;
@@ -2318,5 +2283,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
-   two operands are guaranted to have the same floating point type */
+   two operands are guaranteed to have the same floating point type */
 /* XXX: need to use ST1 too */
 void gen_opf(int op)
@@ -2330,5 +2295,5 @@
 
     ft = vtop->type.t;
-    fc = vtop->c.ul;
+    fc = vtop->c.i;
     r = vtop->r;
     fr = vtop[-1].r;
@@ -2555,4 +2520,19 @@
 }
 
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
 /* end of C67 code generator */
 /*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c	(revision 331)
@@ -0,0 +1,131 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_C60
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_C60_32
+#define R_DATA_PTR  R_C60_32
+#define R_JMP_SLOT  R_C60_JMP_SLOT
+#define R_GLOB_DAT  R_C60_GLOB_DAT
+#define R_COPY      R_C60_COPY
+#define R_RELATIVE  R_C60_RELATIVE
+
+#define R_NUM       R_C60_NUM
+
+#define ELF_START_ADDR 0x00000400
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_C60_32:
+	case R_C60LO16:
+	case R_C60HI16:
+        case R_C60_GOT32:
+        case R_C60_GOTOFF:
+        case R_C60_GOTPC:
+        case R_C60_COPY:
+            return 0;
+
+        case R_C60_PLT32:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_C60_32:
+	case R_C60LO16:
+	case R_C60HI16:
+        case R_C60_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_C60_GOTOFF:
+        case R_C60_GOTPC:
+            return BUILD_GOT_ONLY;
+
+        case R_C60_PLT32:
+        case R_C60_GOT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    tcc_error("C67 got not implemented");
+    return 0;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        /* XXX: TODO */
+        while (p < p_end) {
+            /* XXX: TODO */
+        }
+   }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    switch(type) {
+        case R_C60_32:
+            *(int *)ptr += val;
+            break;
+        case R_C60LO16:
+            {
+                uint32_t orig;
+
+                /* put the low 16 bits of the absolute address add to what is
+                   already there */
+                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
+                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
+
+                /* patch both at once - assumes always in pairs Low - High */
+                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |
+                                   (((val+orig)      & 0xffff) << 7);
+                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) |
+                                  ((((val+orig)>>16) & 0xffff) << 7);
+            }
+            break;
+        case R_C60HI16:
+            break;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+                    type, (unsigned) addr, ptr, (unsigned) val);
+            break;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/coff.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/coff.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/coff.h	(revision 331)
@@ -23,5 +23,5 @@
 #define  F_RELFLG   0x01       /* relocation info stripped from file       */
 #define  F_EXEC     0x02       /* file is executable (no unresolved refs)  */
-#define  F_LNNO     0x04       /* line nunbers stripped from file          */
+#define  F_LNNO     0x04       /* line numbers stripped from file          */
 #define  F_LSYMS    0x08       /* local symbols stripped from file         */
 #define  F_GSP10    0x10       /* 34010 version                            */
@@ -38,6 +38,6 @@
 #define FILHDR  struct filehdr
 
-//#define FILHSZ  sizeof(FILHDR) 
-#define FILHSZ  22                // above rounds to align on 4 bytes which causes problems 
+/* #define FILHSZ  sizeof(FILHDR)  */
+#define FILHSZ  22                /* above rounds to align on 4 bytes which causes problems */
 
 #define COFF_C67_MAGIC 0x00c2
@@ -154,5 +154,5 @@
 /* Define constants for names of "special" sections                       */
 /*------------------------------------------------------------------------*/
-//#define _TEXT    ".text"
+/* #define _TEXT    ".text" */
 #define _DATA    ".data"
 #define _BSS     ".bss"
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/config.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.h	(revision 331)
@@ -1,10 +1,7 @@
 /* Automatically generated by configure - do not modify */
 #ifndef CONFIG_TCCDIR
-# define CONFIG_TCCDIR "0:/lib/tcc"
+# define CONFIG_TCCDIR "1:/lib"
 #endif
-#define GCC_MAJOR 
-#define GCC_MINOR 
-#define HOST_ARM 1
-#define TCC_ARM_VERSION 7
-#define TCC_VERSION "0.9.26"
-#define CONFIG_TCC_STATIC
+#define CONFIG_TCC_CRTPREFIX "1:/lib"
+#define CONFIG_TCC_SYSINCLUDEPATHS "1:/include"
+#define TCC_VERSION "0.9.27"
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.mak
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/config.mak	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.mak	(revision 331)
@@ -1,27 +1,27 @@
 # Automatically generated by configure - do not modify
-prefix=0:
-bindir=$(DESTDIR)0:/bin
-tccdir=$(DESTDIR)0:/lib/tcc
-libdir=$(DESTDIR)0:/lib
-ln_libdir=0:/lib
-includedir=$(DESTDIR)0:/include
-mandir=$(DESTDIR)0:/share/man
-infodir=$(DESTDIR)0:/share/info
-docdir=$(DESTDIR)0:/share/doc/tcc
+prefix=1:
+bindir=$(DESTDIR)1:
+tccdir=$(DESTDIR)1:
+libdir=$(DESTDIR)1:/libtcc
+includedir=$(DESTDIR)
+mandir=$(DESTDIR)
+infodir=$(DESTDIR)
+docdir=$(DESTDIR)1:/doc
 CC=arm-none-eabi-gcc
-GCC_MAJOR=
-GCC_MINOR=
-HOST_CC=gcc
+GCC_MAJOR=0
+GCC_MINOR=0
 AR=arm-none-eabi-ar
 STRIP=arm-none-eabi-strip -s -R .comment -R .note
-CFLAGS=-Wall -g -O2
-LDFLAGS=
+CFLAGS=-Wall -g -Og -nostdinc -I$(TOP)/../musl-1.1.18/include -mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfp -Dtcc_main=main -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result
+LDFLAGS=-Wl,-e_start_c -nostdlib $(TOP)/../musl-1.1.18/lib/crtn.o $(TOP)/../musl-1.1.18/lib/crti.o $(TOP)/../musl-1.1.18/lib/rcrt1.o -L$(TOP)/../musl-1.1.18/lib -L. -lc -lgcc
 LIBSUF=.a
-EXESUF=
+EXESUF=.elf
+DLLSUF=.so
+NATIVE_DEFINES+=-DTCC_CPU_VERSION=7
 ARCH=arm
 TARGETOS=
-VERSION=0.9.26
-SRC_PATH=.
-top_srcdir=$(TOP)
-top_builddir=$(TOP)
-CONFIG_NOLDL=yes
+#CONFIG_libgcc=yes
+CONFIG_musl=yes
+VERSION = 0.9.27
+TOPSRC=$(TOP)
+arm-libtcc1-usegcc=yes
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.texi
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/config.texi	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.texi	(revision 331)
@@ -1,1 +1,1 @@
-@set VERSION 0.9.26
+@set VERSION 0.9.27
Index: EcnlProtoTool/trunk/tcc-0.9.27/configure
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/configure	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/configure	(revision 331)
@@ -18,6 +18,4 @@
 
 # default parameters
-build_cross="no"
-use_libgcc="no"
 prefix=""
 execprefix=""
@@ -31,36 +29,42 @@
 cross_prefix=""
 cc="gcc"
-host_cc="gcc"
 ar="ar"
 strip="strip"
-cygwin="no"
-gprof="no"
 bigendian="no"
 mingw32="no"
 LIBSUF=".a"
 EXESUF=""
+DLLSUF=".so"
 tcc_sysincludepaths=""
 tcc_libpaths=""
 tcc_crtprefix=""
 tcc_elfinterp=""
+triplet=
 tcc_lddir=
 confvars=
-
-#cpu=`uname -m`
-cpu="armv7a"
+suggest="yes"
+cpu=
+cpuver=
+gcc_major=0
+gcc_minor=0
 
 # OS specific
-#targetos=`uname -s`
-targetos=""
+targetos=`uname`
 case $targetos in
-  MINGW32*)  mingw32=yes;;
-  DragonFly) noldl=yes;;
-  OpenBSD)   noldl=yes;;
-  *) ;;
+  Darwin)
+    confvars="$confvars OSX"
+    DLLSUF=".dylib"
+    ;;
+  MINGW*|MSYS*|CYGWIN*)
+    mingw32=yes
+    ;;
+  DragonFly|OpenBSD|FreeBSD|NetBSD)
+    confvars="$confvars ldl=no"
+    ;;
+  *)
+    ;;
 esac
 
 # find source path
-# XXX: we assume an absolute path is given when launching configure, 
-# except in './configure' case.
 source_path=${0%configure}
 source_path=${source_path%/}
@@ -71,45 +75,4 @@
 fi
 
-case "$cpu" in
-  i386|i486|i586|i686|i86pc|BePC|i686-AT386)
-    cpu="x86"
-  ;;
-  x86_64)
-    cpu="x86-64"
-  ;;
-  arm*)
-    case "$cpu" in
-      arm|armv4l)
-        cpuver=4
-      ;;
-      armv5tel|armv5tejl)
-        cpuver=5
-      ;;
-      armv6j|armv6l)
-        cpuver=6
-      ;;
-      armv7a|armv7l)
-        cpuver=7
-      ;;
-    esac
-    cpu="armv4l"
-  ;;
-  alpha)
-    cpu="alpha"
-  ;;
-  "Power Macintosh"|ppc|ppc64)
-    cpu="powerpc"
-  ;;
-  mips)
-    cpu="mips"
-  ;;
-  s390)
-    cpu="s390"
-  ;;
-  *)
-    cpu="unknown"
-  ;;
-esac
-
 for opt do
   eval opt=\"$opt\"
@@ -143,9 +106,11 @@
   --cc=*) cc=`echo $opt | cut -d '=' -f 2`
   ;;
+  --ar=*) ar=`echo $opt | cut -d '=' -f 2`
+  ;;
   --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
   ;;
   --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
   ;;
-  --extra-libs=*) extralibs=${opt#--extra-libs=}
+  --extra-libs=*) extralibs="${opt#--extra-libs=}"
   ;;
   --sysincludepaths=*) tcc_sysincludepaths=`echo $opt | cut -d '=' -f 2`
@@ -157,23 +122,25 @@
   --elfinterp=*) tcc_elfinterp=`echo $opt | cut -d '=' -f 2`
   ;;
+  --triplet=*) triplet=`echo $opt | cut -d '=' -f 2`
+  ;;
   --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
   ;;
-  --enable-gprof) gprof="yes"
-  ;;
-  --enable-mingw32) mingw32="yes" ; cross_prefix="i686-pc-mingw32-" ; cpu=x86
-  ;;
-  --enable-cygwin) mingw32="yes" ; cygwin="yes" ; cross_prefix="mingw32-" ; cpu=x86
-  ;;
-  --enable-cross) build_cross="yes"
-  ;;
-  --disable-static) disable_static="yes"
-  ;;
-  --disable-rpath) disable_rpath="yes"
-  ;;
-  --strip-binaries) strip_binaries="yes"
-  ;;
-  --with-libgcc) use_libgcc="yes"
-  ;;
-  --with-selinux) have_selinux="yes"
+  --enable-cross) confvars="$confvars cross"
+  ;;
+  --disable-static) confvars="$confvars static=no"
+  ;;
+  --enable-static) confvars="$confvars static"
+  ;;
+  --disable-rpath) confvars="$confvars rpath=no"
+  ;;
+  --strip-binaries) confvars="$confvars strip"
+  ;;
+  --with-libgcc) confvars="$confvars libgcc"
+  ;;
+  --with-selinux) confvars="$confvars selinux"
+  ;;
+  --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
+  ;;
+  --config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
   ;;
   --help|-h) show_help="yes"
@@ -183,4 +150,57 @@
   esac
 done
+
+if test -z "$cpu" ; then
+    if test -n "$ARCH" ; then
+	cpu="$ARCH"
+    else
+	cpu=`uname -m`
+    fi
+fi
+
+case "$cpu" in
+  x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
+    cpu="i386"
+  ;;
+  x86_64|amd64|x86-64)
+    cpu="x86_64"
+  ;;
+  arm*)
+    case "$cpu" in
+      arm|armv4l)
+	cpuver=4
+      ;;
+      armv5tel|armv5tejl)
+	cpuver=5
+      ;;
+      armv6j|armv6l)
+	cpuver=6
+      ;;
+      armv7a|armv7l)
+	cpuver=7
+      ;;
+    esac
+    cpu="arm"
+  ;;
+  aarch64)
+    cpu="aarch64"
+  ;;
+  alpha)
+    cpu="alpha"
+  ;;
+  "Power Macintosh"|ppc|ppc64)
+    cpu="ppc"
+  ;;
+  mips)
+    cpu="mips"
+  ;;
+  s390)
+    cpu="s390"
+  ;;
+  *)
+    echo "Unsupported CPU"
+    exit 1
+  ;;
+esac
 
 # Checking for CFLAGS
@@ -190,56 +210,51 @@
 
 if test "$mingw32" = "yes" ; then
-    if test x"$tccdir" = x""; then
-    tccdir="tcc"
-    fi
-    if test -z "$prefix" ; then
-    prefix="C:/Program Files/${tccdir}"
-    fi
-    if test -z "$sharedir" ; then
-    sharedir="${prefix}"
-    fi
-    execprefix="$prefix"
-    bindir="${prefix}"
-    tccdir="${prefix}"
-    libdir="${prefix}/lib"
-    docdir="${sharedir}/doc"
-    mandir="${sharedir}/man"
-    infodir="${sharedir}/info"
+    if test "$source_path_used" = "no"; then
+      source_path="."
+    fi
+    if test "$cc" = gcc; then
+      test -z "$LDFLAGS" && LDFLAGS="-static"
+    fi
+    test -z "$prefix" && prefix="C:/Program Files/tcc"
+    test -z "$tccdir" && tccdir="${prefix}"
+    test -z "$bindir" && bindir="${tccdir}"
+    test -z "$docdir" && docdir="${tccdir}/doc"
+    test -z "$libdir" && libdir="${tccdir}/libtcc"
+    confvars="$confvars WIN32"
     LIBSUF=".lib"
     EXESUF=".exe"
+    DLLSUF=".dll"
 else
     if test -z "$prefix" ; then
-    prefix="/usr/local"
+      prefix="/usr/local"
     fi
     if test -z "$sharedir" ; then
-    sharedir="${prefix}/share"
+      sharedir="${prefix}/share"
     fi
     if test x"$execprefix" = x""; then
-    execprefix="${prefix}"
+      execprefix="${prefix}"
     fi
     if test x"$libdir" = x""; then
-    libdir="${execprefix}/lib"
+      libdir="${execprefix}/lib"
     fi
     if test x"$bindir" = x""; then
-    bindir="${execprefix}/bin"
+      bindir="${execprefix}/bin"
+    fi
+    if test x"$docdir" = x""; then
+      docdir="${sharedir}/doc"
+    fi
+    if test x"$mandir" = x""; then
+      mandir="${sharedir}/man"
+    fi
+    if test x"$infodir" = x""; then
+      infodir="${sharedir}/info"
     fi
     if test x"$tccdir" = x""; then
-    tccdir="tcc"
-    fi
-    if test x"$docdir" = x""; then
-    docdir="${sharedir}/doc/${tccdir}"
-    fi
-    if test x"$mandir" = x""; then
-    mandir="${sharedir}/man"
-    fi
-    if test x"$infodir" = x""; then
-    infodir="${sharedir}/info"
-    fi
-    tccdir="${libdir}/${tccdir}"
+      tccdir="${libdir}/tcc"
+    fi
+    if test x"$includedir" = x""; then
+      includedir="${prefix}/include"
+    fi
 fi # mingw32
-
-if test x"$includedir" = x""; then
-includedir="${prefix}/include"
-fi
 
 if test x"$show_help" = "xyes" ; then
@@ -252,5 +267,5 @@
   --prefix=PREFIX          install in PREFIX [$prefix]
   --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
-                           [same as prefix]
+			   [same as prefix]
   --bindir=DIR             user executables in DIR [EPREFIX/bin]
   --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
@@ -267,18 +282,21 @@
   --sysroot=PREFIX         prepend PREFIX to library/include paths []
   --cc=CC                  use C compiler CC [$cc]
+  --ar=AR                  create archives using AR [$ar]
   --extra-cflags=          specify compiler flags [$CFLAGS]
   --extra-ldflags=         specify linker options []
+  --cpu=CPU                CPU [$cpu]
   --strip-binaries         strip symbol tables from resulting binaries
   --disable-static         make libtcc.so instead of libtcc.a
+  --enable-static          make libtcc.a instead of libtcc.dll (win32)
   --disable-rpath          disable use of -rpath with the above
-  --with-libgcc            use /lib/libgcc_s.so.1 instead of libtcc.a
-  --enable-mingw32         build windows version on linux with mingw32
-  --enable-cygwin          build windows version on windows with cygwin
+  --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
   --enable-cross           build cross compilers
-  --with-selinux           use mmap for exec mem [needs writable /tmp]
+  --with-selinux           use mmap for executable memory (with tcc -run)
   --sysincludepaths=...    specify system include paths, colon separated
   --libpaths=...           specify system library paths, colon separated
   --crtprefix=...          specify locations of crt?.o, colon separated
   --elfinterp=...          specify elf interpreter
+  --triplet=...            specify system library/include directory triplet
+  --config-uClibc,-musl,-mingw32... enable system specific configurations
 EOF
 #echo "NOTE: The object files are build at the place where configure is launched"
@@ -290,75 +308,98 @@
 strip="${cross_prefix}${strip}"
 
-CONFTEST=./conftest$EXESUF
-
 if test -z "$cross_prefix" ; then
+  CONFTEST=./conftest$EXESUF
   if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
     echo "configure: error: '$cc' failed to compile conftest.c."
   else
-    bigendian="$($CONFTEST bigendian)"
     gcc_major="$($CONFTEST version)"
     gcc_minor="$($CONFTEST minor)"
-    if test "$mingw32" = "no" ; then
-      triplet="$($CONFTEST triplet)"
-      if test -f "/usr/lib/$triplet/crti.o" ; then
-        tcc_lddir="lib/$triplet"
-        multiarch_triplet="$triplet"
-      elif test -f "/usr/lib64/crti.o" ; then
-        tcc_lddir="lib64"
-      fi
-
-      if test "$cpu" = "armv4l" ; then
-        if test "${triplet%eabihf}" != "$triplet" ; then
-           confvars="$confvars arm_eabihf"
-        elif test "${triplet%eabi}" != "$triplet" ; then
-           confvars="$confvars arm_eabi"
-        fi
-        if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
-           confvars="$confvars arm_vfp"
+  fi
+  bigendian="$($CONFTEST bigendian)"
+  if test "$mingw32" = "no" ; then
+
+      if test -z "$triplet"; then
+        tt="$($CONFTEST triplet)"
+        if test -n "$tt" -a -f "/usr/lib/$tt/crti.o" ; then
+          triplet="$tt"
         fi
       fi
 
-#      multiarch_triplet=${libc_dir#*/}
-#      multiarch_triplet=${multiarch_triplet%/}
-#      tcc_lddir="${libc_dir%%/*}"
-#      if test -n "$multiarch_triplet" ; then
-#        tcc_lddir="$tcc_lddir/$multiarch_triplet"
-#      fi
-
-      if test -f "/lib/ld-uClibc.so.0" ; then
-        confvars="$confvars uClibc"
+      if test -z "$triplet"; then
+        if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
+          if test -f "/usr/lib64/crti.o" ; then
+            tcc_lddir="lib64"
+          fi
+        fi
       fi
-# gr: maybe for after the release:
-#       tcc_elfinterp="$(ldd $CONFTEST | grep 'ld.*.so' | sed 's,\s*\(\S\+\).*,\1,')"
-       # echo "elfinterp           $tcc_elfinterp"
-
-    fi
+
+      if test "$cpu" = "arm" ; then
+	if test "${triplet%eabihf}" != "$triplet" ; then
+	   confvars="$confvars arm_eabihf"
+	elif test "${triplet%eabi}" != "$triplet" ; then
+	   confvars="$confvars arm_eabi"
+	fi
+	if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
+	   confvars="$confvars arm_vfp"
+	fi
+      fi
+
+      if test "$suggest" = "yes"; then
+        if test -f "/lib/ld-uClibc.so.0" ; then
+          echo "Perhaps you want ./configure --config-uClibc"
+        fi
+        if test -f "/lib/ld-musl-$cpu.so.1"; then
+          echo "Perhaps you want ./configure --config-musl"
+        fi
+      fi
   fi
 else
   # if cross compiling, cannot launch a program, so make a static guess
   case $cpu in
-    powerpc|mips|s390)  bigendian=yes;;
+    ppc|mips|s390)  bigendian=yes;;
   esac
 fi
 
-cat <<EOF
-Binary  directory   $bindir
-TinyCC directory    $tccdir
-Library directory   $libdir
-Include directory   $includedir
-Manual directory    $mandir
-Info directory      $infodir
-Doc directory       $docdir
-Target root prefix  $sysroot
-Source path      $source_path
-C compiler       $cc
-Target OS        $targetos
-CPU              $cpu
-Big Endian       $bigendian
-gprof enabled    $gprof
-cross compilers  $build_cross
-use libgcc       $use_libgcc
-EOF
-
+if test "$bigendian" = "yes" ; then
+  confvars="$confvars BIGENDIAN"
+fi
+
+# a final configuration tuning
+if ! echo "$cc" | grep -q "tcc"; then
+  OPT1="-Wdeclaration-after-statement -fno-strict-aliasing"
+  # we want -Wno- but gcc does not always reject unknown -Wno- options
+  OPT2="-Wpointer-sign -Wsign-compare -Wunused-result"
+  if echo "$cc" | grep -q "clang"; then
+    OPT1="$OPT1 -fheinous-gnu-extensions"
+    OPT2="$OPT2 -Wstring-plus-int"
+  fi
+  $cc $OPT1 $OPT2 -o a.out -c -xc - < /dev/null > cc_msg.txt 2>&1
+  for o in $OPT1; do # enable these options
+    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS $o"; fi
+  done
+  for o in $OPT2; do # disable these options
+    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS -Wno-${o#-W*}"; fi
+  done
+  # cat cc_msg.txt
+  # echo $CFLAGS
+  rm -f cc_msg.txt a.out
+fi
+
+fcho() { if test -n "$2"; then echo "$1$2"; fi }
+
+fcho "Binary directory    " "$bindir"
+fcho "TinyCC directory    " "$tccdir"
+fcho "Library directory   " "$libdir"
+fcho "Include directory   " "$includedir"
+fcho "Manual directory    " "$mandir"
+fcho "Info directory      " "$infodir"
+fcho "Doc directory       " "$docdir"
+fcho "Target root prefix  " "$sysroot"
+echo "Source path         $source_path"
+echo "C compiler          $cc ($gcc_major.$gcc_minor)"
+echo "Target OS           $targetos"
+echo "CPU                 $cpu"
+fcho "Triplet             " "$triplet"
+fcho "Config              " "${confvars# }"
 echo "Creating config.mak and config.h"
 
@@ -369,5 +410,4 @@
 tccdir=\$(DESTDIR)$tccdir
 libdir=\$(DESTDIR)$libdir
-ln_libdir=$libdir
 includedir=\$(DESTDIR)$includedir
 mandir=\$(DESTDIR)$mandir
@@ -377,5 +417,4 @@
 GCC_MAJOR=$gcc_major
 GCC_MINOR=$gcc_minor
-HOST_CC=$host_cc
 AR=$ar
 STRIP=$strip -s -R .comment -R .note
@@ -384,4 +423,5 @@
 LIBSUF=$LIBSUF
 EXESUF=$EXESUF
+DLLSUF=$DLLSUF
 EOF
 
@@ -393,7 +433,14 @@
   fi
 }
+
 print_mak() {
   if test -n "$2"; then
     echo "NATIVE_DEFINES+=-D$1=\"\\\"$2\\\"\"" >> config.mak
+  fi
+}
+
+print_mak_int() {
+  if test -n "$2"; then
+    echo "NATIVE_DEFINES+=-D$1=$2" >> config.mak
   fi
 }
@@ -408,98 +455,35 @@
 print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp"
 print_mak CONFIG_LDDIR "$tcc_lddir"
-print_mak CONFIG_MULTIARCHDIR "$multiarch_triplet"
-
-echo "#define GCC_MAJOR $gcc_major" >> $TMPH
-echo "#define GCC_MINOR $gcc_minor" >> $TMPH
-
-if test "$cpu" = "x86" ; then
-  echo "ARCH=i386" >> config.mak
-  echo "#define HOST_I386 1" >> $TMPH
-elif test "$cpu" = "x86-64" ; then
-  echo "ARCH=x86-64" >> config.mak
-  echo "#define HOST_X86_64 1" >> $TMPH
-elif test "$cpu" = "armv4l" ; then
-  echo "ARCH=arm" >> config.mak
-  echo "#define HOST_ARM 1" >> $TMPH
-  echo "#define TCC_ARM_VERSION $cpuver" >> $TMPH
-elif test "$cpu" = "powerpc" ; then
-  echo "ARCH=ppc" >> config.mak
-  echo "#define HOST_PPC 1" >> $TMPH
-elif test "$cpu" = "mips" ; then
-  echo "ARCH=mips" >> config.mak
-  echo "#define HOST_MIPS 1" >> $TMPH
-elif test "$cpu" = "s390" ; then
-  echo "ARCH=s390" >> config.mak
-  echo "#define HOST_S390 1" >> $TMPH
-elif test "$cpu" = "alpha" ; then
-  echo "ARCH=alpha" >> config.mak
-  echo "#define HOST_ALPHA 1" >> $TMPH
+print_mak CONFIG_TRIPLET "$triplet"
+print_mak_int TCC_CPU_VERSION "$cpuver"
+
+if test "$cpu" = "aarch64" ; then
+  echo "ARCH=arm64" >> config.mak
 else
-  echo "Unsupported CPU"
-  exit 1
-fi
-
+  echo "ARCH=$cpu" >> config.mak
+fi
 echo "TARGETOS=$targetos" >> config.mak
 
 for v in $confvars ; do
-  echo "CONFIG_$v=yes" >> config.mak
+  if test "${v%=*}" = "$v"; then
+    echo "CONFIG_$v=yes" >> config.mak
+  else
+    echo "CONFIG_$v" >> config.mak
+  fi
 done
-if test "$noldl" = "yes" ; then
-  echo "CONFIG_NOLDL=yes" >> config.mak
-fi
-if test "$mingw32" = "yes" ; then
-  echo "CONFIG_WIN32=yes" >> config.mak
-  echo "#define CONFIG_WIN32 1" >> $TMPH
-fi
-if test "$cygwin" = "yes" ; then
-  echo "#ifndef _WIN32" >> $TMPH
-  echo "# define _WIN32" >> $TMPH
-  echo "#endif" >> $TMPH
-  echo "AR=ar" >> config.mak
-fi
-if test "$bigendian" = "yes" ; then
-  echo "WORDS_BIGENDIAN=yes" >> config.mak
-  echo "#define WORDS_BIGENDIAN 1" >> $TMPH
-fi
-if test "$gprof" = "yes" ; then
-  echo "TARGET_GPROF=yes" >> config.mak
-  echo "#define HAVE_GPROF 1" >> $TMPH
-fi
-if test "$build_cross" = "yes" ; then
-  echo "CONFIG_CROSS=yes" >> config.mak
-fi
-if test "$disable_static" = "yes" ; then
-  echo "DISABLE_STATIC=yes" >> config.mak
-fi
-if test "$disable_rpath" = "yes" ; then
-  echo "DISABLE_RPATH=yes" >> config.mak
-fi
-if test "$strip_binaries" = "yes" ; then
-  echo "STRIP_BINARIES=yes" >> config.mak
-fi
-if test "$use_libgcc" = "yes" ; then
-  echo "#define CONFIG_USE_LIBGCC" >> $TMPH
-  echo "CONFIG_USE_LIBGCC=yes" >> config.mak
-fi
-if test "$have_selinux" = "yes" ; then
-  echo "#define HAVE_SELINUX" >> $TMPH
-  echo "HAVE_SELINUX=yes" >> config.mak
-fi
 
 version=`head $source_path/VERSION`
-echo "VERSION=$version" >>config.mak
+echo "VERSION = $version" >> config.mak
 echo "#define TCC_VERSION \"$version\"" >> $TMPH
 echo "@set VERSION $version" > config.texi
-echo "SRC_PATH=$source_path" >>config.mak
 
 if test "$source_path_used" = "yes" ; then
     case $source_path in
-       /*) echo "top_srcdir=$source_path";;
-        *) echo "top_srcdir=\$(TOP)/$source_path";;
+       /*) echo "TOPSRC=$source_path";;
+	*) echo "TOPSRC=\$(TOP)/$source_path";;
      esac >>config.mak
 else
-     echo 'top_srcdir=$(TOP)' >>config.mak
-fi
-echo 'top_builddir=$(TOP)' >>config.mak
+     echo 'TOPSRC=$(TOP)' >>config.mak
+fi
 
 diff $TMPH config.h >/dev/null 2>&1
@@ -520,19 +504,20 @@
     case $2 in
     */*) dn=${2%/*}
-         test -d $dn || mkdir -p $dn
-         case $1 in
-         /*) ;;
-          *) while test $dn ; do
-                tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
-             done
-             ;;
-         esac
-         ;;
+	 test -d $dn || mkdir -p $dn
+	 case $1 in
+	 /*) ;;
+	  *) while test $dn ; do
+		tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
+	     done
+	     ;;
+	 esac
+	 ;;
     esac
-    ln -sfn $tgt $2
+
+    ln -sfn $tgt $2 || ( echo "ln failed. Using cp instead."; cp -f $1/$2 $2 )
 }
 
 if test "$source_path_used" = "yes" ; then
-  FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile"
+  FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile tests/pp/Makefile"
   for f in $FILES ; do
     fn_makelink $source_path $f
Index: EcnlProtoTool/trunk/tcc-0.9.27/conftest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/conftest.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/conftest.c	(revision 331)
@@ -2,10 +2,12 @@
 
 /* Define architecture */
-#if defined(__i386__)
+#if defined(__i386__) || defined _M_IX86
 # define TRIPLET_ARCH "i386"
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) || defined _M_AMD64
 # define TRIPLET_ARCH "x86_64"
 #elif defined(__arm__)
 # define TRIPLET_ARCH "arm"
+#elif defined(__aarch64__)
+# define TRIPLET_ARCH "aarch64"
 #else
 # define TRIPLET_ARCH "unknown"
@@ -17,4 +19,6 @@
 #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
 # define TRIPLET_OS "kfreebsd"
+#elif defined _WIN32
+# define TRIPLET_OS "win32"
 #elif !defined (__GNU__)
 # define TRIPLET_OS "unknown"
@@ -32,8 +36,14 @@
 #endif
 
-#ifdef __GNU__
+#if defined _WIN32
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS
+#elif defined __GNU__
 # define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
 #else
 # define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
+#endif
+
+#if defined(_WIN32)
+int _CRT_glob = 0;
 #endif
 
@@ -54,4 +64,11 @@
             printf("%d\n", __GNUC__);
             break;
+#elif defined __TINYC__
+        case 'v':
+            puts("0");
+            break;
+        case 'm':
+            printf("%d\n", __TINYC__);
+            break;
 #else
         case 'm':
@@ -63,7 +80,6 @@
             puts(TRIPLET);
             break;
-        case -1:
-            /* to test -Wno-unused-result */
-            fread(NULL, 1, 1, NULL);
+
+        default:
             break;
     }
Index: EcnlProtoTool/trunk/tcc-0.9.27/elf.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/elf.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/elf.h	(revision 331)
@@ -1,24 +1,22 @@
 /* This file defines standard ELF types, structures, and macros.
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Ian Lance Taylor <ian@cygnus.com>.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef _ELF_H
-#define _ELF_H 1
+#define	_ELF_H 1
 
 #ifndef _WIN32
@@ -31,6 +29,4 @@
 typedef int int32_t;
 typedef long long int int64_t;
-#endif
-
 typedef unsigned char           uint8_t;
 typedef unsigned short int      uint16_t;
@@ -38,4 +34,5 @@
 typedef unsigned long long int  uint64_t;
 #endif
+#endif
 
 /* Standard ELF types.  */
@@ -47,13 +44,13 @@
 /* Types for signed and unsigned 32-bit quantities.  */
 typedef uint32_t Elf32_Word;
-typedef int32_t  Elf32_Sword;
+typedef	int32_t  Elf32_Sword;
 typedef uint32_t Elf64_Word;
-typedef int32_t  Elf64_Sword;
+typedef	int32_t  Elf64_Sword;
 
 /* Types for signed and unsigned 64-bit quantities.  */
 typedef uint64_t Elf32_Xword;
-typedef int64_t  Elf32_Sxword;
+typedef	int64_t  Elf32_Sxword;
 typedef uint64_t Elf64_Xword;
-typedef int64_t  Elf64_Sxword;
+typedef	int64_t  Elf64_Sxword;
 
 /* Type of addresses.  */
@@ -69,7 +66,7 @@
 typedef uint16_t Elf64_Section;
 
-/* Type of symbol indices.  */
-typedef uint32_t Elf32_Symndx;
-typedef uint64_t Elf64_Symndx;
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
 
 
@@ -80,37 +77,37 @@
 typedef struct
 {
-  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
-  Elf32_Half    e_type;                 /* Object file type */
-  Elf32_Half    e_machine;              /* Architecture */
-  Elf32_Word    e_version;              /* Object file version */
-  Elf32_Addr    e_entry;                /* Entry point virtual address */
-  Elf32_Off     e_phoff;                /* Program header table file offset */
-  Elf32_Off     e_shoff;                /* Section header table file offset */
-  Elf32_Word    e_flags;                /* Processor-specific flags */
-  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
-  Elf32_Half    e_phentsize;            /* Program header table entry size */
-  Elf32_Half    e_phnum;                /* Program header table entry count */
-  Elf32_Half    e_shentsize;            /* Section header table entry size */
-  Elf32_Half    e_shnum;                /* Section header table entry count */
-  Elf32_Half    e_shstrndx;             /* Section header string table index */
-} Elf32_Ehdr;
-
-typedef struct
-{
-  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
-  Elf64_Half    e_type;                 /* Object file type */
-  Elf64_Half    e_machine;              /* Architecture */
-  Elf64_Word    e_version;              /* Object file version */
-  Elf64_Addr    e_entry;                /* Entry point virtual address */
-  Elf64_Off     e_phoff;                /* Program header table file offset */
-  Elf64_Off     e_shoff;                /* Section header table file offset */
-  Elf64_Word    e_flags;                /* Processor-specific flags */
-  Elf64_Half    e_ehsize;               /* ELF header size in bytes */
-  Elf64_Half    e_phentsize;            /* Program header table entry size */
-  Elf64_Half    e_phnum;                /* Program header table entry count */
-  Elf64_Half    e_shentsize;            /* Section header table entry size */
-  Elf64_Half    e_shnum;                /* Section header table entry count */
-  Elf64_Half    e_shstrndx;             /* Section header string table index */
-} Elf64_Ehdr;
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} __attribute__((packed)) Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} __attribute__((packed)) Elf64_Ehdr;
 
 /* Fields in the e_ident array.  The EI_* macros are indices into the
@@ -118,137 +115,153 @@
    may have.  */
 
-#define EI_MAG0         0               /* File identification byte 0 index */
-#define ELFMAG0         0x7f            /* Magic number byte 0 */
-
-#define EI_MAG1         1               /* File identification byte 1 index */
-#define ELFMAG1         'E'             /* Magic number byte 1 */
-
-#define EI_MAG2         2               /* File identification byte 2 index */
-#define ELFMAG2         'L'             /* Magic number byte 2 */
-
-#define EI_MAG3         3               /* File identification byte 3 index */
-#define ELFMAG3         'F'             /* Magic number byte 3 */
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
 
 /* Conglomeration of the identification bytes, for easy testing as a word.  */
-#define ELFMAG          "\177ELF"
-#define SELFMAG         4
-
-#define EI_CLASS        4               /* File class byte index */
-#define ELFCLASSNONE    0               /* Invalid class */
-#define ELFCLASS32      1               /* 32-bit objects */
-#define ELFCLASS64      2               /* 64-bit objects */
-#define ELFCLASSNUM     3
-
-#define EI_DATA         5               /* Data encoding byte index */
-#define ELFDATANONE     0               /* Invalid data encoding */
-#define ELFDATA2LSB     1               /* 2's complement, little endian */
-#define ELFDATA2MSB     2               /* 2's complement, big endian */
-#define ELFDATANUM      3
-
-#define EI_VERSION      6               /* File version byte index */
-                                        /* Value must be EV_CURRENT */
-
-#define EI_OSABI        7               /* OS ABI identification */
-#define ELFOSABI_SYSV           0       /* UNIX System V ABI */
-#define ELFOSABI_HPUX           1       /* HP-UX */
-#define ELFOSABI_FREEBSD        9       /* Free BSD */
-#define ELFOSABI_ARM            97      /* ARM */
-#define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
-
-#define EI_ABIVERSION   8               /* ABI version */
-
-#define EI_PAD          9               /* Byte index of padding bytes */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_GNU		3	/* Object uses GNU ELF extensions.  */
+#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM_AEABI	64	/* ARM EABI */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
 
 /* Legal values for e_type (object file type).  */
 
-#define ET_NONE         0               /* No file type */
-#define ET_REL          1               /* Relocatable file */
-#define ET_EXEC         2               /* Executable file */
-#define ET_DYN          3               /* Shared object file */
-#define ET_CORE         4               /* Core file */
-#define ET_NUM          5               /* Number of defined types */
-#define ET_LOPROC       0xff00          /* Processor-specific */
-#define ET_HIPROC       0xffff          /* Processor-specific */
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
 
 /* Legal values for e_machine (architecture).  */
 
-#define EM_NONE          0              /* No machine */
-#define EM_M32           1              /* AT&T WE 32100 */
-#define EM_SPARC         2              /* SUN SPARC */
-#define EM_386           3              /* Intel 80386 */
-#define EM_68K           4              /* Motorola m68k family */
-#define EM_88K           5              /* Motorola m88k family */
-#define EM_486           6              /* Intel 80486 */
-#define EM_860           7              /* Intel 80860 */
-#define EM_MIPS          8              /* MIPS R3000 big-endian */
-#define EM_S370          9              /* Amdahl */
-#define EM_MIPS_RS4_BE  10              /* MIPS R4000 big-endian */
-#define EM_RS6000       11              /* RS6000 */
-
-#define EM_PARISC       15              /* HPPA */
-#define EM_nCUBE        16              /* nCUBE */
-#define EM_VPP500       17              /* Fujitsu VPP500 */
-#define EM_SPARC32PLUS  18              /* Sun's "v8plus" */
-#define EM_960          19              /* Intel 80960 */
-#define EM_PPC          20              /* PowerPC */
-
-#define EM_V800         36              /* NEC V800 series */
-#define EM_FR20         37              /* Fujitsu FR20 */
-#define EM_RH32         38              /* TRW RH32 */
-#define EM_RCE          39              /* Motorola RCE */
-#define EM_ARM          40              /* ARM */
-#define EM_FAKE_ALPHA   41              /* Digital Alpha */
-#define EM_SH           42              /* Hitachi SH */
-#define EM_SPARCV9      43              /* SPARC v9 64-bit */
-#define EM_TRICORE      44              /* Siemens Tricore */
-#define EM_ARC          45              /* Argonaut RISC Core */
-#define EM_H8_300       46              /* Hitachi H8/300 */
-#define EM_H8_300H      47              /* Hitachi H8/300H */
-#define EM_H8S          48              /* Hitachi H8S */
-#define EM_H8_500       49              /* Hitachi H8/500 */
-#define EM_IA_64        50              /* Intel Merced */
-#define EM_MIPS_X       51              /* Stanford MIPS-X */
-#define EM_COLDFIRE     52              /* Motorola Coldfire */
-#define EM_68HC12       53              /* Motorola M68HC12 */
-#define EM_MMA          54              /* Fujitsu MMA Multimedia Accelerator*/
-#define EM_PCP          55              /* Siemens PCP */
-#define EM_NCPU         56              /* Sony nCPU embeeded RISC */
-#define EM_NDR1         57              /* Denso NDR1 microprocessor */
-#define EM_STARCORE     58              /* Motorola Start*Core processor */
-#define EM_ME16         59              /* Toyota ME16 processor */
-#define EM_ST100        60              /* STMicroelectronic ST100 processor */
-#define EM_TINYJ        61              /* Advanced Logic Corp. Tinyj emb.fam*/
-#define EM_X86_64       62              /* AMD x86-64 architecture */
-#define EM_PDSP         63              /* Sony DSP Processor */
-#define EM_FX66         66              /* Siemens FX66 microcontroller */
-#define EM_ST9PLUS      67              /* STMicroelectronics ST9+ 8/16 mc */
-#define EM_ST7          68              /* STmicroelectronics ST7 8 bit mc */
-#define EM_68HC16       69              /* Motorola MC68HC16 microcontroller */
-#define EM_68HC11       70              /* Motorola MC68HC11 microcontroller */
-#define EM_68HC08       71              /* Motorola MC68HC08 microcontroller */
-#define EM_68HC05       72              /* Motorola MC68HC05 microcontroller */
-#define EM_SVX          73              /* Silicon Graphics SVx */
-#define EM_ST19         74              /* STMicroelectronics ST19 8 bit mc */
-#define EM_VAX          75              /* Digital VAX */
-#define EM_CRIS         76              /* Axis Communications 32-bit embedded processor */
-#define EM_JAVELIN      77              /* Infineon Technologies 32-bit embedded processor */
-#define EM_FIREPATH     78              /* Element 14 64-bit DSP Processor */
-#define EM_ZSP          79              /* LSI Logic 16-bit DSP Processor */
-#define EM_MMIX         80              /* Donald Knuth's educational 64-bit processor */
-#define EM_HUANY        81              /* Harvard University machine-independent object files */
-#define EM_PRISM        82              /* SiTera Prism */
-#define EM_AVR          83              /* Atmel AVR 8-bit microcontroller */
-#define EM_FR30         84              /* Fujitsu FR30 */
-#define EM_D10V         85              /* Mitsubishi D10V */
-#define EM_D30V         86              /* Mitsubishi D30V */
-#define EM_V850         87              /* NEC v850 */
-#define EM_M32R         88              /* Mitsubishi M32R */
-#define EM_MN10300      89              /* Matsushita MN10300 */
-#define EM_MN10200      90              /* Matsushita MN10200 */
-#define EM_PJ           91              /* picoJava */
-#define EM_OPENRISC     92              /* OpenRISC 32-bit embedded processor */
-#define EM_ARC_A5       93              /* ARC Cores Tangent-A5 */
-#define EM_XTENSA       94              /* Tensilica Xtensa Architecture */
-#define EM_NUM          95
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+#define EM_PPC64	21		/* PowerPC 64-bit */
+#define EM_S390		22		/* IBM S390 */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH-32 */
+#define EM_RCE		39		/* Motorola RCE */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP		55		/* Siemens PCP */
+#define EM_NCPU		56		/* Sony nCPU embedded RISC */
+#define EM_NDR1		57		/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58		/* Motorola Start*Core processor */
+#define EM_ME16		59		/* Toyota ME16 processor */
+#define EM_ST100	60		/* STMicroelectronic ST100 processor */
+#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64	62		/* AMD x86-64 architecture */
+#define EM_PDSP		63		/* Sony DSP Processor */
+
+#define EM_FX66		66		/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68		/* STMicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73		/* Silicon Graphics SVx */
+#define EM_ST19		74		/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75		/* Digital VAX */
+#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81		/* Harvard University machine-independent object files */
+#define EM_PRISM	82		/* SiTera Prism */
+#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84		/* Fujitsu FR30 */
+#define EM_D10V		85		/* Mitsubishi D10V */
+#define EM_D30V		86		/* Mitsubishi D30V */
+#define EM_V850		87		/* NEC v850 */
+#define EM_M32R		88		/* Mitsubishi M32R */
+#define EM_MN10300	89		/* Matsushita MN10300 */
+#define EM_MN10200	90		/* Matsushita MN10200 */
+#define EM_PJ		91		/* picoJava */
+#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
+#define EM_AARCH64	183		/* ARM AARCH64 */
+#define EM_TILEPRO	188		/* Tilera TILEPro */
+#define EM_TILEGX	191		/* Tilera TILE-Gx */
+#define EM_NUM		192
 
 /* If it is necessary to assign new unofficial EM_* values, please
@@ -256,12 +269,12 @@
    chances of collision with official or non-GNU unofficial values.  */
 
-#define EM_ALPHA        0x9026
-#define EM_C60          0x9c60
+#define EM_ALPHA	0x9026
+#define EM_C60		0x9c60
 
 /* Legal values for e_version (version).  */
 
-#define EV_NONE         0               /* Invalid ELF version */
-#define EV_CURRENT      1               /* Current version */
-#define EV_NUM          2
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
 
 /* Section header.  */
@@ -269,94 +282,109 @@
 typedef struct
 {
-  Elf32_Word    sh_name;                /* Section name (string tbl index) */
-  Elf32_Word    sh_type;                /* Section type */
-  Elf32_Word    sh_flags;               /* Section flags */
-  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
-  Elf32_Off     sh_offset;              /* Section file offset */
-  Elf32_Word    sh_size;                /* Section size in bytes */
-  Elf32_Word    sh_link;                /* Link to another section */
-  Elf32_Word    sh_info;                /* Additional section information */
-  Elf32_Word    sh_addralign;           /* Section alignment */
-  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
-} Elf32_Shdr;
-
-typedef struct
-{
-  Elf64_Word    sh_name;                /* Section name (string tbl index) */
-  Elf64_Word    sh_type;                /* Section type */
-  Elf64_Xword   sh_flags;               /* Section flags */
-  Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
-  Elf64_Off     sh_offset;              /* Section file offset */
-  Elf64_Xword   sh_size;                /* Section size in bytes */
-  Elf64_Word    sh_link;                /* Link to another section */
-  Elf64_Word    sh_info;                /* Additional section information */
-  Elf64_Xword   sh_addralign;           /* Section alignment */
-  Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
-} Elf64_Shdr;
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} __attribute__((packed)) Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} __attribute__((packed)) Elf64_Shdr;
 
 /* Special section indices.  */
 
-#define SHN_UNDEF       0               /* Undefined section */
-#define SHN_LORESERVE   0xff00          /* Start of reserved indices */
-#define SHN_LOPROC      0xff00          /* Start of processor-specific */
-#define SHN_HIPROC      0xff1f          /* End of processor-specific */
-#define SHN_ABS         0xfff1          /* Associated symbol is absolute */
-#define SHN_COMMON      0xfff2          /* Associated symbol is common */
-#define SHN_HIRESERVE   0xffff          /* End of reserved indices */
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_BEFORE	0xff00		/* Order section before all others
+					   (Solaris).  */
+#define SHN_AFTER	0xff01		/* Order section after all others
+					   (Solaris).  */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
 
 /* Legal values for sh_type (section type).  */
 
-#define SHT_NULL         0              /* Section header table entry unused */
-#define SHT_PROGBITS     1              /* Program data */
-#define SHT_SYMTAB       2              /* Symbol table */
-#define SHT_STRTAB       3              /* String table */
-#define SHT_RELA         4              /* Relocation entries with addends */
-#define SHT_HASH         5              /* Symbol hash table */
-#define SHT_DYNAMIC      6              /* Dynamic linking information */
-#define SHT_NOTE         7              /* Notes */
-#define SHT_NOBITS       8              /* Program space with no data (bss) */
-#define SHT_REL          9              /* Relocation entries, no addends */
-#define SHT_SHLIB        10             /* Reserved */
-#define SHT_DYNSYM       11             /* Dynamic linker symbol table */
-#define SHT_INIT_ARRAY   14             /* Array of constructors */
-#define SHT_FINI_ARRAY   15             /* Array of destructors */
-#define SHT_PREINIT_ARRAY 16            /* Array of pre-constructors */
-#define SHT_GROUP        17             /* Section group */
-#define SHT_SYMTAB_SHNDX 18             /* Extended section indices */
-#define SHT_NUM          19             /* Number of defined types.  */
-#define SHT_LOOS         0x60000000     /* Start OS-specific */
-#define SHT_LOSUNW       0x6ffffffb     /* Sun-specific low bound.  */
-#define SHT_SUNW_COMDAT  0x6ffffffb
-#define SHT_SUNW_syminfo 0x6ffffffc
-#define SHT_GNU_verdef   0x6ffffffd     /* Version definition section.  */
-#define SHT_GNU_verneed  0x6ffffffe     /* Version needs section.  */
-#define SHT_GNU_versym   0x6fffffff     /* Version symbol table.  */
-#define SHT_HISUNW       0x6fffffff     /* Sun-specific high bound.  */
-#define SHT_HIOS         0x6fffffff     /* End OS-specific type */
-#define SHT_LOPROC       0x70000000     /* Start of processor-specific */
-#define SHT_ARM_EXIDX    0x70000001     /* Exception Index table */
-#define SHT_ARM_PREEMPTMAP 0x70000002   /* dynamic linking pre-emption map */
-#define SHT_ARM_ATTRIBUTES 0x70000003   /* Object file compatibility attrs */
-#define SHT_HIPROC       0x7fffffff     /* End of processor-specific */
-#define SHT_LOUSER       0x80000000     /* Start of application-specific */
-#define SHT_HIUSER       0x8fffffff     /* End of application-specific */
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indices */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
+#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
 
 /* Legal values for sh_flags (section flags).  */
 
-#define SHF_WRITE       (1 << 0)        /* Writable */
-#define SHF_ALLOC       (1 << 1)        /* Occupies memory during execution */
-#define SHF_EXECINSTR   (1 << 2)        /* Executable */
-#define SHF_MASKPROC    0xf0000000      /* Processor-specific */
-
-#define SHF_MERGE       0x10
-#define SHF_STRINGS     0x20
-#define SHF_INFO_LINK   0x40
-#define SHF_LINK_ORDER  0x80
-#define SHF_OS_NONCONFORMING 0x100
-#define SHF_GROUP       0x200
-#define SHF_TLS         0x400
-#define SHF_MASKOS      0x0ff00000
-#define SHF_ORDERED     0x40000000
-#define SHF_EXCLUDE     0x80000000
+#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.  */
+#define SHF_COMPRESSED	     (1 << 11)	/* Section with compressed data. */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
+					   (Solaris).  */
+#define SHF_EXCLUDE	     (1 << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
 
 /* Symbol table entry.  */
@@ -364,21 +392,21 @@
 typedef struct
 {
-  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
-  Elf32_Addr    st_value;               /* Symbol value */
-  Elf32_Word    st_size;                /* Symbol size */
-  unsigned char st_info;                /* Symbol type and binding */
-  unsigned char st_other;               /* No defined meaning, 0 */
-  Elf32_Section st_shndx;               /* Section index */
-} Elf32_Sym;
-
-typedef struct
-{
-  Elf64_Word    st_name;                /* Symbol name (string tbl index) */
-  unsigned char st_info;                /* Symbol type and binding */
-  unsigned char st_other;               /* No defined meaning, 0 */
-  Elf64_Section st_shndx;               /* Section index */
-  Elf64_Addr    st_value;               /* Symbol value */
-  Elf64_Xword   st_size;                /* Symbol size */
-} Elf64_Sym;
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} __attribute__((packed)) Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} __attribute__((packed)) Elf64_Sym;
 
 /* The syminfo section if available contains additional information about
@@ -387,70 +415,69 @@
 typedef struct
 {
-  Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
-  Elf32_Half si_flags;                  /* Per symbol flags */
-} Elf32_Syminfo;
-
-typedef struct
-{
-  Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
-  Elf64_Half si_flags;                  /* Per symbol flags */
-} Elf64_Syminfo;
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} __attribute__((packed)) Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} __attribute__((packed)) Elf64_Syminfo;
 
 /* Possible values for si_boundto.  */
-#define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
-#define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
-#define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
 
 /* Possible bitmasks for si_flags.  */
-#define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */
-#define SYMINFO_FLG_PASSTHRU    0x0002  /* Pass-thru symbol for translator */
-#define SYMINFO_FLG_COPY        0x0004  /* Symbol is a copy-reloc */
-#define SYMINFO_FLG_LAZYLOAD    0x0008  /* Symbol bound to object to be lazy
-                                           loaded */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
 /* Syminfo version values.  */
-#define SYMINFO_NONE            0
-#define SYMINFO_CURRENT         1
-#define SYMINFO_NUM             2
-
-
-/* Special section index.  */
-
-#define SHN_UNDEF       0               /* No section, undefined symbol.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
 
 /* 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)
-#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
 
 /* 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)
-#define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
 
 /* 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 */
+#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_GNU_UNIQUE	10		/* Unique symbol.  */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
 
 /* Legal values for ST_TYPE subfield of st_info (symbol type).  */
 
-#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_NUM         5               /* Number of defined types.  */
-#define STT_GNU_IFUNC   10              /* Symbol is a indirect code object */
-#define STT_LOOS        11              /* Start of OS-specific */
-#define STT_HIOS        12              /* End of OS-specific */
-#define STT_LOPROC      13              /* Start of processor-specific */
-#define STT_HIPROC      15              /* End of processor-specific */
+#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.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_GNU_IFUNC	10		/* Symbol is indirect code object */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
 
 
@@ -459,19 +486,19 @@
    the end of a chain, meaning no further symbols are found in that bucket.  */
 
-#define STN_UNDEF       0               /* End of a chain.  */
+#define STN_UNDEF	0		/* End of a chain.  */
 
 
 /* How to extract and insert information held in the st_other field.  */
 
-#define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
 
 /* For ELF64 the definitions are the same.  */
-#define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
 
 /* Symbol visibility specification encoded in the st_other field.  */
-#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 */
+#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 */
 
 
@@ -480,7 +507,7 @@
 typedef struct
 {
-  Elf32_Addr    r_offset;               /* Address */
-  Elf32_Word    r_info;                 /* Relocation type and symbol index */
-} Elf32_Rel;
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} __attribute__((packed)) Elf32_Rel;
 
 /* I have seen two different definitions of the Elf64_Rel and
@@ -491,7 +518,7 @@
 typedef struct
 {
-  Elf64_Addr    r_offset;               /* Address */
-  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
-} Elf64_Rel;
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} __attribute__((packed)) Elf64_Rel;
 
 /* Relocation table entry with addend (in section of type SHT_RELA).  */
@@ -499,25 +526,25 @@
 typedef struct
 {
-  Elf32_Addr    r_offset;               /* Address */
-  Elf32_Word    r_info;                 /* Relocation type and symbol index */
-  Elf32_Sword   r_addend;               /* Addend */
-} Elf32_Rela;
-
-typedef struct
-{
-  Elf64_Addr    r_offset;               /* Address */
-  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
-  Elf64_Sxword  r_addend;               /* Addend */
-} Elf64_Rela;
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} __attribute__((packed)) Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} __attribute__((packed)) Elf64_Rela;
 
 /* How to extract and insert information held in the r_info field.  */
 
-#define ELF32_R_SYM(val)                ((val) >> 8)
-#define ELF32_R_TYPE(val)               ((val) & 0xff)
-#define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
-
-#define ELF64_R_SYM(i)                  ((i) >> 32)
-#define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
-#define ELF64_R_INFO(sym,type)          ((((Elf64_Xword)(sym)) << 32) + (type))
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
 
 /* Program segment header.  */
@@ -525,67 +552,104 @@
 typedef struct
 {
-  Elf32_Word    p_type;                 /* Segment type */
-  Elf32_Off     p_offset;               /* Segment file offset */
-  Elf32_Addr    p_vaddr;                /* Segment virtual address */
-  Elf32_Addr    p_paddr;                /* Segment physical address */
-  Elf32_Word    p_filesz;               /* Segment size in file */
-  Elf32_Word    p_memsz;                /* Segment size in memory */
-  Elf32_Word    p_flags;                /* Segment flags */
-  Elf32_Word    p_align;                /* Segment alignment */
-} Elf32_Phdr;
-
-typedef struct
-{
-  Elf64_Word    p_type;                 /* Segment type */
-  Elf64_Word    p_flags;                /* Segment flags */
-  Elf64_Off     p_offset;               /* Segment file offset */
-  Elf64_Addr    p_vaddr;                /* Segment virtual address */
-  Elf64_Addr    p_paddr;                /* Segment physical address */
-  Elf64_Xword   p_filesz;               /* Segment size in file */
-  Elf64_Xword   p_memsz;                /* Segment size in memory */
-  Elf64_Xword   p_align;                /* Segment alignment */
-} Elf64_Phdr;
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} __attribute__((packed)) Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} __attribute__((packed)) Elf64_Phdr;
+
+/* Special value for e_phnum.  This indicates that the real number of
+   program headers is too large to fit into e_phnum.  Instead the real
+   value is in the field sh_info of section 0.  */
+
+#define PN_XNUM		0xffff
 
 /* Legal values for p_type (segment type).  */
 
-#define PT_NULL         0               /* Program header table entry unused */
-#define PT_LOAD         1               /* Loadable program segment */
-#define PT_DYNAMIC      2               /* Dynamic linking information */
-#define PT_INTERP       3               /* Program interpreter */
-#define PT_NOTE         4               /* Auxiliary information */
-#define PT_SHLIB        5               /* Reserved */
-#define PT_PHDR         6               /* Entry for header table itself */
-#define PT_NUM          7               /* Number of defined types.  */
-#define PT_LOOS         0x60000000      /* Start of OS-specific */
-#define PT_HIOS         0x6fffffff      /* End of OS-specific */
-#define PT_LOPROC       0x70000000      /* Start of processor-specific */
-#define PT_HIPROC       0x7fffffff      /* End of processor-specific */
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
+#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
 
 /* Legal values for p_flags (segment flags).  */
 
-#define PF_X            (1 << 0)        /* Segment is executable */
-#define PF_W            (1 << 1)        /* Segment is writable */
-#define PF_R            (1 << 2)        /* Segment is readable */
-#define PF_MASKPROC     0xf0000000      /* Processor-specific */
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
 
 /* Legal values for note segment descriptor types for core files. */
 
-#define NT_PRSTATUS     1               /* Contains copy of prstatus struct */
-#define NT_FPREGSET     2               /* Contains copy of fpregset struct */
-#define NT_PRPSINFO     3               /* Contains copy of prpsinfo struct */
-#define NT_PRXREG       4               /* Contains copy of prxregset struct */
-#define NT_PLATFORM     5               /* String from sysinfo(SI_PLATFORM) */
-#define NT_AUXV         6               /* Contains copy of auxv array */
-#define NT_GWINDOWS     7               /* Contains copy of gwindows struct */
-#define NT_PSTATUS      10              /* Contains copy of pstatus struct */
-#define NT_PSINFO       13              /* Contains copy of psinfo struct */
-#define NT_PRCRED       14              /* Contains copy of prcred struct */
-#define NT_UTSNAME      15              /* Contains copy of utsname struct */
-#define NT_LWPSTATUS    16              /* Contains copy of lwpstatus struct */
-#define NT_LWPSINFO     17              /* Contains copy of lwpinfo struct */
-
-/* Legal values for the  note segment descriptor types for object files.  */
-
-#define NT_VERSION      1               /* Contains a version string.  */
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
+#define NT_S390_TIMER	0x301		/* s390 timer register */
+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
+#define NT_S390_CTRS	0x304		/* s390 control registers */
+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
 
 
@@ -594,69 +658,84 @@
 typedef struct
 {
-  Elf32_Sword   d_tag;                  /* Dynamic entry type */
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
   union
     {
-      Elf32_Word d_val;                 /* Integer value */
-      Elf32_Addr d_ptr;                 /* Address value */
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
     } d_un;
-} Elf32_Dyn;
-
-typedef struct
-{
-  Elf64_Sxword  d_tag;                  /* Dynamic entry type */
+} __attribute__((packed)) Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
   union
     {
-      Elf64_Xword d_val;                /* Integer value */
-      Elf64_Addr d_ptr;                 /* Address value */
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
     } d_un;
-} Elf64_Dyn;
+} __attribute__((packed)) Elf64_Dyn;
 
 /* Legal values for d_tag (dynamic entry type).  */
 
-#define DT_NULL         0               /* Marks end of dynamic section */
-#define DT_NEEDED       1               /* Name of needed library */
-#define DT_PLTRELSZ     2               /* Size in bytes of PLT relocs */
-#define DT_PLTGOT       3               /* Processor defined value */
-#define DT_HASH         4               /* Address of symbol hash table */
-#define DT_STRTAB       5               /* Address of string table */
-#define DT_SYMTAB       6               /* Address of symbol table */
-#define DT_RELA         7               /* Address of Rela relocs */
-#define DT_RELASZ       8               /* Total size of Rela relocs */
-#define DT_RELAENT      9               /* Size of one Rela reloc */
-#define DT_STRSZ        10              /* Size of string table */
-#define DT_SYMENT       11              /* Size of one symbol table entry */
-#define DT_INIT         12              /* Address of init function */
-#define DT_FINI         13              /* Address of termination function */
-#define DT_SONAME       14              /* Name of shared object */
-#define DT_RPATH        15              /* Library search path */
-#define DT_SYMBOLIC     16              /* Start symbol search here */
-#define DT_REL          17              /* Address of Rel relocs */
-#define DT_RELSZ        18              /* Total size of Rel relocs */
-#define DT_RELENT       19              /* Size of one Rel reloc */
-#define DT_PLTREL       20              /* Type of reloc in PLT */
-#define DT_DEBUG        21              /* For debugging; unspecified */
-#define DT_TEXTREL      22              /* Reloc might modify .text */
-#define DT_JMPREL       23              /* Address of PLT relocs */
-#define DT_BIND_NOW     24              /* Process relocations of object */
-#define DT_INIT_ARRAY   25              /* Array with addresses of init fct */
-#define DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
-#define DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
-#define DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
-#define DT_NUM          29              /* Number used */
-#define DT_LOOS         0x60000000      /* Start of OS-specific */
-#define DT_HIOS         0x6fffffff      /* End of OS-specific */
-#define DT_LOPROC       0x70000000      /* Start of processor-specific */
-#define DT_HIPROC       0x7fffffff      /* End of processor-specific */
-#define DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
 
 /* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
    Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
    approach.  */
-#define DT_VALRNGLO     0x6ffffd00
-#define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting
-                                           the following DT_* entry.  */
-#define DT_SYMINSZ      0x6ffffdfe      /* Size of syminfo table (in bytes) */
-#define DT_SYMINENT     0x6ffffdff      /* Entry size of syminfo */
-#define DT_VALRNGHI     0x6ffffdff
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
 
 /* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
@@ -665,21 +744,36 @@
    If any adjustment is made to the ELF object after it has been
    built these entries will need to be adjusted.  */
-#define DT_ADDRRNGLO    0x6ffffe00
-#define DT_SYMINFO      0x6ffffeff      /* syminfo table */
-#define DT_ADDRRNGHI    0x6ffffeff
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 11
 
 /* The versioning entry types.  The next are defined as part of the
    GNU extension.  */
-#define DT_VERSYM       0x6ffffff0
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
 
 /* These were chosen by Sun.  */
-#define DT_FLAGS_1      0x6ffffffb      /* State flags, see DF_1_* below.  */
-#define DT_VERDEF       0x6ffffffc      /* Address of version definition
-                                           table */
-#define DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
-#define DT_VERNEED      0x6ffffffe      /* Address of table with needed
-                                           versions */
-#define DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
-#define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
 #define DT_VERSIONTAGNUM 16
 
@@ -688,16 +782,51 @@
 #define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
 #define DT_FILTER       0x7fffffff      /* Shared object to get values from */
-#define DT_EXTRATAGIDX(tag)     ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
-#define DT_EXTRANUM     3
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
 
 /* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
    entry in the dynamic section.  */
-#define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
-#define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
-#define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
-#define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object.*/
-#define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime.*/
-#define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object*/
-#define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+#define	DF_1_NODIRECT	0x00020000	/* Object has no-direct binding. */
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000	/* Object is modified after built.  */
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000	/* Object has individual interposers.  */
+#define	DF_1_GLOBAUDIT	0x01000000	/* Global auditing required.  */
+#define	DF_1_SINGLETON	0x02000000	/* Singleton symbols are used.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
 
 /* Version definition sections.  */
@@ -705,51 +834,57 @@
 typedef struct
 {
-  Elf32_Half    vd_version;             /* Version revision */
-  Elf32_Half    vd_flags;               /* Version information */
-  Elf32_Half    vd_ndx;                 /* Version Index */
-  Elf32_Half    vd_cnt;                 /* Number of associated aux entries */
-  Elf32_Word    vd_hash;                /* Version name hash value */
-  Elf32_Word    vd_aux;                 /* Offset in bytes to verdaux array */
-  Elf32_Word    vd_next;                /* Offset in bytes to next verdef
-                                           entry */
-} Elf32_Verdef;
-
-typedef struct
-{
-  Elf64_Half    vd_version;             /* Version revision */
-  Elf64_Half    vd_flags;               /* Version information */
-  Elf64_Half    vd_ndx;                 /* Version Index */
-  Elf64_Half    vd_cnt;                 /* Number of associated aux entries */
-  Elf64_Word    vd_hash;                /* Version name hash value */
-  Elf64_Word    vd_aux;                 /* Offset in bytes to verdaux array */
-  Elf64_Word    vd_next;                /* Offset in bytes to next verdef
-                                           entry */
-} Elf64_Verdef;
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} __attribute__((packed)) Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} __attribute__((packed)) Elf64_Verdef;
 
 
 /* Legal values for vd_version (version revision).  */
-#define VER_DEF_NONE    0               /* No version */
-#define VER_DEF_CURRENT 1               /* Current version */
-#define VER_DEF_NUM     2               /* Given version number */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
 
 /* Legal values for vd_flags (version information flags).  */
-#define VER_FLG_BASE    0x1             /* Version definition of file itself */
-#define VER_FLG_WEAK    0x2             /* Weak version identifier */
-
-/* Auxialiary version information.  */
-
-typedef struct
-{
-  Elf32_Word    vda_name;               /* Version or dependency names */
-  Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
-                                           entry */
-} Elf32_Verdaux;
-
-typedef struct
-{
-  Elf64_Word    vda_name;               /* Version or dependency names */
-  Elf64_Word    vda_next;               /* Offset in bytes to next verdaux
-                                           entry */
-} Elf64_Verdaux;
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxiliary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} __attribute__((packed)) Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} __attribute__((packed)) Elf64_Verdaux;
 
 
@@ -758,29 +893,29 @@
 typedef struct
 {
-  Elf32_Half    vn_version;             /* Version of structure */
-  Elf32_Half    vn_cnt;                 /* Number of associated aux entries */
-  Elf32_Word    vn_file;                /* Offset of filename for this
-                                           dependency */
-  Elf32_Word    vn_aux;                 /* Offset in bytes to vernaux array */
-  Elf32_Word    vn_next;                /* Offset in bytes to next verneed
-                                           entry */
-} Elf32_Verneed;
-
-typedef struct
-{
-  Elf64_Half    vn_version;             /* Version of structure */
-  Elf64_Half    vn_cnt;                 /* Number of associated aux entries */
-  Elf64_Word    vn_file;                /* Offset of filename for this
-                                           dependency */
-  Elf64_Word    vn_aux;                 /* Offset in bytes to vernaux array */
-  Elf64_Word    vn_next;                /* Offset in bytes to next verneed
-                                           entry */
-} Elf64_Verneed;
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} __attribute__((packed)) Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} __attribute__((packed)) Elf64_Verneed;
 
 
 /* Legal values for vn_version (version revision).  */
-#define VER_NEED_NONE    0              /* No version */
-#define VER_NEED_CURRENT 1              /* Current version */
-#define VER_NEED_NUM     2              /* Given version number */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
 
 /* Auxiliary needed version information.  */
@@ -788,25 +923,25 @@
 typedef struct
 {
-  Elf32_Word    vna_hash;               /* Hash value of dependency name */
-  Elf32_Half    vna_flags;              /* Dependency specific information */
-  Elf32_Half    vna_other;              /* Unused */
-  Elf32_Word    vna_name;               /* Dependency name string offset */
-  Elf32_Word    vna_next;               /* Offset in bytes to next vernaux
-                                           entry */
-} Elf32_Vernaux;
-
-typedef struct
-{
-  Elf64_Word    vna_hash;               /* Hash value of dependency name */
-  Elf64_Half    vna_flags;              /* Dependency specific information */
-  Elf64_Half    vna_other;              /* Unused */
-  Elf64_Word    vna_name;               /* Dependency name string offset */
-  Elf64_Word    vna_next;               /* Offset in bytes to next vernaux
-                                           entry */
-} Elf64_Vernaux;
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} __attribute__((packed)) Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} __attribute__((packed)) Elf64_Vernaux;
 
 
 /* Legal values for vna_flags.  */
-#define VER_FLG_WEAK    0x2             /* Weak version identifier */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
 
 
@@ -822,51 +957,82 @@
 typedef struct
 {
-  int a_type;                   /* Entry type */
+  uint32_t a_type;		/* Entry type */
   union
     {
-      long int a_val;           /* Integer value */
-      void *a_ptr;              /* Pointer value */
-      void (*a_fcn) (void);     /* Function pointer value */
+      uint32_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
     } a_un;
-} Elf32_auxv_t;
-
-typedef struct
-{
-  long int a_type;              /* Entry type */
+} __attribute__((packed)) Elf32_auxv_t;
+
+typedef struct
+{
+  uint64_t a_type;		/* Entry type */
   union
     {
-      long int a_val;           /* Integer value */
-      void *a_ptr;              /* Pointer value */
-      void (*a_fcn) (void);     /* Function pointer value */
+      uint64_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
     } a_un;
-} Elf64_auxv_t;
+} __attribute__((packed)) Elf64_auxv_t;
 
 /* Legal values for a_type (entry type).  */
 
-#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_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_CLKTCK	17		/* Frequency of times() */
 
 /* Some more special a_type values describing the hardware.  */
-#define AT_PLATFORM     15              /* String identifying platform.  */
-#define AT_HWCAP        16              /* Machine dependent hints about
-                                           processor capabilities.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine dependent hints about
+					   processor capabilities.  */
 
 /* This entry gives some information about the FPU initialization
    performed by the kernel.  */
-#define AT_FPUCW        17              /* Used FPU control word.  */
-
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
+
+#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
+
+#define AT_BASE_PLATFORM 24		/* String identifying real platforms.*/
+
+#define AT_RANDOM	25		/* Address of 16 random bytes.  */
+
+#define AT_EXECFN	31		/* Filename of executable.  */
+
+/* Pointer to the global system page used for system calls and other
+   nice things.  */
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
 
 /* Note section contents.  Each entry in the note section begins with
@@ -875,23 +1041,23 @@
 typedef struct
 {
-  Elf32_Word n_namesz;                  /* Length of the note's name.  */
-  Elf32_Word n_descsz;                  /* Length of the note's descriptor.  */
-  Elf32_Word n_type;                    /* Type of the note.  */
-} Elf32_Nhdr;
-
-typedef struct
-{
-  Elf64_Word n_namesz;                  /* Length of the note's name.  */
-  Elf64_Word n_descsz;                  /* Length of the note's descriptor.  */
-  Elf64_Word n_type;                    /* Type of the note.  */
-} Elf64_Nhdr;
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} __attribute__((packed)) Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} __attribute__((packed)) Elf64_Nhdr;
 
 /* Known names of notes.  */
 
 /* Solaris entries in the note section have this name.  */
-#define ELF_NOTE_SOLARIS        "SUNW Solaris"
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
 
 /* Note entries for GNU systems have this name.  */
-#define ELF_NOTE_GNU            "GNU"
+#define ELF_NOTE_GNU		"GNU"
 
 
@@ -899,5 +1065,5 @@
 
 /* Value of descriptor (one word) is desired pagesize for the binary.  */
-#define ELF_NOTE_PAGESIZE_HINT  1
+#define ELF_NOTE_PAGESIZE_HINT	1
 
 
@@ -910,42 +1076,112 @@
    word 3: subminor version of the ABI
 */
-#define ELF_NOTE_ABI            1
-
-/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
-   note section entry.  */
-#define ELF_NOTE_OS_LINUX       0
-#define ELF_NOTE_OS_GNU         1
-#define ELF_NOTE_OS_SOLARIS2    2
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
+
+/* Known OSes.  These values can appear in word 0 of an
+   NT_GNU_ABI_TAG note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+/* Synthetic hwcap information.  The descriptor begins with two words:
+   word 0: number of entries
+   word 1: bitmask of enabled entries
+   Then follow variable-length entries, one byte followed by a
+   '\0'-terminated hwcap name string.  The byte gives the bit
+   number to test if enabled, (1U << bit) & bitmask.  */
+#define NT_GNU_HWCAP	2
+
+/* Build ID bits as generated by ld --build-id.
+   The descriptor consists of any nonzero number of bytes.  */
+#define NT_GNU_BUILD_ID	3
+
+/* Version note generated by GNU gold containing a version string.  */
+#define NT_GNU_GOLD_VERSION	4
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} __attribute__((packed)) Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} __attribute__((packed)) Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
 
 
 /* Motorola 68k specific definitions.  */
 
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
 /* m68k relocs.  */
 
-#define R_68K_NONE      0               /* No reloc */
-#define R_68K_32        1               /* Direct 32 bit  */
-#define R_68K_16        2               /* Direct 16 bit  */
-#define R_68K_8         3               /* Direct 8 bit  */
-#define R_68K_PC32      4               /* PC relative 32 bit */
-#define R_68K_PC16      5               /* PC relative 16 bit */
-#define R_68K_PC8       6               /* PC relative 8 bit */
-#define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
-#define R_68K_GOT16     8               /* 16 bit PC relative GOT entry */
-#define R_68K_GOT8      9               /* 8 bit PC relative GOT entry */
-#define R_68K_GOT32O    10              /* 32 bit GOT offset */
-#define R_68K_GOT16O    11              /* 16 bit GOT offset */
-#define R_68K_GOT8O     12              /* 8 bit GOT offset */
-#define R_68K_PLT32     13              /* 32 bit PC relative PLT address */
-#define R_68K_PLT16     14              /* 16 bit PC relative PLT address */
-#define R_68K_PLT8      15              /* 8 bit PC relative PLT address */
-#define R_68K_PLT32O    16              /* 32 bit PLT offset */
-#define R_68K_PLT16O    17              /* 16 bit PLT offset */
-#define R_68K_PLT8O     18              /* 8 bit PLT offset */
-#define R_68K_COPY      19              /* Copy symbol at runtime */
-#define R_68K_GLOB_DAT  20              /* Create GOT entry */
-#define R_68K_JMP_SLOT  21              /* Create PLT entry */
-#define R_68K_RELATIVE  22              /* Adjust by program base */
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
+#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
 /* Keep this the last entry.  */
-#define R_68K_NUM       23
+#define R_68K_NUM	43
 
 /* Intel 80386 specific definitions.  */
@@ -953,96 +1189,1667 @@
 /* i386 relocs.  */
 
-#define R_386_NONE      0               /* No reloc */
-#define R_386_32        1               /* Direct 32 bit  */
-#define R_386_PC32      2               /* PC relative 32 bit */
-#define R_386_GOT32     3               /* 32 bit GOT entry */
-#define R_386_PLT32     4               /* 32 bit PLT address */
-#define R_386_COPY      5               /* Copy symbol at runtime */
-#define R_386_GLOB_DAT  6               /* Create GOT entry */
-#define R_386_JMP_SLOT  7               /* Create PLT entry */
-#define R_386_RELATIVE  8               /* Adjust by program base */
-#define R_386_GOTOFF    9               /* 32 bit offset to GOT */
-#define R_386_GOTPC     10              /* 32 bit PC relative offset to GOT */
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* 38? */
+#define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
+#define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
+					   descriptor for
+					   relaxation.  */
+#define R_386_TLS_DESC     41		/* TLS descriptor containing
+					   pointer to code and to
+					   argument, returning the TLS
+					   offset for the symbol.  */
+#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
+#define R_386_GOT32X       43		/* 32 bit GOT entry, relaxable */
 /* Keep this the last entry.  */
-#define R_386_NUM       11
-
-/* TCC-specific 16-bit relocs. */
-#define R_386_16        12              /* Direct 16 bit  */
-#define R_386_PC16      13              /* PC relative 16 bit */
+#define R_386_NUM	   44
 
 /* SUN SPARC specific definitions.  */
 
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
+
 /* Values for Elf64_Ehdr.e_flags.  */
 
-#define EF_SPARCV9_MM           3
-#define EF_SPARCV9_TSO          0
-#define EF_SPARCV9_PSO          1
-#define EF_SPARCV9_RMO          2
-#define EF_SPARC_EXT_MASK       0xFFFF00
-#define EF_SPARC_SUN_US1        0x000200
-#define EF_SPARC_HAL_R1         0x000400
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
 
 /* SPARC relocs.  */
 
-#define R_SPARC_NONE    0               /* No reloc */
-#define R_SPARC_8       1               /* Direct 8 bit */
-#define R_SPARC_16      2               /* Direct 16 bit */
-#define R_SPARC_32      3               /* Direct 32 bit */
-#define R_SPARC_DISP8   4               /* PC relative 8 bit */
-#define R_SPARC_DISP16  5               /* PC relative 16 bit */
-#define R_SPARC_DISP32  6               /* PC relative 32 bit */
-#define R_SPARC_WDISP30 7               /* PC relative 30 bit shifted */
-#define R_SPARC_WDISP22 8               /* PC relative 22 bit shifted */
-#define R_SPARC_HI22    9               /* High 22 bit */
-#define R_SPARC_22      10              /* Direct 22 bit */
-#define R_SPARC_13      11              /* Direct 13 bit */
-#define R_SPARC_LO10    12              /* Truncated 10 bit */
-#define R_SPARC_GOT10   13              /* Truncated 10 bit GOT entry */
-#define R_SPARC_GOT13   14              /* 13 bit GOT entry */
-#define R_SPARC_GOT22   15              /* 22 bit GOT entry shifted */
-#define R_SPARC_PC10    16              /* PC relative 10 bit truncated */
-#define R_SPARC_PC22    17              /* PC relative 22 bit shifted */
-#define R_SPARC_WPLT30  18              /* 30 bit PC relative PLT address */
-#define R_SPARC_COPY    19              /* Copy symbol at runtime */
-#define R_SPARC_GLOB_DAT 20             /* Create GOT entry */
-#define R_SPARC_JMP_SLOT 21             /* Create PLT entry */
-#define R_SPARC_RELATIVE 22             /* Adjust by program base */
-#define R_SPARC_UA32    23              /* Direct 32 bit unaligned */
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
 
 /* Additional Sparc64 relocs.  */
 
-#define R_SPARC_PLT32   24              /* Direct 32 bit ref to PLT entry */
-#define R_SPARC_HIPLT22 25              /* High 22 bit PLT entry */
-#define R_SPARC_LOPLT10 26              /* Truncated 10 bit PLT entry */
-#define R_SPARC_PCPLT32 27              /* PC rel 32 bit ref to PLT entry */
-#define R_SPARC_PCPLT22 28              /* PC rel high 22 bit PLT entry */
-#define R_SPARC_PCPLT10 29              /* PC rel trunc 10 bit PLT entry */
-#define R_SPARC_10      30              /* Direct 10 bit */
-#define R_SPARC_11      31              /* Direct 11 bit */
-#define R_SPARC_64      32              /* Direct 64 bit */
-#define R_SPARC_OLO10   33              /* ?? */
-#define R_SPARC_HH22    34              /* Top 22 bits of direct 64 bit */
-#define R_SPARC_HM10    35              /* High middle 10 bits of ... */
-#define R_SPARC_LM22    36              /* Low middle 22 bits of ... */
-#define R_SPARC_PC_HH22 37              /* Top 22 bits of pc rel 64 bit */
-#define R_SPARC_PC_HM10 38              /* High middle 10 bit of ... */
-#define R_SPARC_PC_LM22 39              /* Low miggle 22 bits of ... */
-#define R_SPARC_WDISP16 40              /* PC relative 16 bit shifted */
-#define R_SPARC_WDISP19 41              /* PC relative 19 bit shifted */
-#define R_SPARC_7       43              /* Direct 7 bit */
-#define R_SPARC_5       44              /* Direct 5 bit */
-#define R_SPARC_6       45              /* Direct 6 bit */
-#define R_SPARC_DISP64  46              /* PC relative 64 bit */
-#define R_SPARC_PLT64   47              /* Direct 64 bit ref to PLT entry */
-#define R_SPARC_HIX22   48              /* High 22 bit complemented */
-#define R_SPARC_LOX10   49              /* Truncated 11 bit complemented */
-#define R_SPARC_H44     50              /* Direct high 12 of 44 bit */
-#define R_SPARC_M44     51              /* Direct mid 22 of 44 bit */
-#define R_SPARC_L44     52              /* Direct low 10 of 44 bit */
-#define R_SPARC_REGISTER 53             /* Global register usage */
-#define R_SPARC_UA64    54              /* Direct 64 bit unaligned */
-#define R_SPARC_UA16    55              /* Direct 16 bit unaligned */
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low middle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP	42	/* was part of v9 ABI but was removed */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_WDISP10		88
+#define R_SPARC_JMP_IREL	248
+#define R_SPARC_IRELATIVE	249
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
 /* Keep this the last entry.  */
-#define R_SPARC_NUM     56
+#define R_SPARC_NUM		253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
+#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
+#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
+#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
+#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
+#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
+#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
+#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
+#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
+      Elf32_Word gt_unused;		/* Not used */
+    } gt_header;			/* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G */
+      Elf32_Word gt_bytes;		/* This many bytes would be used */
+    } gt_entry;				/* Subsequent entries in section */
+} __attribute__((packed)) Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word	ri_gprmask;		/* General registers used */
+  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
+  Elf32_Sword	ri_gp_value;		/* $gp register value */
+} __attribute__((packed)) Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} __attribute__((packed)) Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} __attribute__((packed)) Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		128
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+/* The address of .got.plt in an executable using the new non-PIC ABI.  */
+#define DT_MIPS_PLTGOT	     0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
+   value.  */
+#define DT_MIPS_RWPLT        0x70000034
+#define DT_MIPS_NUM	     0x35
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} __attribute__((packed)) Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} __attribute__((packed)) Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indices.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tentatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
+#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
+#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
+#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
+#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
+#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
+#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
+#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
+#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
+#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
+#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
+#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primarily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE		0	/* No reloc */
+#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
+#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
+#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
+#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
+#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
+#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
+#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
+#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
+#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+/* Legal values for d_tag of Elf64_Dyn.  */
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC_IRELATIVE		248
+
+/* GNU relocs used in PIC code sequences.  */
+#define R_PPC_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
+#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
+#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_NUM		1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
+#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64		45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC		51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16	52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI.  */
+#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
+#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
+#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_NUM    3
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD	0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+/* Additional symbol types for Thumb.  */
+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
+					      in the input to a link step.  */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB		0x10000000 /* Segment contains the location
+					      addressed by the static base. */
+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
+
+
+/* AArch64 relocs.  */
+
+#define R_AARCH64_NONE            0	/* No relocation.  */
+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
+#define R_AARCH64_ABS16         259	/* Direct 16-bit.  */
+#define R_AARCH64_PREL64        260	/* PC-relative 64-bit.  */
+#define R_AARCH64_PREL32        261	/* PC-relative 32-bit.  */
+#define R_AARCH64_PREL16        262	/* PC-relative 16-bit.  */
+#define R_AARCH64_MOVW_UABS_G0  263	/* Dir. MOVZ imm. from bits 15:0.  */
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G1  265	/* Dir. MOVZ imm. from bits 31:16.  */
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G2  267	/* Dir. MOVZ imm. from bits 47:32.  */
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G3  269	/* Dir. MOV{K,Z} imm. from 63:48.  */
+#define R_AARCH64_MOVW_SABS_G0  270	/* Dir. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_SABS_G1  271	/* Dir. MOV{N,Z} imm. from 31:16.  */
+#define R_AARCH64_MOVW_SABS_G2  272	/* Dir. MOV{N,Z} imm. from 47:32.  */
+#define R_AARCH64_LD_PREL_LO19  273	/* PC-rel. LD imm. from bits 20:2.  */
+#define R_AARCH64_ADR_PREL_LO21 274	/* PC-rel. ADR imm. from bits 20:0.  */
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276	/* Likewise; no overflow check.  */
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14       279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
+#define R_AARCH64_CONDBR19      280	/* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26        282	/* PC-rel. B imm. from bits 27:2.  */
+#define R_AARCH64_CALL26        283	/* Likewise for CALL.  */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284	/* Dir. ADD imm. from bits 11:1.  */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285	/* Likewise for bits 11:2.  */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286	/* Likewise for bits 11:3.  */
+#define R_AARCH64_MOVW_PREL_G0  287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G1  289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G2  291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G3  293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299	/* Dir. ADD imm. from bits 11:4.  */
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
+#define R_AARCH64_GOTREL64      307	/* GOT-relative 64-bit.  */
+#define R_AARCH64_GOTREL32      308	/* GOT-relative 32-bit.  */
+#define R_AARCH64_GOT_LD_PREL19 309	/* PC-rel. GOT off. load imm. 20:2.  */
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
+#define R_AARCH64_ADR_GOT_PAGE  311	/* P-page-rel. GOT off. ADRP 32:12.  */
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSGD_MOVW_G1 515	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G1 520	/* Like 515; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523	/* TLS DTP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524	/* TLS DTP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526	/* TLS DTP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528	/* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529	/* DTP-rel. ADD imm. from 11:0.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530	/* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531	/* DTP-rel. LD/ST imm. 11:0.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533	/* DTP-rel. LD/ST imm. 11:1.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535	/* DTP-rel. LD/ST imm. 11:2.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537	/* DTP-rel. LD/ST imm. 11:3.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538	/* Likewise; no check.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540	/* GOT-rel. MOVK 15:0.  */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541	/* Page-rel. ADRP 32:12.  */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542	/* Direct LD off. 11:3.  */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543	/* PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544	/* TLS TP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545	/* TLS TP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547	/* TLS TP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549	/* TP-rel. ADD imm. 23:12.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550	/* TP-rel. ADD imm. 11:0.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551	/* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552	/* TP-rel. LD/ST off. 11:0.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553	/* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554	/* TP-rel. LD/ST off. 11:1.  */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555	/* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556	/* TP-rel. LD/ST off. 11:2.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557	/* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558	/* TP-rel. LD/ST off. 11:3.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559	/* Likewise; no check.  */
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561	/* PC-rel. ADR immediate 20:0.  */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562	/* Page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
+#define R_AARCH64_TLSDESC_LDR   567	/* Relax LDR.  */
+#define R_AARCH64_TLSDESC_ADD   568	/* Relax ADD.  */
+#define R_AARCH64_TLSDESC_CALL  569	/* Relax BLR.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570	/* TP-rel. LD/ST off. 11:4.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572	/* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573	/* Likewise; no check.  */
+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD64 1028	/* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL64 1029	/* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL64  1030	/* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
+#define R_AARCH64_IRELATIVE    1032	/* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_AARCH64_NUM          1033
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* PC relative 26 bit branch */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
+#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* 32 bit PLT address */
+#define R_ARM_CALL		28
+#define R_ARM_JUMP24		29
+#define R_ARM_THM_JUMP24	30
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_V4BX		40
+#define R_ARM_PREL31		42
+#define R_ARM_MOVW_ABS_NC	43
+#define R_ARM_MOVT_ABS		 44
+#define R_ARM_THM_MOVW_ABS_NC	47
+#define R_ARM_THM_MOVT_ABS	48
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
+#define R_ARM_THM_PC9		103	/* thumb conditional branch */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
+					   thread local data */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
+					   thread local data */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
+					   block */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
+					   static TLS block offset */
+#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
+					   TLS block */
+#define	R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_IRELATIVE		160
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* TMS320C67xx specific declarations */
+
+/* XXX: no ELF standard yet*/
+
+/* TMS320C67xx relocs. */
+#define R_C60_32       1
+#define R_C60_GOT32     3               /* 32 bit GOT entry */
+#define R_C60_PLT32     4               /* 32 bit PLT address */
+#define R_C60_COPY      5               /* Copy symbol at runtime */
+#define R_C60_GLOB_DAT  6               /* Create GOT entry */
+#define R_C60_JMP_SLOT  7               /* Create PLT entry */
+#define R_C60_RELATIVE  8               /* Adjust by program base */
+#define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
+#define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
+
+#define R_C60LO16      0x54       /* low 16 bit MVKL embedded */
+#define R_C60HI16      0x55       /* high 16 bit MVKH embedded */
+/* Keep this the last entry.  */
+#define R_C60_NUM      0x56
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* S/390 specific definitions.  */
+
+/* Valid values for the e_flags field.  */
+
+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
+
+/* Additional s390 relocs */
+
+#define R_390_NONE		0	/* No reloc.  */
+#define R_390_8			1	/* Direct 8 bit.  */
+#define R_390_12		2	/* Direct 12 bit.  */
+#define R_390_16		3	/* Direct 16 bit.  */
+#define R_390_32		4	/* Direct 32 bit.  */
+#define R_390_PC32		5	/* PC relative 32 bit.	*/
+#define R_390_GOT12		6	/* 12 bit GOT offset.  */
+#define R_390_GOT32		7	/* 32 bit GOT offset.  */
+#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
+#define R_390_COPY		9	/* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
+#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
+#define R_390_RELATIVE		12	/* Adjust by program base.  */
+#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
+#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16		15	/* 16 bit GOT offset.  */
+#define R_390_PC16		16	/* PC relative 16 bit.	*/
+#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64		22	/* Direct 64 bit.  */
+#define R_390_PC64		23	/* PC relative 64 bit.	*/
+#define R_390_GOT64		24	/* 64 bit GOT offset.  */
+#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
+#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
+#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
+#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
+#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
+#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
+#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
+#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
+#define R_390_TLS_GDCALL	38	/* Tag for function call in general
+					   dynamic TLS code. */
+#define R_390_TLS_LDCALL	39	/* Tag for function call in local
+					   dynamic TLS code. */
+#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
+					   thread local data.  */
+#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
+					  thread local data.  */
+#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
+					   block offset. */
+#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
+#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
+#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
+					   block.  */
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		62
+
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
 
 /* AMD x86-64 relocations.  */
@@ -1075,657 +2882,356 @@
 					   to GOT entry for IE symbol */
 #define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
-
-#define R_X86_64_NUM		24
-
-/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
-
-#define DT_SPARC_REGISTER 0x70000001
-#define DT_SPARC_NUM    2
-
-/* Bits present in AT_HWCAP, primarily for Sparc32.  */
-
-#define HWCAP_SPARC_FLUSH       1       /* The cpu supports flush insn.  */
-#define HWCAP_SPARC_STBAR       2
-#define HWCAP_SPARC_SWAP        4
-#define HWCAP_SPARC_MULDIV      8
-#define HWCAP_SPARC_V9          16      /* The cpu is v9, so v8plus is ok.  */
-
-/* MIPS R3000 specific definitions.  */
-
-/* Legal values for e_flags field of Elf32_Ehdr.  */
-
-#define EF_MIPS_NOREORDER   1           /* A .noreorder directive was used */
-#define EF_MIPS_PIC         2           /* Contains PIC code */
-#define EF_MIPS_CPIC        4           /* Uses PIC calling sequence */
-#define EF_MIPS_XGOT        8
-#define EF_MIPS_64BIT_WHIRL 16
-#define EF_MIPS_ABI2        32
-#define EF_MIPS_ABI_ON32    64
-#define EF_MIPS_ARCH        0xf0000000  /* MIPS architecture level */
-
-/* Legal values for MIPS architecture level.  */
-
-#define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
-#define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
-#define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
-#define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
-#define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
-
-/* The following are non-official names and should not be used.  */
-
-#define E_MIPS_ARCH_1     0x00000000    /* -mips1 code.  */
-#define E_MIPS_ARCH_2     0x10000000    /* -mips2 code.  */
-#define E_MIPS_ARCH_3     0x20000000    /* -mips3 code.  */
-#define E_MIPS_ARCH_4     0x30000000    /* -mips4 code.  */
-#define E_MIPS_ARCH_5     0x40000000    /* -mips5 code.  */
-
-/* Special section indices.  */
-
-#define SHN_MIPS_ACOMMON 0xff00         /* Allocated common symbols */
-#define SHN_MIPS_TEXT    0xff01         /* Allocated test symbols.  */
-#define SHN_MIPS_DATA    0xff02         /* Allocated data symbols.  */
-#define SHN_MIPS_SCOMMON 0xff03         /* Small common symbols */
-#define SHN_MIPS_SUNDEFINED 0xff04      /* Small undefined symbols */
-
-/* Legal values for sh_type field of Elf32_Shdr.  */
-
-#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
-#define SHT_MIPS_MSYM          0x70000001
-#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
-#define SHT_MIPS_GPTAB         0x70000003 /* Global data area sizes */
-#define SHT_MIPS_UCODE         0x70000004 /* Reserved for SGI/MIPS compilers */
-#define SHT_MIPS_DEBUG         0x70000005 /* MIPS ECOFF debugging information*/
-#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
-#define SHT_MIPS_PACKAGE       0x70000007
-#define SHT_MIPS_PACKSYM       0x70000008
-#define SHT_MIPS_RELD          0x70000009
-#define SHT_MIPS_IFACE         0x7000000b
-#define SHT_MIPS_CONTENT       0x7000000c
-#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
-#define SHT_MIPS_SHDR          0x70000010
-#define SHT_MIPS_FDESC         0x70000011
-#define SHT_MIPS_EXTSYM        0x70000012
-#define SHT_MIPS_DENSE         0x70000013
-#define SHT_MIPS_PDESC         0x70000014
-#define SHT_MIPS_LOCSYM        0x70000015
-#define SHT_MIPS_AUXSYM        0x70000016
-#define SHT_MIPS_OPTSYM        0x70000017
-#define SHT_MIPS_LOCSTR        0x70000018
-#define SHT_MIPS_LINE          0x70000019
-#define SHT_MIPS_RFDESC        0x7000001a
-#define SHT_MIPS_DELTASYM      0x7000001b
-#define SHT_MIPS_DELTAINST     0x7000001c
-#define SHT_MIPS_DELTACLASS    0x7000001d
-#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
-#define SHT_MIPS_DELTADECL     0x7000001f
-#define SHT_MIPS_SYMBOL_LIB    0x70000020
-#define SHT_MIPS_EVENTS        0x70000021 /* Event section.  */
-#define SHT_MIPS_TRANSLATE     0x70000022
-#define SHT_MIPS_PIXIE         0x70000023
-#define SHT_MIPS_XLATE         0x70000024
-#define SHT_MIPS_XLATE_DEBUG   0x70000025
-#define SHT_MIPS_WHIRL         0x70000026
-#define SHT_MIPS_EH_REGION     0x70000027
-#define SHT_MIPS_XLATE_OLD     0x70000028
-#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-
-/* Legal values for sh_flags field of Elf32_Shdr.  */
-
-#define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
-#define SHF_MIPS_MERGE   0x20000000
-#define SHF_MIPS_ADDR    0x40000000
-#define SHF_MIPS_STRINGS 0x80000000
-#define SHF_MIPS_NOSTRIP 0x08000000
-#define SHF_MIPS_LOCAL   0x04000000
-#define SHF_MIPS_NAMES   0x02000000
-#define SHF_MIPS_NODUPE  0x01000000
-
-
-/* Symbol tables.  */
-
-/* MIPS specific values for `st_other'.  */
-#define STO_MIPS_DEFAULT                0x0
-#define STO_MIPS_INTERNAL               0x1
-#define STO_MIPS_HIDDEN                 0x2
-#define STO_MIPS_PROTECTED              0x3
-#define STO_MIPS_SC_ALIGN_UNUSED        0xff
-
-/* MIPS specific values for `st_info'.  */
-#define STB_MIPS_SPLIT_COMMON           13
-
-/* Entries found in sections of type SHT_MIPS_GPTAB.  */
-
-typedef union
-{
-  struct
-    {
-      Elf32_Word gt_current_g_value;    /* -G value used for compilation */
-      Elf32_Word gt_unused;             /* Not used */
-    } gt_header;                        /* First entry in section */
-  struct
-    {
-      Elf32_Word gt_g_value;            /* If this value were used for -G */
-      Elf32_Word gt_bytes;              /* This many bytes would be used */
-    } gt_entry;                         /* Subsequent entries in section */
-} Elf32_gptab;
-
-/* Entry found in sections of type SHT_MIPS_REGINFO.  */
-
-typedef struct
-{
-  Elf32_Word    ri_gprmask;             /* General registers used */
-  Elf32_Word    ri_cprmask[4];          /* Coprocessor registers used */
-  Elf32_Sword   ri_gp_value;            /* $gp register value */
-} Elf32_RegInfo;
-
-/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
-
-typedef struct
-{
-  unsigned char kind;           /* Determines interpretation of the
-                                   variable part of descriptor.  */
-  unsigned char size;           /* Size of descriptor, including header.  */
-  Elf32_Section section;        /* Section header index of section affected,
-                                   0 for global options.  */
-  Elf32_Word info;              /* Kind-specific information.  */
-} Elf_Options;
-
-/* Values for `kind' field in Elf_Options.  */
-
-#define ODK_NULL        0       /* Undefined.  */
-#define ODK_REGINFO     1       /* Register usage information.  */
-#define ODK_EXCEPTIONS  2       /* Exception processing options.  */
-#define ODK_PAD         3       /* Section padding options.  */
-#define ODK_HWPATCH     4       /* Hardware workarounds performed */
-#define ODK_FILL        5       /* record the fill value used by the linker. */
-#define ODK_TAGS        6       /* reserve space for desktop tools to write. */
-#define ODK_HWAND       7       /* HW workarounds.  'AND' bits when merging. */
-#define ODK_HWOR        8       /* HW workarounds.  'OR' bits when merging.  */
-
-/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
-
-#define OEX_FPU_MIN     0x1f    /* FPE's which MUST be enabled.  */
-#define OEX_FPU_MAX     0x1f00  /* FPE's which MAY be enabled.  */
-#define OEX_PAGE0       0x10000 /* page zero must be mapped.  */
-#define OEX_SMM         0x20000 /* Force sequential memory mode?  */
-#define OEX_FPDBUG      0x40000 /* Force floating point debug mode?  */
-#define OEX_PRECISEFP   OEX_FPDBUG
-#define OEX_DISMISS     0x80000 /* Dismiss invalid address faults?  */
-
-#define OEX_FPU_INVAL   0x10
-#define OEX_FPU_DIV0    0x08
-#define OEX_FPU_OFLO    0x04
-#define OEX_FPU_UFLO    0x02
-#define OEX_FPU_INEX    0x01
-
-/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
-
-#define OHW_R4KEOP      0x1     /* R4000 end-of-page patch.  */
-#define OHW_R8KPFETCH   0x2     /* may need R8000 prefetch patch.  */
-#define OHW_R5KEOP      0x4     /* R5000 end-of-page patch.  */
-#define OHW_R5KCVTL     0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
-
-#define OPAD_PREFIX     0x1
-#define OPAD_POSTFIX    0x2
-#define OPAD_SYMBOL     0x4
-
-/* Entry found in `.options' section.  */
-
-typedef struct
-{
-  Elf32_Word hwp_flags1;        /* Extra flags.  */
-  Elf32_Word hwp_flags2;        /* Extra flags.  */
-} Elf_Options_Hw;
-
-/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
-
-#define OHWA0_R4KEOP_CHECKED    0x00000001
-#define OHWA1_R4KEOP_CLEAN      0x00000002
-
-/* MIPS relocs.  */
-
-#define R_MIPS_NONE             0       /* No reloc */
-#define R_MIPS_16               1       /* Direct 16 bit */
-#define R_MIPS_32               2       /* Direct 32 bit */
-#define R_MIPS_REL32            3       /* PC relative 32 bit */
-#define R_MIPS_26               4       /* Direct 26 bit shifted */
-#define R_MIPS_HI16             5       /* High 16 bit */
-#define R_MIPS_LO16             6       /* Low 16 bit */
-#define R_MIPS_GPREL16          7       /* GP relative 16 bit */
-#define R_MIPS_LITERAL          8       /* 16 bit literal entry */
-#define R_MIPS_GOT16            9       /* 16 bit GOT entry */
-#define R_MIPS_PC16             10      /* PC relative 16 bit */
-#define R_MIPS_CALL16           11      /* 16 bit GOT entry for function */
-#define R_MIPS_GPREL32          12      /* GP relative 32 bit */
-
-#define R_MIPS_SHIFT5           16
-#define R_MIPS_SHIFT6           17
-#define R_MIPS_64               18
-#define R_MIPS_GOT_DISP         19
-#define R_MIPS_GOT_PAGE         20
-#define R_MIPS_GOT_OFST         21
-#define R_MIPS_GOT_HI16         22
-#define R_MIPS_GOT_LO16         23
-#define R_MIPS_SUB              24
-#define R_MIPS_INSERT_A         25
-#define R_MIPS_INSERT_B         26
-#define R_MIPS_DELETE           27
-#define R_MIPS_HIGHER           28
-#define R_MIPS_HIGHEST          29
-#define R_MIPS_CALL_HI16        30
-#define R_MIPS_CALL_LO16        31
-#define R_MIPS_SCN_DISP         32
-#define R_MIPS_REL16            33
-#define R_MIPS_ADD_IMMEDIATE    34
-#define R_MIPS_PJUMP            35
-#define R_MIPS_RELGOT           36
-#define R_MIPS_JALR             37
-/* Keep this the last entry.  */
-#define R_MIPS_NUM              38
-
-/* Legal values for p_type field of Elf32_Phdr.  */
-
-#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
-#define PT_MIPS_RTPROC  0x70000001      /* Runtime procedure table. */
-#define PT_MIPS_OPTIONS 0x70000002
-
-/* Special program header types.  */
-
-#define PF_MIPS_LOCAL   0x10000000
-
-/* Legal values for d_tag field of Elf32_Dyn.  */
-
-#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime linker interface version */
-#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
-#define DT_MIPS_ICHECKSUM    0x70000003 /* Checksum */
-#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
-#define DT_MIPS_FLAGS        0x70000005 /* Flags */
-#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
-#define DT_MIPS_MSYM         0x70000007
-#define DT_MIPS_CONFLICT     0x70000008 /* Address of CONFLICT section */
-#define DT_MIPS_LIBLIST      0x70000009 /* Address of LIBLIST section */
-#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local GOT entries */
-#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of CONFLICT entries */
-#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of LIBLIST entries */
-#define DT_MIPS_SYMTABNO     0x70000011 /* Number of DYNSYM entries */
-#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
-#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in DYNSYM */
-#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
-#define DT_MIPS_RLD_MAP      0x70000016 /* Address of run time loader map.  */
-#define DT_MIPS_DELTA_CLASS  0x70000017 /* Delta C++ class definition.  */
-#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
-                                                DT_MIPS_DELTA_CLASS.  */
-#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
-#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
-                                                DT_MIPS_DELTA_INSTANCE.  */
-#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
-#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
-                                             DT_MIPS_DELTA_RELOC.  */
-#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
-                                           relocations refer to.  */
-#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
-                                           DT_MIPS_DELTA_SYM.  */
-#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
-                                             class declaration.  */
-#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
-                                                DT_MIPS_DELTA_CLASSSYM.  */
-#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
-#define DT_MIPS_PIXIE_INIT   0x70000023
-#define DT_MIPS_SYMBOL_LIB   0x70000024
-#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
-#define DT_MIPS_LOCAL_GOTIDX 0x70000026
-#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
-#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
-#define DT_MIPS_OPTIONS      0x70000029 /* Address of .options.  */
-#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
-#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
-#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
-#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
-                                                    function stored in GOT.  */
-#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
-                                           by rld on dlopen() calls.  */
-#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
-#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
-#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
-#define DT_MIPS_NUM          0x32
-
-/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
-
-#define RHF_NONE                   0            /* No flags */
-#define RHF_QUICKSTART             (1 << 0)     /* Use quickstart */
-#define RHF_NOTPOT                 (1 << 1)     /* Hash size not power of 2 */
-#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)     /* Ignore LD_LIBRARY_PATH */
-#define RHF_NO_MOVE                (1 << 3)
-#define RHF_SGI_ONLY               (1 << 4)
-#define RHF_GUARANTEE_INIT         (1 << 5)
-#define RHF_DELTA_C_PLUS_PLUS      (1 << 6)
-#define RHF_GUARANTEE_START_INIT   (1 << 7)
-#define RHF_PIXIE                  (1 << 8)
-#define RHF_DEFAULT_DELAY_LOAD     (1 << 9)
-#define RHF_REQUICKSTART           (1 << 10)
-#define RHF_REQUICKSTARTED         (1 << 11)
-#define RHF_CORD                   (1 << 12)
-#define RHF_NO_UNRES_UNDEF         (1 << 13)
-#define RHF_RLD_ORDER_SAFE         (1 << 14)
-
-/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
-
-typedef struct
-{
-  Elf32_Word l_name;            /* Name (string table index) */
-  Elf32_Word l_time_stamp;      /* Timestamp */
-  Elf32_Word l_checksum;        /* Checksum */
-  Elf32_Word l_version;         /* Interface version */
-  Elf32_Word l_flags;           /* Flags */
-} Elf32_Lib;
-
-typedef struct
-{
-  Elf64_Word l_name;            /* Name (string table index) */
-  Elf64_Word l_time_stamp;      /* Timestamp */
-  Elf64_Word l_checksum;        /* Checksum */
-  Elf64_Word l_version;         /* Interface version */
-  Elf64_Word l_flags;           /* Flags */
-} Elf64_Lib;
-
-
-/* Legal values for l_flags.  */
-
-#define LL_NONE           0
-#define LL_EXACT_MATCH    (1 << 0)      /* Require exact match */
-#define LL_IGNORE_INT_VER (1 << 1)      /* Ignore interface version */
-#define LL_REQUIRE_MINOR  (1 << 2)
-#define LL_EXPORTS        (1 << 3)
-#define LL_DELAY_LOAD     (1 << 4)
-#define LL_DELTA          (1 << 5)
-
-/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
-
-typedef Elf32_Addr Elf32_Conflict;
-
-
-/* HPPA specific definitions.  */
-
-/* Legal values for e_flags field of Elf32_Ehdr.  */
-
-#define EF_PARISC_TRAPNL        1       /* Trap nil pointer dereference.  */
-#define EF_PARISC_EXT           2       /* Program uses arch. extensions.  */
-#define EF_PARISC_ARCH          0xffff0000 /* Architecture version.  */
-/* Defined values are:
-                                0x020b  PA-RISC 1.0 big-endian
-                                0x0210  PA-RISC 1.1 big-endian
-                                0x028b  PA-RISC 1.0 little-endian
-                                0x0290  PA-RISC 1.1 little-endian
-*/
-
-/* Legal values for sh_type field of Elf32_Shdr.  */
-
-#define SHT_PARISC_GOT          0x70000000 /* GOT for external data.  */
-#define SHT_PARISC_ARCH         0x70000001 /* Architecture extensions.  */
-#define SHT_PARISC_GLOBAL       0x70000002 /* Definition of $global$.  */
-#define SHT_PARISC_MILLI        0x70000003 /* Millicode routines.  */
-#define SHT_PARISC_UNWIND       0x70000004 /* Unwind information.  */
-#define SHT_PARISC_PLT          0x70000005 /* Procedure linkage table.  */
-#define SHT_PARISC_SDATA        0x70000006 /* Short initialized data.  */
-#define SHT_PARISC_SBSS         0x70000007 /* Short uninitialized data.  */
-#define SHT_PARISC_SYMEXTN      0x70000008 /* Argument/relocation info.  */
-#define SHT_PARISC_STUBS        0x70000009 /* Linker stubs.  */
-
-/* Legal values for sh_flags field of Elf32_Shdr.  */
-
-#define SHF_PARISC_GLOBAL       0x10000000 /* Section defines dp.  */
-#define SHF_PARISC_SHORT        0x20000000 /* Section with short addressing. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
-
-#define STT_PARISC_MILLICODE    13      /* Millicode function entry point.  */
-
-/* HPPA relocs.  */
-
-#define R_PARISC_NONE           0       /* No reloc.  */
-#define R_PARISC_DIR32          1       /* Direct 32-bit reference.  */
-#define R_PARISC_DIR21L         2       /* Left 21 bits of eff. address.  */
-#define R_PARISC_DIR17R         3       /* Right 17 bits of eff. address.  */
-#define R_PARISC_DIR14R         4       /* Right 14 bits of eff. address.  */
-#define R_PARISC_PCREL21L       5       /* PC-relative, left 21 bits.  */
-#define R_PARISC_PCREL14R       6       /* PC-relative, right 14 bits.  */
-#define R_PARISC_PCREL17C       7       /* Conditional PC-relative, ignore
-                                           if displacement > 17bits.  */
-#define R_PARISC_PCREL17F       8       /* Conditional PC-relative, must
-                                           fit in 17bits.  */
-#define R_PARISC_DPREL21L       9       /* DP-relative, left 21 bits.  */
-#define R_PARISC_DPREL14R       10      /* DP-relative, right 14 bits.  */
-#define R_PARISC_DPREL14F       11      /* DP-relative, must bit in 14 bits. */
-#define R_PARISC_DLTREL21L      12      /* DLT-relative, left 21 bits.  */
-#define R_PARISC_DLTREL14R      13      /* DLT-relative, right 14 bits.  */
-#define R_PARISC_DLTREL14F      14      /* DLT-relative, must fit in 14 bits.*/
-#define R_PARISC_DLTIND21L      15      /* DLT-relative indirect, left
-                                           21 bits.  */
-#define R_PARISC_DLTIND14R      16      /* DLT-relative indirect, right
-                                           14 bits.  */
-#define R_PARISC_DLTIND14F      17      /* DLT-relative indirect, must fit
-                                           int 14 bits.  */
-#define R_PARISC_PLABEL32       18      /* Direct 32-bit reference to proc.  */
-
-/* Alpha specific definitions.  */
-
-/* Legal values for e_flags field of Elf64_Ehdr.  */
-
-#define EF_ALPHA_32BIT          1       /* All addresses must be < 2GB.  */
-#define EF_ALPHA_CANRELAX       2       /* Relocations for relaxing exist.  */
-
-/* Legal values for sh_type field of Elf64_Shdr.  */
-
-/* These two are primerily concerned with ECOFF debugging info.  */
-#define SHT_ALPHA_DEBUG         0x70000001
-#define SHT_ALPHA_REGINFO       0x70000002
-
-/* Legal values for sh_flags field of Elf64_Shdr.  */
-
-#define SHF_ALPHA_GPREL         0x10000000
-
-/* Legal values for st_other field of Elf64_Sym.  */
-#define STO_ALPHA_NOPV          0x80    /* No PV required.  */
-#define STO_ALPHA_STD_GPLOAD    0x88    /* PV only used for initial ldgp.  */
-
-/* Alpha relocs.  */
-
-#define R_ALPHA_NONE            0       /* No reloc */
-#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
-#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
-#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
-#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
-#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
-#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
-#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
-#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
-#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
-#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
-#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
-#define R_ALPHA_OP_PUSH         12      /* OP stack push */
-#define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
-#define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
-#define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
-#define R_ALPHA_GPVALUE         16
-#define R_ALPHA_GPRELHIGH       17
-#define R_ALPHA_GPRELLOW        18
-#define R_ALPHA_IMMED_GP_16     19
-#define R_ALPHA_IMMED_GP_HI32   20
-#define R_ALPHA_IMMED_SCN_HI32  21
-#define R_ALPHA_IMMED_BR_HI32   22
-#define R_ALPHA_IMMED_LO32      23
-#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
-#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
-#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
-#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
-/* Keep this the last entry.  */
-#define R_ALPHA_NUM             28
-
-
-/* PowerPC specific declarations */
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE              0
-#define R_PPC_ADDR32            1       /* 32bit absolute address */
-#define R_PPC_ADDR24            2       /* 26bit address, 2 bits ignored.  */
-#define R_PPC_ADDR16            3       /* 16bit absolute address */
-#define R_PPC_ADDR16_LO         4       /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI         5       /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA         6       /* adjusted high 16bit */
-#define R_PPC_ADDR14            7       /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN    8
-#define R_PPC_ADDR14_BRNTAKEN   9
-#define R_PPC_REL24             10      /* PC relative 26 bit */
-#define R_PPC_REL14             11      /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN     12
-#define R_PPC_REL14_BRNTAKEN    13
-#define R_PPC_GOT16             14
-#define R_PPC_GOT16_LO          15
-#define R_PPC_GOT16_HI          16
-#define R_PPC_GOT16_HA          17
-#define R_PPC_PLTREL24          18
-#define R_PPC_COPY              19
-#define R_PPC_GLOB_DAT          20
-#define R_PPC_JMP_SLOT          21
-#define R_PPC_RELATIVE          22
-#define R_PPC_LOCAL24PC         23
-#define R_PPC_UADDR32           24
-#define R_PPC_UADDR16           25
-#define R_PPC_REL32             26
-#define R_PPC_PLT32             27
-#define R_PPC_PLTREL32          28
-#define R_PPC_PLT16_LO          29
-#define R_PPC_PLT16_HI          30
-#define R_PPC_PLT16_HA          31
-#define R_PPC_SDAREL16          32
-#define R_PPC_SECTOFF           33
-#define R_PPC_SECTOFF_LO        34
-#define R_PPC_SECTOFF_HI        35
-#define R_PPC_SECTOFF_HA        36
-/* Keep this the last entry.  */
-#define R_PPC_NUM               37
-
-/* The remaining relocs are from the Embedded ELF ABI, and are not
-   in the SVR4 ELF ABI.  */
-#define R_PPC_EMB_NADDR32       101
-#define R_PPC_EMB_NADDR16       102
-#define R_PPC_EMB_NADDR16_LO    103
-#define R_PPC_EMB_NADDR16_HI    104
-#define R_PPC_EMB_NADDR16_HA    105
-#define R_PPC_EMB_SDAI16        106
-#define R_PPC_EMB_SDA2I16       107
-#define R_PPC_EMB_SDA2REL       108
-#define R_PPC_EMB_SDA21         109     /* 16 bit offset in SDA */
-#define R_PPC_EMB_MRKREF        110
-#define R_PPC_EMB_RELSEC16      111
-#define R_PPC_EMB_RELST_LO      112
-#define R_PPC_EMB_RELST_HI      113
-#define R_PPC_EMB_RELST_HA      114
-#define R_PPC_EMB_BIT_FLD       115
-#define R_PPC_EMB_RELSDA        116     /* 16 bit relative offset in SDA */
-
-/* Diab tool relocations.  */
-#define R_PPC_DIAB_SDA21_LO     180     /* like EMB_SDA21, but lower 16 bit */
-#define R_PPC_DIAB_SDA21_HI     181     /* like EMB_SDA21, but high 16 bit */
-#define R_PPC_DIAB_SDA21_HA     182     /* like EMB_SDA21, adjusted high 16 */
-#define R_PPC_DIAB_RELSDA_LO    183     /* like EMB_RELSDA, but lower 16 bit */
-#define R_PPC_DIAB_RELSDA_HI    184     /* like EMB_RELSDA, but high 16 bit */
-#define R_PPC_DIAB_RELSDA_HA    185     /* like EMB_RELSDA, adjusted high 16 */
-
-/* This is a phony reloc to handle any old fashioned TOC16 references
-   that may still be in object files.  */
-#define R_PPC_TOC16             255
-
-
-/* ARM specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field.  */
-#define EF_ARM_RELEXEC     0x01
-#define EF_ARM_HASENTRY    0x02
-#define EF_ARM_INTERWORK   0x04
-#define EF_ARM_APCS_26     0x08
-#define EF_ARM_APCS_FLOAT  0x10
-#define EF_ARM_PIC         0x20
-#define EF_ALIGN8          0x40         /* 8-bit structure alignment is in use */
-#define EF_NEW_ABI         0x80
-#define EF_OLD_ABI         0x100
-
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC      0xd
-
-/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
-#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
-                                           in the input to a link step */
-
-/* ARM-specific program header flags */
-#define PF_ARM_SB          0x10000000   /* Segment contains the location
-                                           addressed by the static base */
-
-/* ARM relocs.  */
-#define R_ARM_NONE              0       /* No reloc */
-#define R_ARM_PC24              1       /* PC relative 26 bit branch */
-#define R_ARM_ABS32             2       /* Direct 32 bit  */
-#define R_ARM_REL32             3       /* PC relative 32 bit */
-#define R_ARM_PC13              4
-#define R_ARM_ABS16             5       /* Direct 16 bit */
-#define R_ARM_ABS12             6       /* Direct 12 bit */
-#define R_ARM_THM_ABS5          7
-#define R_ARM_ABS8              8       /* Direct 8 bit */
-#define R_ARM_SBREL32           9
-#define R_ARM_THM_CALL          10
-#define R_ARM_THM_PC8           11
-#define R_ARM_AMP_VCALL9        12
-#define R_ARM_SWI24             13
-#define R_ARM_THM_SWI8          14
-#define R_ARM_XPC25             15
-#define R_ARM_THM_XPC22         16
-#define R_ARM_COPY              20      /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT          21      /* Create GOT entry */
-#define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
-#define R_ARM_RELATIVE          23      /* Adjust by program base */
-#define R_ARM_GOTOFF32          24      /* 32 bit offset to GOT */
-#define R_ARM_BASE_PREL         25      /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT_BREL          26      /* 32 bit GOT entry */
-#define R_ARM_PLT32             27      /* 32 bit PLT address */
-#define R_ARM_CALL              28
-#define R_ARM_JUMP24            29
-#define R_ARM_THM_JUMP24        30
-#define R_ARM_V4BX              40
-#define R_ARM_PREL31            42
-#define R_ARM_MOVW_ABS_NC       43
-#define R_ARM_MOVT_ABS          44
-#define R_ARM_THM_MOVW_ABS_NC   47
-#define R_ARM_THM_MOVT_ABS      48
-#define R_ARM_GNU_VTENTRY       100
-#define R_ARM_GNU_VTINHERIT     101
-#define R_ARM_THM_PC11          102     /* thumb unconditional branch */
-#define R_ARM_THM_PC9           103     /* thumb conditional branch */
-#define R_ARM_RXPC25            249
-#define R_ARM_RSBREL32          250
-#define R_ARM_THM_RPC22         251
-#define R_ARM_RREL32            252
-#define R_ARM_RABS22            253
-#define R_ARM_RPC24             254
-#define R_ARM_RBASE             255
-/* Keep this the last entry.  */
-#define R_ARM_NUM               256
-
-/* TMS320C67xx specific declarations */
-/* XXX: no ELF standard yet */
-
-/* TMS320C67xx relocs. */
-#define R_C60_32       1
-#define R_C60_GOT32     3               /* 32 bit GOT entry */
-#define R_C60_PLT32     4               /* 32 bit PLT address */
-#define R_C60_COPY      5               /* Copy symbol at runtime */
-#define R_C60_GLOB_DAT  6               /* Create GOT entry */
-#define R_C60_JMP_SLOT  7               /* Create PLT entry */
-#define R_C60_RELATIVE  8               /* Adjust by program base */
-#define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
-#define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
-
-#define R_C60HI16      0x55       // high 16 bit MVKH embedded
-#define R_C60LO16      0x54       // low 16 bit MVKL embedded
-
-#endif  /* elf.h */
+#define R_X86_64_PC64		24	/* PC relative 64 bit */
+#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
+					   offset to GOT */
+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
+					   to GOT entry */
+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
+					   to PLT entry */
+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
+					   descriptor.  */
+#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
+#define R_X86_64_GOTPCRELX	41	/* like GOTPCREL, but optionally with
+					   linker optimizations */
+#define R_X86_64_REX_GOTPCRELX	42      /* like GOTPCRELX, but a REX prefix
+					   is present */
+
+#define R_X86_64_NUM		43
+
+
+/* AM33 relocations.  */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
+#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
+#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
+#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
+#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
+#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
+#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
+#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
+#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
+#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
+#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+#define R_MN10300_TLS_GD	24	/* 32-bit offset for global dynamic.  */
+#define R_MN10300_TLS_LD	25	/* 32-bit offset for local dynamic.  */
+#define R_MN10300_TLS_LDO	26	/* Module-relative offset.  */
+#define R_MN10300_TLS_GOTIE	27	/* GOT offset for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_IE	28	/* GOT address for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_LE	29	/* Offset relative to static TLS
+					   block.  */
+#define R_MN10300_TLS_DTPMOD	30	/* ID of module containing symbol.  */
+#define R_MN10300_TLS_DTPOFF	31	/* Offset in module TLS block.  */
+#define R_MN10300_TLS_TPOFF	32	/* Offset in static TLS block.  */
+#define R_MN10300_SYM_DIFF	33	/* Adjustment for next reloc as needed
+					   by linker relaxation.  */
+#define R_MN10300_ALIGN		34	/* Alignment requirement for linker
+					   relaxation.  */
+#define R_MN10300_NUM		35
+
+
+/* M32R relocs.  */
+#define R_M32R_NONE		0	/* No reloc. */
+#define R_M32R_16		1	/* Direct 16 bit. */
+#define R_M32R_32		2	/* Direct 32 bit. */
+#define R_M32R_24		3	/* Direct 24 bit. */
+#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
+#define R_M32R_LO16		9	/* Low 16 bit. */
+#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+/* M32R relocs use SHT_RELA.  */
+#define R_M32R_16_RELA		33	/* Direct 16 bit. */
+#define R_M32R_32_RELA		34	/* Direct 32 bit. */
+#define R_M32R_24_RELA		35	/* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
+#define R_M32R_LO16_RELA	41	/* Low 16 bit */
+#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45	/* PC relative 32 bit.  */
+
+#define R_M32R_GOT24		48	/* 24 bit GOT entry */
+#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY		50	/* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
+#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
+#define R_M32R_RELATIVE		53	/* Adjust by program base */
+#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
+#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
+					   low */
+#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
+					   low */
+#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
+					   GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
+					   GOT with signed low */
+#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
+					   GOT */
+#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
+					   with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
+					   with signed low */
+#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
+#define R_M32R_NUM		256	/* Keep this the last entry. */
+
+
+/* TILEPro relocations.  */
+#define R_TILEPRO_NONE		0	/* No reloc */
+#define R_TILEPRO_32		1	/* Direct 32 bit */
+#define R_TILEPRO_16		2	/* Direct 16 bit */
+#define R_TILEPRO_8		3	/* Direct 8 bit */
+#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
+#define R_TILEPRO_LO16		7	/* Low 16 bit */
+#define R_TILEPRO_HI16		8	/* High 16 bit */
+#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
+#define R_TILEPRO_COPY		10	/* Copy relocation */
+#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
+#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
+#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined.  */
+#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM		130
+
+
+/* TILE-Gx relocations.  */
+#define R_TILEGX_NONE		0	/* No reloc */
+#define R_TILEGX_64		1	/* Direct 64 bit */
+#define R_TILEGX_32		2	/* Direct 32 bit */
+#define R_TILEGX_16		3	/* Direct 16 bit */
+#define R_TILEGX_8		4	/* Direct 8 bit */
+#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
+#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
+#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
+#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
+#define R_TILEGX_HW0		9	/* hword 0 16-bit */
+#define R_TILEGX_HW1		10	/* hword 1 16-bit */
+#define R_TILEGX_HW2		11	/* hword 2 16-bit */
+#define R_TILEGX_HW3		12	/* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
+#define R_TILEGX_COPY		16	/* Copy relocation */
+#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
+#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
+#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
+#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined.  */
+#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM		130
+
+
+#endif	/* elf.h */
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/examples/ex3.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c	(revision 331)
@@ -1,4 +1,3 @@
-#include <stdlib.h>
-#include <stdio.h>
+#include <tcclib.h>
 
 int fib(n)
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/i386-asm.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c	(revision 331)
@@ -22,30 +22,34 @@
 #include "tcc.h"
 
-// #define NB_ASM_REGS 8
 #define MAX_OPERANDS 3
-#define NB_SAVED_REGS 3
 
 #define TOK_ASM_first TOK_ASM_clc
 #define TOK_ASM_last TOK_ASM_emms
-
-#define OPC_JMP        0x01  /* jmp operand */
-#define OPC_B          0x02  /* only used with OPC_WL */
-#define OPC_WL         0x04  /* accepts w, l or no suffix */
+#define TOK_ASM_alllast TOK_ASM_subps
+
+#define OPC_B          0x01  /* only used with OPC_WL */
+#define OPC_WL         0x02  /* accepts w, l or no suffix */
 #define OPC_BWL        (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
-#define OPC_REG        0x08 /* register is added to opcode */
-#define OPC_MODRM      0x10 /* modrm encoding */
-#define OPC_FWAIT      0x20 /* add fwait opcode */
-#define OPC_TEST       0x40 /* test opcodes */
-#define OPC_SHIFT      0x80 /* shift opcodes */
-#define OPC_D16      0x0100 /* generate data16 prefix */
-#define OPC_ARITH    0x0200 /* arithmetic opcodes */
-#define OPC_SHORTJMP 0x0400 /* short jmp operand */
-#define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
+#define OPC_REG        0x04 /* register is added to opcode */
+#define OPC_MODRM      0x08 /* modrm encoding */
+
+#define OPCT_MASK      0x70
+#define OPC_FWAIT      0x10 /* add fwait opcode */
+#define OPC_SHIFT      0x20 /* shift opcodes */
+#define OPC_ARITH      0x30 /* arithmetic opcodes */
+#define OPC_FARITH     0x40 /* FPU arithmetic opcodes */
+#define OPC_TEST       0x50 /* test opcodes */
+#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
+
+#define OPC_0F        0x100 /* Is secondary map (0x0f prefix) */
+#define OPC_48        0x200 /* Always has REX prefix */
 #ifdef TCC_TARGET_X86_64
 # define OPC_WLQ     0x1000  /* accepts w, l, q or no suffix */
 # define OPC_BWLQ    (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
 # define OPC_WLX     OPC_WLQ
+# define OPC_BWLX    OPC_BWLQ
 #else
 # define OPC_WLX     OPC_WL
+# define OPC_BWLX    OPC_BWL
 #endif
 
@@ -68,4 +72,8 @@
     OPT_SEG,
     OPT_ST,
+#ifdef TCC_TARGET_X86_64
+    OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but
+		     with REX prefix, not used in insn templates */
+#endif
     OPT_IM8,
     OPT_IM8S,
@@ -83,11 +91,11 @@
     /* composite types */
     OPT_COMPOSITE_FIRST,
-    OPT_IM,     /* IM8 | IM16 | IM32 | IM64 */
+    OPT_IM,     /* IM8 | IM16 | IM32 */
     OPT_REG,    /* REG8 | REG16 | REG32 | REG64 */
     OPT_REGW,   /* REG16 | REG32 | REG64 */
-    OPT_IMW,    /* IM16 | IM32 | IM64 */
-#ifdef TCC_TARGET_X86_64
-    OPT_IMNO64, /* IM16 | IM32 */
-#endif
+    OPT_IMW,    /* IM16 | IM32 */
+    OPT_MMXSSE, /* MMX | SSE */
+    OPT_DISP,   /* Like OPT_ADDR, but emitted as displacement (for jumps) */
+    OPT_DISP8,  /* Like OPT_ADDR, but only 8bit (short jumps) */
     /* can be ored with any OPT_xxx */
     OPT_EA = 0x80
@@ -115,9 +123,13 @@
 #define OP_INDIR  (1 << OPT_INDIR)
 #ifdef TCC_TARGET_X86_64
-# define OP_REG64  (1 << OPT_REG64)
-# define OP_IM64   (1 << OPT_IM64)
+# define OP_REG64 (1 << OPT_REG64)
+# define OP_REG8_LOW (1 << OPT_REG8_LOW)
+# define OP_IM64  (1 << OPT_IM64)
+# define OP_EA32  (OP_EA << 1)
 #else
 # define OP_REG64 0
+# define OP_REG8_LOW 0
 # define OP_IM64  0
+# define OP_EA32  0
 #endif
 
@@ -126,10 +138,8 @@
 
 #ifdef TCC_TARGET_X86_64
-# define OP_IM      OP_IM64
 # define TREG_XAX   TREG_RAX
 # define TREG_XCX   TREG_RCX
 # define TREG_XDX   TREG_RDX
 #else
-# define OP_IM      OP_IM32
 # define TREG_XAX   TREG_EAX
 # define TREG_XCX   TREG_ECX
@@ -211,9 +221,13 @@
 static const ASMInstr asm_instrs[] = {
 #define ALT(x) x
+/* This removes a 0x0f in the second byte */
+#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
+/* This constructs instr_type from opcode, type and group.  */
+#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
 #define DEF_ASM_OP0(name, opcode)
-#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
-#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
-#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
-#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } },
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }},
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
 #ifdef TCC_TARGET_X86_64
 # include "x86_64-asm.h"
@@ -242,8 +256,4 @@
 {
     int shift, v;
-#ifdef I386_ASM_16
-    if (s1->seg_size == 16)
-        tcc_error("invalid effective address");
-#endif
     v = asm_int_expr(s1);
     switch(v) {
@@ -268,7 +278,48 @@
 }
 
-static int asm_parse_reg(void)
+#ifdef TCC_TARGET_X86_64
+static int asm_parse_numeric_reg(int t, unsigned int *type)
+{
+    int reg = -1;
+    if (t >= TOK_IDENT && t < tok_ident) {
+	const char *s = table_ident[t - TOK_IDENT]->str;
+	char c;
+	*type = OP_REG64;
+	if (*s == 'c') {
+	    s++;
+	    *type = OP_CR;
+	}
+	if (*s++ != 'r')
+	  return -1;
+	/* Don't allow leading '0'.  */
+	if ((c = *s++) >= '1' && c <= '9')
+	  reg = c - '0';
+	else
+	  return -1;
+	if ((c = *s) >= '0' && c <= '5')
+	  s++, reg = reg * 10 + c - '0';
+	if (reg > 15)
+	  return -1;
+	if ((c = *s) == 0)
+	  ;
+	else if (*type != OP_REG64)
+	  return -1;
+	else if (c == 'b' && !s[1])
+	  *type = OP_REG8;
+	else if (c == 'w' && !s[1])
+	  *type = OP_REG16;
+	else if (c == 'd' && !s[1])
+	  *type = OP_REG32;
+	else
+	  return -1;
+    }
+    return reg;
+}
+#endif
+
+static int asm_parse_reg(unsigned int *type)
 {
     int reg = 0;
+    *type = 0;
     if (tok != '%')
         goto error_32;
@@ -276,11 +327,15 @@
     if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
         reg = tok - TOK_ASM_eax;
+	*type = OP_REG32;
 #ifdef TCC_TARGET_X86_64
     } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
         reg = tok - TOK_ASM_rax;
-#endif
-#ifdef I386_ASM_16
-    } else if (tok >= TOK_ASM_ax && tok <= TOK_ASM_di) {
-        reg = tok - TOK_ASM_ax;
+	*type = OP_REG64;
+    } else if (tok == TOK_ASM_rip) {
+        reg = -2; /* Probably should use different escape code. */
+	*type = OP_REG64;
+    } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
+	       && (*type == OP_REG32 || *type == OP_REG64)) {
+	;
 #endif
     } else {
@@ -330,5 +385,5 @@
                 if (tok != TOK_PPNUM)
                     goto reg_error;
-                p = tokc.cstr->data;
+                p = tokc.str.data;
                 reg = p[0] - '0';
                 if ((unsigned)reg >= 8 || p[1] != '\0')
@@ -341,7 +396,14 @@
                 op->type |= OP_ST0;
             goto no_skip;
+#ifdef TCC_TARGET_X86_64
+	} else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
+	    op->type = OP_REG8 | OP_REG8_LOW;
+	    op->reg = 4 + tok - TOK_ASM_spl;
+        } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
+	    ;
+#endif
         } else {
         reg_error:
-            tcc_error("unknown register");
+            tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
         }
         next();
@@ -351,7 +413,6 @@
         next();
         asm_expr(s1, &e);
-        op->type = OP_IM;
-        op->e.v = e.v;
-        op->e.sym = e.sym;
+        op->type = OP_IM32;
+        op->e = e;
         if (!op->e.sym) {
             if (op->e.v == (uint8_t)op->e.v)
@@ -362,6 +423,6 @@
                 op->type |= OP_IM16;
 #ifdef TCC_TARGET_X86_64
-            if (op->e.v == (uint32_t)op->e.v)
-                op->type |= OP_IM32;
+            if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v)
+                op->type = OP_IM64;
 #endif
         }
@@ -374,6 +435,5 @@
         if (tok != '(') {
             asm_expr(s1, &e);
-            op->e.v = e.v;
-            op->e.sym = e.sym;
+            op->e = e;
         } else {
             next();
@@ -391,14 +451,16 @@
                 op->e.sym = e.sym;
             }
+	    op->e.pcrel = 0;
         }
         if (tok == '(') {
+	    unsigned int type = 0;
             next();
             if (tok != ',') {
-                op->reg = asm_parse_reg();
+                op->reg = asm_parse_reg(&type);
             }
             if (tok == ',') {
                 next();
                 if (tok != ',') {
-                    op->reg2 = asm_parse_reg();
+                    op->reg2 = asm_parse_reg(&type);
                 }
                 if (tok == ',') {
@@ -407,4 +469,6 @@
                 }
             }
+	    if (type & OP_REG32)
+	        op->type |= OP_EA32;
             skip(')');
         }
@@ -418,9 +482,14 @@
 ST_FUNC void gen_expr32(ExprValue *pe)
 {
-    gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+    if (pe->pcrel)
+        /* If PC-relative, always set VT_SYM, even without symbol,
+	   so as to force a relocation to be emitted.  */
+	gen_addrpc32(VT_SYM, pe->sym, pe->v);
+    else
+	gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
 }
 
 #ifdef TCC_TARGET_X86_64
-static void gen_expr64(ExprValue *pe)
+ST_FUNC void gen_expr64(ExprValue *pe)
 {
     gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
@@ -432,10 +501,11 @@
 {
     Sym *sym = pe->sym;
-    if (sym && sym->r == cur_text_section->sh_num) {
+    ElfSym *esym = elfsym(sym);
+    if (esym && esym->st_shndx == cur_text_section->sh_num) {
         /* same section: we can output an absolute value. Note
            that the TCC compiler behaves differently here because
            it always outputs a relocation to ease (future) code
            elimination in the linker */
-        gen_le32(pe->v + sym->jnext - ind - 4);
+        gen_le32(pe->v + esym->st_value - ind - 4);
     } else {
         if (sym && sym->type.t == VT_VOID) {
@@ -447,37 +517,6 @@
 }
 
-#ifdef I386_ASM_16
-static void gen_expr16(ExprValue *pe)
-{
-    if (pe->sym)
-        greloc(cur_text_section, pe->sym, ind, R_386_16);
-    gen_le16(pe->v);
-}
-static void gen_disp16(ExprValue *pe)
-{
-    Sym *sym;
-    sym = pe->sym;
-    if (sym) {
-        if (sym->r == cur_text_section->sh_num) {
-            /* same section: we can output an absolute value. Note
-               that the TCC compiler behaves differently here because
-               it always outputs a relocation to ease (future) code
-               elimination in the linker */
-            gen_le16(pe->v + sym->jnext - ind - 2);
-        } else {
-            greloc(cur_text_section, sym, ind, R_386_PC16);
-            gen_le16(pe->v - 2);
-        }
-    } else {
-        /* put an empty PC32 relocation */
-        put_elf_reloc(symtab_section, cur_text_section,
-                      ind, R_386_PC16, 0);
-        gen_le16(pe->v - 2);
-    }
-}
-#endif
-
 /* generate the modrm operand */
-static inline void asm_modrm(int reg, Operand *op)
+static inline int asm_modrm(int reg, Operand *op)
 {
     int mod, reg1, reg2, sib_reg1;
@@ -487,14 +526,18 @@
     } else if (op->reg == -1 && op->reg2 == -1) {
         /* displacement only */
-#ifdef I386_ASM_16
-        if (tcc_state->seg_size == 16) {
-            g(0x06 + (reg << 3));
-            gen_expr16(&op->e);
-        } else if (tcc_state->seg_size == 32)
-#endif
-        {
-            g(0x05 + (reg << 3));
-            gen_expr32(&op->e);
-        }
+#ifdef TCC_TARGET_X86_64
+	g(0x04 + (reg << 3));
+	g(0x25);
+#else
+	g(0x05 + (reg << 3));
+#endif
+	gen_expr32(&op->e);
+#ifdef TCC_TARGET_X86_64
+    } else if (op->reg == -2) {
+        ExprValue *pe = &op->e;
+        g(0x05 + (reg << 3));
+        gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+        return ind;
+#endif
     } else {
         sib_reg1 = op->reg;
@@ -514,7 +557,4 @@
         if (op->reg2 != -1)
             reg1 = 4;
-#ifdef I386_ASM_16
-        if (tcc_state->seg_size == 32) {
-#endif
         g(mod + (reg << 3) + reg1);
         if (reg1 == 4) {
@@ -525,52 +565,113 @@
             g((op->shift << 6) + (reg2 << 3) + sib_reg1);
         }
-#ifdef I386_ASM_16
-        } else if (tcc_state->seg_size == 16) {
-            /* edi = 7, esi = 6 --> di = 5, si = 4 */
-            if ((reg1 == 6) || (reg1 == 7)) {
-                reg1 -= 2;
-            /* ebx = 3 --> bx = 7 */
-            } else if (reg1 == 3) {
-                reg1 = 7;
-            /* o32 = 5 --> o16 = 6 */
-            } else if (reg1 == 5) {
-                reg1 = 6;
-            /* sib not valid in 16-bit mode */
-            } else if (reg1 == 4) {
-                reg2 = op->reg2;
-		/* bp + si + offset */
-		if ((sib_reg1 == 5) && (reg2 == 6)) {
-		    reg1 = 2;
-		/* bp + di + offset */
-		} else if ((sib_reg1 == 5) && (reg2 == 7)) {
-		    reg1 = 3;
-		/* bx + si + offset */
-		} else if ((sib_reg1 == 3) && (reg2 == 6)) {
-		    reg1 = 0;
-		/* bx + di + offset */
-		} else if ((sib_reg1 == 3) && (reg2 == 7)) {
-		    reg1 = 1;
-		} else {
-		    tcc_error("invalid effective address");
-		}
-		if (op->e.v == 0)
-		    mod = 0;
-            } else {
-                tcc_error("invalid register");
-            }
-            g(mod + (reg << 3) + reg1);
-        }
-#endif
         /* add offset */
         if (mod == 0x40) {
             g(op->e.v);
         } else if (mod == 0x80 || op->reg == -1) {
-#ifdef I386_ASM_16
-            if (tcc_state->seg_size == 16)
-                gen_expr16(&op->e);
-            else if (tcc_state->seg_size == 32)
-#endif
-                gen_expr32(&op->e);
-        }
+	    gen_expr32(&op->e);
+        }
+    }
+    return 0;
+}
+
+#ifdef TCC_TARGET_X86_64
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+
+static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
+		    int regi, int rmi)
+{
+  unsigned char rex = width64 ? 0x48 : 0;
+  int saw_high_8bit = 0;
+  int i;
+  if (rmi == -1) {
+      /* No mod/rm byte, but we might have a register op nevertheless
+         (we will add it to the opcode later).  */
+      for(i = 0; i < nb_ops; i++) {
+	  if (op_type[i] & (OP_REG | OP_ST)) {
+	      if (ops[i].reg >= 8) {
+		  rex |= REX_B;
+		  ops[i].reg -= 8;
+	      } else if (ops[i].type & OP_REG8_LOW)
+		  rex |= 0x40;
+	      else if (ops[i].type & OP_REG8 && ops[i].reg >= 4)
+		  /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+		  saw_high_8bit = ops[i].reg;
+	      break;
+	  }
+      }
+  } else {
+      if (regi != -1) {
+	  if (ops[regi].reg >= 8) {
+	      rex |= REX_R;
+	      ops[regi].reg -= 8;
+	  } else if (ops[regi].type & OP_REG8_LOW)
+	      rex |= 0x40;
+	  else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4)
+	      /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+	      saw_high_8bit = ops[regi].reg;
+      }
+      if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) {
+	  if (ops[rmi].reg >= 8) {
+	      rex |= REX_B;
+	      ops[rmi].reg -= 8;
+	  } else if (ops[rmi].type & OP_REG8_LOW)
+	      rex |= 0x40;
+	  else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4)
+	      /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+	      saw_high_8bit = ops[rmi].reg;
+      }
+      if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) {
+	  rex |= REX_X;
+	  ops[rmi].reg2 -= 8;
+      }
+  }
+  if (rex) {
+      if (saw_high_8bit)
+	  tcc_error("can't encode register %%%ch when REX prefix is required",
+		    "acdb"[saw_high_8bit-4]);
+      g(rex);
+  }
+}
+#endif
+
+static void maybe_print_stats (void)
+{
+  static int already = 1;
+  if (!already)
+    /* print stats about opcodes */
+    {
+        const struct ASMInstr *pa;
+        int freq[4];
+        int op_vals[500];
+        int nb_op_vals, i, j;
+
+	already = 1;
+        nb_op_vals = 0;
+        memset(freq, 0, sizeof(freq));
+        for(pa = asm_instrs; pa->sym != 0; pa++) {
+            freq[pa->nb_ops]++;
+            //for(i=0;i<pa->nb_ops;i++) {
+                for(j=0;j<nb_op_vals;j++) {
+                    //if (pa->op_type[i] == op_vals[j])
+                    if (pa->instr_type == op_vals[j])
+                        goto found;
+                }
+                //op_vals[nb_op_vals++] = pa->op_type[i];
+                op_vals[nb_op_vals++] = pa->instr_type;
+            found: ;
+            //}
+        }
+        for(i=0;i<nb_op_vals;i++) {
+            int v = op_vals[i];
+            //if ((v & (v - 1)) != 0)
+                printf("%3d: %08x\n", i, v);
+        }
+        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
+               (int)sizeof(asm_instrs),
+	       (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr),
+               freq[0], freq[1], freq[2], freq[3]);
     }
 }
@@ -579,12 +680,16 @@
 {
     const ASMInstr *pa;
-    int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
+    int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
     int nb_ops, s;
     Operand ops[MAX_OPERANDS], *pop;
     int op_type[3]; /* decoded op type */
-#ifdef I386_ASM_16
-    static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0;
-#endif
-
+    int alltypes;   /* OR of all operand types */
+    int autosize;
+    int p66;
+#ifdef TCC_TARGET_X86_64
+    int rex64;
+#endif
+
+    maybe_print_stats();
     /* force synthetic ';' after prefix instruction, so we can handle */
     /* one-line things like "rep stosb" instead of only "rep\nstosb" */
@@ -596,4 +701,5 @@
     nb_ops = 0;
     seg_prefix = 0;
+    alltypes = 0;
     for(;;) {
         if (tok == ';' || tok == TOK_LINEFEED)
@@ -609,9 +715,7 @@
            next();
            parse_operand(s1, pop);
-#ifndef I386_ASM_16
            if (!(pop->type & OP_EA)) {
                tcc_error("segment prefix must be followed by memory reference");
            }
-#endif
         }
         pop++;
@@ -622,27 +726,50 @@
     }
 
-    is_short_jmp = 0;
     s = 0; /* avoid warning */
 
+again:
     /* optimize matching by using a lookup table (no hashing is needed
        !) */
     for(pa = asm_instrs; pa->sym != 0; pa++) {
+	int it = pa->instr_type & OPCT_MASK;
         s = 0;
-        if (pa->instr_type & OPC_FARITH) {
+        if (it == OPC_FARITH) {
             v = opcode - pa->sym;
             if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
                 continue;
-        } else if (pa->instr_type & OPC_ARITH) {
+        } else if (it == OPC_ARITH) {
             if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX))
                 continue;
             s = (opcode - pa->sym) % NBWLX;
-        } else if (pa->instr_type & OPC_SHIFT) {
+	    if ((pa->instr_type & OPC_BWLX) == OPC_WLX)
+	      {
+		/* We need to reject the xxxb opcodes that we accepted above.
+		   Note that pa->sym for WLX opcodes is the 'w' token,
+		   to get the 'b' token subtract one.  */
+		if (((opcode - pa->sym + 1) % NBWLX) == 0)
+		    continue;
+	        s++;
+	      }
+        } else if (it == OPC_SHIFT) {
             if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
                 continue;
             s = (opcode - pa->sym) % NBWLX;
-        } else if (pa->instr_type & OPC_TEST) {
+        } else if (it == OPC_TEST) {
             if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
                 continue;
+	    /* cmovxx is a test opcode but accepts multiple sizes.
+	       The suffixes aren't encoded in the table, instead we
+	       simply force size autodetection always and deal with suffixed
+	       variants below when we don't find e.g. "cmovzl".  */
+	    if (pa->instr_type & OPC_WLX)
+	        s = NBWLX - 1;
         } else if (pa->instr_type & OPC_B) {
+#ifdef TCC_TARGET_X86_64
+	    /* Some instructions don't have the full size but only
+	       bwl form.  insb e.g. */
+	    if ((pa->instr_type & OPC_WLQ) != OPC_WLQ
+		&& !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
+	        continue;
+#endif
             if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX))
                 continue;
@@ -658,5 +785,15 @@
         if (pa->nb_ops != nb_ops)
             continue;
+#ifdef TCC_TARGET_X86_64
+	/* Special case for moves.  Selecting the IM64->REG64 form
+	   should only be done if we really have an >32bit imm64, and that
+	   is hardcoded.  Ignore it here.  */
+	if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
+	    && (ops[1].type & OP_REG) == OP_REG64
+	    && !(pa->instr_type & OPC_0F))
+	    continue;
+#endif
         /* now decode and check each operand */
+	alltypes = 0;
         for(i = 0; i < nb_ops; i++) {
             int op1, op2;
@@ -665,5 +802,5 @@
             switch(op2) {
             case OPT_IM:
-                v = OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64;
+                v = OP_IM8 | OP_IM16 | OP_IM32;
                 break;
             case OPT_REG:
@@ -674,11 +811,13 @@
                 break;
             case OPT_IMW:
-                v = OP_IM16 | OP_IM32 | OP_IM64;
-                break;
-#ifdef TCC_TARGET_X86_64
-            case OPT_IMNO64:
                 v = OP_IM16 | OP_IM32;
                 break;
-#endif
+	    case OPT_MMXSSE:
+		v = OP_MMX | OP_SSE;
+		break;
+	    case OPT_DISP:
+	    case OPT_DISP8:
+		v = OP_ADDR;
+		break;
             default:
                 v = 1 << op2;
@@ -687,7 +826,8 @@
             if (op1 & OPT_EA)
                 v |= OP_EA;
-            op_type[i] = v;
+	    op_type[i] = v;
             if ((ops[i].type & v) == 0)
                 goto next;
+	    alltypes |= ops[i].type;
         }
         /* all is matching ! */
@@ -699,36 +839,48 @@
             int b;
             b = op0_codes[opcode - TOK_ASM_first];
-#ifdef I386_ASM_16
-            if (opcode == TOK_ASM_o32) {
-                if (s1->seg_size == 32)
-                    tcc_error("incorrect prefix");
-                else
-                    o32 = data32 = 1;
-            } else if (opcode == TOK_ASM_a32) {
-                if (s1->seg_size == 32)
-                    tcc_error("incorrect prefix");
-                else
-                    a32 = addr32 = 1;
-            }
-#endif
             if (b & 0xff00) 
                 g(b >> 8);
             g(b);
             return;
+        } else if (opcode <= TOK_ASM_alllast) {
+            tcc_error("bad operand with opcode '%s'",
+                  get_tok_str(opcode, NULL));
         } else {
-            tcc_error("unknown opcode '%s'",
-                  get_tok_str(opcode, NULL));
+	    /* Special case for cmovcc, we accept size suffixes but ignore
+	       them, but we don't want them to blow up our tables.  */
+	    TokenSym *ts = table_ident[opcode - TOK_IDENT];
+	    if (ts->len >= 6
+		&& strchr("wlq", ts->str[ts->len-1])
+		&& !memcmp(ts->str, "cmov", 4)) {
+		opcode = tok_alloc(ts->str, ts->len-1)->tok;
+		goto again;
+	    }
+            tcc_error("unknown opcode '%s'", ts->str);
         }
     }
     /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
-    if (s == NBWLX-1) {
-        for(i = 0; s == NBWLX-1 && i < nb_ops; i++) {
+    autosize = NBWLX-1;
+#ifdef TCC_TARGET_X86_64
+    /* XXX the autosize should rather be zero, to not have to adjust this
+       all the time.  */
+    if ((pa->instr_type & OPC_BWLQ) == OPC_B)
+        autosize = NBWLX-2;
+#endif
+    if (s == autosize) {
+	/* Check for register operands providing hints about the size.
+	   Start from the end, i.e. destination operands.  This matters
+	   only for opcodes accepting different sized registers, lar and lsl
+	   are such opcodes.  */
+        for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
             if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
                 s = reg_to_size[ops[i].type & OP_REG];
         }
-        if (s == NBWLX-1) {
+        if (s == autosize) {
             if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
-                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32 | OP_IM64)))
+                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
                 s = 2;
+	    else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
+		     (ops[0].type & OP_EA))
+	        s = NBWLX - 2;
             else
                 tcc_error("cannot infer opcode suffix");
@@ -736,50 +888,57 @@
     }
 
-#ifdef I386_ASM_16
+#ifdef TCC_TARGET_X86_64
+    /* Generate addr32 prefix if needed */
     for(i = 0; i < nb_ops; i++) {
-        if (ops[i].type & OP_REG32) {
-            if (s1->seg_size == 16)
-                o32 = 1;
-        } else if (!(ops[i].type & OP_REG32)) {
-            if (s1->seg_size == 32)
-                o32 = 1;
-        }
-    }
-
-
-    if (s == 1 || (pa->instr_type & OPC_D16)) {
-        if (s1->seg_size == 32)
-            o32 = 1;
-    } else if (s == 2) {
-        if (s1->seg_size == 16) {
-            if (!(pa->instr_type & OPC_D16))
-            o32 = 1;
-        }
-    }
-
-    /* generate a16/a32 prefix if needed */
-    if ((a32 == 1) && (addr32 == 0))
-        g(0x67);
-    /* generate o16/o32 prefix if needed */
-    if ((o32 == 1) && (data32 == 0))
+        if (ops[i].type & OP_EA32) {
+	    g(0x67);
+	    break;
+        }
+    }
+#endif
+    /* generate data16 prefix if needed */
+    p66 = 0;
+    if (s == 1)
+        p66 = 1;
+    else {
+	/* accepting mmx+sse in all operands --> needs 0x66 to
+	   switch to sse mode.  Accepting only sse in an operand --> is
+	   already SSE insn and needs 0x66/f2/f3 handling.  */
+        for (i = 0; i < nb_ops; i++)
+            if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
+	        && ops[i].type & OP_SSE)
+	        p66 = 1;
+    }
+    if (p66)
         g(0x66);
-
-    addr32 = data32 = 0;
-#else
-    /* generate data16 prefix if needed */
-    if (s == 1 || (pa->instr_type & OPC_D16))
-        g(0x66);
-#ifdef TCC_TARGET_X86_64
-    else if (s == 3) {
+#ifdef TCC_TARGET_X86_64
+    rex64 = 0;
+    if (pa->instr_type & OPC_48)
+        rex64 = 1;
+    else if (s == 3 || (alltypes & OP_REG64)) {
         /* generate REX prefix */
-        if ((opcode != TOK_ASM_push && opcode != TOK_ASM_pop)
-            || !(ops[0].type & OP_REG64))
-            g(0x48);
-    }
-#endif
+	int default64 = 0;
+	for(i = 0; i < nb_ops; i++) {
+	    if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
+		/* If only 64bit regs are accepted in one operand
+		   this is a default64 instruction without need for
+		   REX prefixes, except for movabs(0xb8).  */
+		default64 = 1;
+		break;
+	    }
+	}
+	/* XXX find better encoding for the default64 instructions.  */
+        if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop
+	      && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl
+	      && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw
+	      && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq
+	      && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp))
+	    && !default64)
+            rex64 = 1;
+    }
 #endif
 
     /* now generates the operation */
-    if (pa->instr_type & OPC_FWAIT)
+    if (OPCT_IS(pa->instr_type, OPC_FWAIT))
         g(0x9b);
     if (seg_prefix)
@@ -787,4 +946,6 @@
 
     v = pa->opcode;
+    if (pa->instr_type & OPC_0F)
+        v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff);
     if ((v == 0x69 || v == 0x6b) && nb_ops == 2) {
         /* kludge for imul $im, %reg */
@@ -806,9 +967,56 @@
         /* arith case */
         v += ((opcode - TOK_ASM_addb) / NBWLX) << 3;
-    } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
+    } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) {
         /* fpu arith case */
         v += ((opcode - pa->sym) / 6) << 3;
     }
+
+    /* search which operand will be used for modrm */
+    modrm_index = -1;
+    modreg_index = -1;
+    if (pa->instr_type & OPC_MODRM) {
+	if (!nb_ops) {
+	    /* A modrm opcode without operands is a special case (e.g. mfence).
+	       It has a group and acts as if there's an register operand 0
+	       (ax).  */
+	    i = 0;
+	    ops[i].type = OP_REG;
+	    ops[i].reg = 0;
+	    goto modrm_found;
+	}
+        /* first look for an ea operand */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & OP_EA)
+                goto modrm_found;
+        }
+        /* then if not found, a register or indirection (shift instructions) */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
+                goto modrm_found;
+        }
+#ifdef ASM_DEBUG
+        tcc_error("bad op table");
+#endif
+    modrm_found:
+        modrm_index = i;
+        /* if a register is used in another operand then it is
+           used instead of group */
+        for(i = 0;i < nb_ops; i++) {
+            int t = op_type[i];
+            if (i != modrm_index &&
+                (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
+                modreg_index = i;
+                break;
+            }
+        }
+    }
+#ifdef TCC_TARGET_X86_64
+    asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
+#endif
+
     if (pa->instr_type & OPC_REG) {
+        /* mov $im, %reg case */
+        if (v == 0xb0 && s >= 1)
+            v += 7;
         for(i = 0; i < nb_ops; i++) {
             if (op_type[i] & (OP_REG | OP_ST)) {
@@ -817,99 +1025,70 @@
             }
         }
-        /* mov $im, %reg case */
-        if (pa->opcode == 0xb0 && s >= 1)
-            v += 7;
     }
     if (pa->instr_type & OPC_B)
         v += s >= 1;
-    if (pa->instr_type & OPC_TEST)
-        v += test_bits[opcode - pa->sym];
-    if (pa->instr_type & OPC_SHORTJMP) {
-        Sym *sym;
+    if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
+	ElfSym *esym;
         int jmp_disp;
 
         /* see if we can really generate the jump with a byte offset */
-        sym = ops[0].e.sym;
-        if (!sym)
+	esym = elfsym(ops[0].e.sym);
+        if (!esym || esym->st_shndx != cur_text_section->sh_num)
             goto no_short_jump;
-        if (sym->r != cur_text_section->sh_num)
-            goto no_short_jump;
-        jmp_disp = ops[0].e.v + sym->jnext - ind - 2;
+        jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
         if (jmp_disp == (int8_t)jmp_disp) {
             /* OK to generate jump */
-            is_short_jmp = 1;
+	    ops[0].e.sym = 0;
             ops[0].e.v = jmp_disp;
+	    op_type[0] = OP_IM8S;
         } else {
         no_short_jump:
-            if (pa->instr_type & OPC_JMP) {
-                /* long jump will be allowed. need to modify the
-                   opcode slightly */
-                if (v == 0xeb)
-                    v = 0xe9;
-                else
-                    v += 0x0f10;
-            } else {
-                tcc_error("invalid displacement");
-            }
-        }
-    }
-    op1 = v >> 8;
+	    /* long jump will be allowed. need to modify the
+	       opcode slightly */
+	    if (v == 0xeb) /* jmp */
+	        v = 0xe9;
+	    else if (v == 0x70) /* jcc */
+	        v += 0x0f10;
+	    else
+	        tcc_error("invalid displacement");
+        }
+    }
+    if (OPCT_IS(pa->instr_type, OPC_TEST))
+        v += test_bits[opcode - pa->sym];
+    op1 = v >> 16;
+    if (op1)
+        g(op1);
+    op1 = (v >> 8) & 0xff;
     if (op1)
         g(op1);
     g(v);
 
-    /* search which operand will used for modrm */
-    modrm_index = 0;
-    if (pa->instr_type & OPC_SHIFT) {
+    if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
         reg = (opcode - pa->sym) / NBWLX;
         if (reg == 6)
             reg = 7;
-    } else if (pa->instr_type & OPC_ARITH) {
+    } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) {
         reg = (opcode - pa->sym) / NBWLX;
-    } else if (pa->instr_type & OPC_FARITH) {
+    } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) {
         reg = (opcode - pa->sym) / 6;
     } else {
         reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
     }
+
+    pc = 0;
     if (pa->instr_type & OPC_MODRM) {
-        /* first look for an ea operand */
-        for(i = 0;i < nb_ops; i++) {
-            if (op_type[i] & OP_EA)
-                goto modrm_found;
-        }
-        /* then if not found, a register or indirection (shift instructions) */
-        for(i = 0;i < nb_ops; i++) {
-            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
-                goto modrm_found;
-        }
-#ifdef ASM_DEBUG
-        tcc_error("bad op table");
-#endif
-    modrm_found:
-        modrm_index = i;
         /* if a register is used in another operand then it is
            used instead of group */
-        for(i = 0;i < nb_ops; i++) {
-            v = op_type[i];
-            if (i != modrm_index &&
-                (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
-                reg = ops[i].reg;
-                break;
-            }
-        }
-
-        asm_modrm(reg, &ops[modrm_index]);
+	if (modreg_index >= 0)
+	    reg = ops[modreg_index].reg;
+        pc = asm_modrm(reg, &ops[modrm_index]);
     }
 
     /* emit constants */
 #ifndef TCC_TARGET_X86_64
-    if (pa->opcode == 0x9a || pa->opcode == 0xea) {
+    if (!(pa->instr_type & OPC_0F)
+	&& (pa->opcode == 0x9a || pa->opcode == 0xea)) {
         /* ljmp or lcall kludge */
-#ifdef I386_ASM_16
-        if (s1->seg_size == 16 && o32 == 0)
-            gen_expr16(&ops[1].e);
-        else
-#endif
-            gen_expr32(&ops[1].e);
+	gen_expr32(&ops[1].e);
         if (ops[0].e.sym)
             tcc_error("cannot relocate");
@@ -933,62 +1112,27 @@
                     v = OP_IM64;
             }
+
+            if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
+                tcc_error("cannot relocate");
+
             if (v & (OP_IM8 | OP_IM8S)) {
-                if (ops[i].e.sym)
-                    goto error_relocate;
                 g(ops[i].e.v);
             } else if (v & OP_IM16) {
-#ifdef I386_ASM_16
-                if (s1->seg_size == 16)
-                    gen_expr16(&ops[i].e);
-                else
-#endif
-                if (ops[i].e.sym)
-                error_relocate:
-                    tcc_error("cannot relocate");
-                else
-                    gen_le16(ops[i].e.v);
+                gen_le16(ops[i].e.v);
+#ifdef TCC_TARGET_X86_64
+            } else if (v & OP_IM64) {
+                gen_expr64(&ops[i].e);
+#endif
+	    } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
+                gen_disp32(&ops[i].e);
             } else {
-                if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
-                    if (is_short_jmp)
-                        g(ops[i].e.v);
-#ifdef I386_ASM_16
-                    else if (s1->seg_size == 16)
-                        gen_disp16(&ops[i].e);
-#endif
-                    else
-                        gen_disp32(&ops[i].e);
-                } else {
-#ifdef I386_ASM_16
-                    if (s1->seg_size == 16 && !((o32 == 1) && (v & OP_IM32)))
-                        gen_expr16(&ops[i].e);
-                    else
-#endif
-#ifdef TCC_TARGET_X86_64
-                    if (v & OP_IM64)
-                        gen_expr64(&ops[i].e);
-                    else
-#endif
-                        gen_expr32(&ops[i].e);
-                }
+                gen_expr32(&ops[i].e);
             }
-#ifdef I386_ASM_16
-        } else if (v & (OP_REG16 | OP_REG32)) {
-            if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
-                /* jmp $r */
-                g(0xE0 + ops[i].reg);
-            }
-#endif
-#ifdef TCC_TARGET_X86_64
-        } else if (v & (OP_REG32 | OP_REG64)) {
-            if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
-                /* jmp $r */
-                g(0xE0 + ops[i].reg);
-            }
-#endif
-        }
-    }
-#ifdef I386_ASM_16
-    a32 = o32 = 0;
-#endif
+        }
+    }
+
+    /* after immediate operands, adjust pc-relative address */
+    if (pc)
+        add32le(cur_text_section->data + pc - 4, pc - ind);
 }
 
@@ -1022,4 +1166,6 @@
             break;
         case 'r':
+	case 'R':
+	case 'p':
             pr = 3;
             break;
@@ -1027,4 +1173,5 @@
         case 'M':
         case 'I':
+	case 'e':
         case 'i':
         case 'm':
@@ -1047,4 +1194,26 @@
         p++;
     return p;
+}
+
+/* If T (a token) is of the form "%reg" returns the register
+   number and type, otherwise return -1.  */
+ST_FUNC int asm_parse_regvar (int t)
+{
+    const char *s;
+    Operand op;
+    if (t < TOK_IDENT)
+        return -1;
+    s = table_ident[t - TOK_IDENT]->str;
+    if (s[0] != '%')
+        return -1;
+    t = tok_alloc(s+1, strlen(s)-1)->tok;
+    unget_tok(t);
+    unget_tok('%');
+    parse_operand(tcc_state, &op);
+    /* Accept only integer regs for now.  */
+    if (op.type & OP_REG)
+        return op.reg;
+    else
+        return -1;
 }
 
@@ -1091,4 +1260,9 @@
             operands[k].input_index = i;
             op->priority = 5;
+	} else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
+		   && op->vt->sym
+		   && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) {
+	    op->priority = 1;
+	    op->reg = reg;
         } else {
             op->priority = constraint_priority(str);
@@ -1138,4 +1312,10 @@
             reg_mask = REG_IN_MASK;
         }
+	if (op->reg >= 0) {
+	    if (is_reg_allocated(op->reg))
+	        tcc_error("asm regvar requests register that's taken already");
+	    reg = op->reg;
+	    goto reg_found;
+	}
     try_next:
         c = *str++;
@@ -1190,4 +1370,6 @@
             goto try_next;
         case 'r':
+	case 'R':
+	case 'p': /* A general address, for x86(64) any register is acceptable*/
             /* any general register */
             for(reg = 0; reg < 8; reg++) {
@@ -1202,4 +1384,5 @@
             regs_allocated[reg] |= reg_mask;
             break;
+	case 'e':
         case 'i':
             if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
@@ -1294,22 +1477,39 @@
     r = sv->r;
     if ((r & VT_VALMASK) == VT_CONST) {
-        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
+        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
+	    modifier != 'P')
             cstr_ccat(add_str, '$');
         if (r & VT_SYM) {
-            cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
-            if (sv->c.i != 0) {
-                cstr_ccat(add_str, '+');
-            } else {
-                return;
-            }
+	    const char *name = get_tok_str(sv->sym->v, NULL);
+	    if (sv->sym->v >= SYM_FIRST_ANOM) {
+		/* In case of anonymous symbols ("L.42", used
+		   for static data labels) we can't find them
+		   in the C symbol table when later looking up
+		   this name.  So enter them now into the asm label
+		   list when we still know the symbol.  */
+		get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
+	    }
+            cstr_cat(add_str, name, -1);
+            if ((uint32_t)sv->c.i == 0)
+                goto no_offset;
+	    cstr_ccat(add_str, '+');
         }
         val = sv->c.i;
         if (modifier == 'n')
             val = -val;
-        snprintf(buf, sizeof(buf), "%d", sv->c.i);
-        cstr_cat(add_str, buf);
+        snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
+        cstr_cat(add_str, buf, -1);
+    no_offset:;
+#ifdef TCC_TARGET_X86_64
+        if (r & VT_LVAL)
+            cstr_cat(add_str, "(%rip)", -1);
+#endif
     } else if ((r & VT_VALMASK) == VT_LOCAL) {
-        snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
-        cstr_cat(add_str, buf);
+#ifdef TCC_TARGET_X86_64
+        snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
+#else
+        snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
+#endif
+        cstr_cat(add_str, buf, -1);
     } else if (r & VT_LVAL) {
         reg = r & VT_VALMASK;
@@ -1317,6 +1517,11 @@
             tcc_error("internal compiler error");
         snprintf(buf, sizeof(buf), "(%%%s)",
-                 get_tok_str(TOK_ASM_eax + reg, NULL));
-        cstr_cat(add_str, buf);
+#ifdef TCC_TARGET_X86_64
+                 get_tok_str(TOK_ASM_rax + reg, NULL)
+#else
+                 get_tok_str(TOK_ASM_eax + reg, NULL)
+#endif
+		 );
+        cstr_cat(add_str, buf, -1);
     } else {
         /* register case */
@@ -1326,10 +1531,12 @@
 
         /* choose register operand size */
-        if ((sv->type.t & VT_BTYPE) == VT_BYTE)
+        if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
+	    (sv->type.t & VT_BTYPE) == VT_BOOL)
             size = 1;
         else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
             size = 2;
 #ifdef TCC_TARGET_X86_64
-        else if ((sv->type.t & VT_BTYPE) == VT_LLONG)
+        else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
+		 (sv->type.t & VT_BTYPE) == VT_PTR)
             size = 8;
 #endif
@@ -1349,4 +1556,6 @@
         } else if (modifier == 'w') {
             size = 2;
+        } else if (modifier == 'k') {
+            size = 4;
 #ifdef TCC_TARGET_X86_64
         } else if (modifier == 'q') {
@@ -1375,9 +1584,9 @@
         }
         snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
-        cstr_cat(add_str, buf);
+        cstr_cat(add_str, buf, -1);
     }
 }
 
-/* generate prolog and epilog code for asm statment */
+/* generate prolog and epilog code for asm statement */
 ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
                          int nb_outputs, int is_output,
@@ -1388,5 +1597,16 @@
     ASMOperand *op;
     int i, reg;
-    static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
+
+    /* Strictly speaking %Xbp and %Xsp should be included in the
+       call-preserved registers, but currently it doesn't matter.  */
+#ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+    static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 };
+#else
+    static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
+#endif
+#else
+    static uint8_t reg_saved[] = { 3, 6, 7 };
+#endif
 
     /* mark all used registers */
@@ -1399,11 +1619,9 @@
     if (!is_output) {
         /* generate reg save code */
-        for(i = 0; i < NB_SAVED_REGS; i++) {
+        for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
             reg = reg_saved[i];
             if (regs_allocated[reg]) {
-#ifdef I386_ASM_16
-                if (tcc_state->seg_size == 16)
-                    g(0x66);
-#endif
+		if (reg >= 8)
+		  g(0x41), reg-=8;
                 g(0x50 + reg);
             }
@@ -1420,5 +1638,6 @@
                     SValue sv;
                     sv = *op->vt;
-                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
+                    sv.type.t = VT_PTR;
                     load(op->reg, &sv);
                 } else if (i >= nb_outputs || op->is_rw) {
@@ -1428,5 +1647,5 @@
                         SValue sv;
                         sv = *op->vt;
-                        sv.c.ul += 4;
+                        sv.c.i += 4;
                         load(TREG_XDX, &sv);
                     }
@@ -1444,6 +1663,8 @@
                         sv = *op->vt;
                         sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+			sv.type.t = VT_PTR;
                         load(out_reg, &sv);
 
+			sv = *op->vt;
                         sv.r = (sv.r & ~VT_VALMASK) | out_reg;
                         store(op->reg, &sv);
@@ -1454,5 +1675,5 @@
                         SValue sv;
                         sv = *op->vt;
-                        sv.c.ul += 4;
+                        sv.c.i += 4;
                         store(TREG_XDX, &sv);
                     }
@@ -1461,11 +1682,9 @@
         }
         /* generate reg restore code */
-        for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
+        for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
             reg = reg_saved[i];
             if (regs_allocated[reg]) {
-#ifdef I386_ASM_16
-                if (tcc_state->seg_size == 16)
-                    g(0x66);
-#endif
+		if (reg >= 8)
+		  g(0x41), reg-=8;
                 g(0x58 + reg);
             }
@@ -1478,7 +1697,11 @@
     int reg;
     TokenSym *ts;
+#ifdef TCC_TARGET_X86_64
+    unsigned int type;
+#endif
 
     if (!strcmp(str, "memory") ||
-        !strcmp(str, "cc"))
+        !strcmp(str, "cc") ||
+	!strcmp(str, "flags"))
         return;
     ts = tok_alloc(str, strlen(str));
@@ -1491,4 +1714,6 @@
     } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
         reg -= TOK_ASM_rax;
+    } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
+	;
 #endif
     } else {
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/i386-asm.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h	(revision 331)
@@ -39,51 +39,46 @@
 
      /* strings */
-ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
-ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
 
 ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
 ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
 
-ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
-ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
-
-ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
-ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
-
-ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
-ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
-
-ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
-ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
 
      /* bits */
      
-ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
-
-ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
 
      /* prefixes */
      DEF_ASM_OP0(wait, 0x9b)
      DEF_ASM_OP0(fwait, 0x9b)
-#ifdef I386_ASM_16
-     DEF_ASM_OP0(a32, 0x67)
-     DEF_ASM_OP0(o32, 0x66)
-#else
      DEF_ASM_OP0(aword, 0x67)
      DEF_ASM_OP0(addr16, 0x67)
      ALT(DEF_ASM_OP0(word, 0x66))
      DEF_ASM_OP0(data16, 0x66)
-#endif
      DEF_ASM_OP0(lock, 0xf0)
      DEF_ASM_OP0(rep, 0xf3)
@@ -103,41 +98,41 @@
 
      /* NOTE: we took the same order as gas opcode definition order */
-ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
-ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
-ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
-
-ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
-ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
-ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
-ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
-ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
-ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR))
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB))
+ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR))
 
 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
 
-ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
-ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
-ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
-ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
-
-ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
-ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
-
-ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
-ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
-ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
 
 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
@@ -151,5 +146,5 @@
 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
 
-ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
 
 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
@@ -160,64 +155,62 @@
 
      /* arith */
-ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
-ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
-ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
-ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
-ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
-ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
-ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
-ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
-
-ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
-ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
 
      /* shifts */
-ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
 
 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
-ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
-ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
-#ifdef I386_ASM_16
-ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW))
-#endif
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
 
 ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
-ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
 ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
-ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
 
 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
     DEF_ASM_OP0(leave, 0xc9)
@@ -229,11 +222,11 @@
 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
 
-ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
-    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
      
      /* float */
@@ -349,10 +342,10 @@
     /* segments */
     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
-    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
-ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
     DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
@@ -364,17 +357,12 @@
     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
 
-#ifdef I386_ASM_16
-    /* 386 */
-    DEF_ASM_OP0(loadall386, 0x0f07)
-#endif
-
     /* 486 */
     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
-ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
-ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
 
     DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
-    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
+    DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA)
 
     /* pentium */
@@ -382,14 +370,5 @@
     
     /* pentium pro */
-    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-#ifdef I386_ASM_16
-ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-#endif
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
     DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
@@ -408,61 +387,89 @@
     /* mmx */
     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
-
-    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
-ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
     DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
-    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+
+    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+    /* sse */
+    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
 
 #undef ALT
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/i386-gen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c	(revision 331)
@@ -22,6 +22,7 @@
 
 /* number of available registers */
-#define NB_REGS         4
+#define NB_REGS         5
 #define NB_ASM_REGS     8
+#define CONFIG_TCC_ASM
 
 /* a register can belong to several classes. The classes must be
@@ -34,4 +35,6 @@
 #define RC_ECX     0x0010
 #define RC_EDX     0x0020
+#define RC_EBX     0x0040
+
 #define RC_IRET    RC_EAX /* function return: integer register */
 #define RC_LRET    RC_EDX /* function return: second integer register */
@@ -43,5 +46,7 @@
     TREG_ECX,
     TREG_EDX,
+    TREG_EBX,
     TREG_ST0,
+    TREG_ESP = 4
 };
 
@@ -56,5 +61,5 @@
 /* defined if structures are passed as pointers. Otherwise structures
    are directly pushed on stack. */
-//#define FUNC_STRUCT_PARAM_AS_PTR
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
 
 /* pointer size, in bytes */
@@ -67,21 +72,4 @@
 #define MAX_ALIGN     8
 
-
-#define psym oad
-
-/******************************************************/
-/* ELF defines */
-
-#define EM_TCC_TARGET EM_386
-
-/* relocation type for 32 bit data relocation */
-#define R_DATA_32   R_386_32
-#define R_DATA_PTR  R_386_32
-#define R_JMP_SLOT  R_386_JMP_SLOT
-#define R_COPY      R_386_COPY
-
-#define ELF_START_ADDR 0x08048000
-#define ELF_PAGE_SIZE  0x1000
-
 /******************************************************/
 #else /* ! TARGET_DEFS_ONLY */
@@ -89,8 +77,12 @@
 #include "tcc.h"
 
+/* define to 1/0 to [not] have EBX as 4th register */
+#define USE_EBX 0
+
 ST_DATA const int reg_classes[NB_REGS] = {
     /* eax */ RC_INT | RC_EAX,
     /* ecx */ RC_INT | RC_ECX,
     /* edx */ RC_INT | RC_EDX,
+    /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
     /* st0 */ RC_FLOAT | RC_ST0,
 };
@@ -99,5 +91,6 @@
 static int func_ret_sub;
 #ifdef CONFIG_TCC_BCHECK
-static unsigned long func_bound_offset;
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
 #endif
 
@@ -106,4 +99,6 @@
 {
     int ind1;
+    if (nocode_wanted)
+        return;
     ind1 = ind + 1;
     if (ind1 > cur_text_section->data_allocated)
@@ -138,9 +133,8 @@
 ST_FUNC void gsym_addr(int t, int a)
 {
-    int n, *ptr;
     while (t) {
-        ptr = (int *)(cur_text_section->data + t);
-        n = *ptr; /* next value */
-        *ptr = a - t - 4;
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t n = read32le(ptr); /* next value */
+        write32le(ptr, a - t - 4);
         t = n;
     }
@@ -152,22 +146,18 @@
 }
 
-/* psym is used to put an instruction with a data field which is a
-   reference to a symbol. It is in fact the same as oad ! */
-#define psym oad
-
 /* instruction + 4 bytes data. Return the address of the data */
-ST_FUNC int oad(int c, int s)
-{
-    int ind1;
-
+static int oad(int c, int s)
+{
+    int t;
+    if (nocode_wanted)
+        return s;
     o(c);
-    ind1 = ind + 4;
-    if (ind1 > cur_text_section->data_allocated)
-        section_realloc(cur_text_section, ind1);
-    *(int *)(cur_text_section->data + ind) = s;
-    s = ind;
-    ind = ind1;
-    return s;
-}
+    t = ind;
+    gen_le32(s);
+    return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
 
 /* output constant with relocation if 'r & VT_SYM' is true */
@@ -186,5 +176,5 @@
 }
 
-/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+/* generate a modrm reference. 'op_reg' contains the additional 3
    opcode bits */
 static void gen_modrm(int op_reg, int r, Sym *sym, int c)
@@ -221,6 +211,8 @@
 
     fr = sv->r;
-    ft = sv->type.t;
-    fc = sv->c.ul;
+    ft = sv->type.t & ~VT_DEFSIGN;
+    fc = sv->c.i;
+
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
 
     v = fr & VT_VALMASK;
@@ -229,5 +221,5 @@
             v1.type.t = VT_INT;
             v1.r = VT_LOCAL | VT_LVAL;
-            v1.c.ul = fc;
+            v1.c.i = fc;
             fr = r;
             if (!(reg_classes[fr] & RC_INT))
@@ -244,5 +236,5 @@
             o(0xdb); /* fldt */
             r = 5;
-        } else if ((ft & VT_TYPE) == VT_BYTE) {
+        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
             o(0xbe0f);   /* movsbl */
         } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
@@ -297,6 +289,7 @@
 
     ft = v->type.t;
-    fc = v->c.ul;
+    fc = v->c.i;
     fr = v->r & VT_VALMASK;
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
     bt = ft & VT_BTYPE;
     /* XXX: incorrect if float reg to reg */
@@ -338,20 +331,23 @@
 }
 
+#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
+static void gen_static_call(int v)
+{
+    Sym *sym;
+
+    sym = external_global_sym(v, &func_old_type, 0);
+    oad(0xe8, -4);
+    greloc(cur_text_section, sym, ind-4, R_386_PC32);
+}
+#endif
+
 /* 'is_jmp' is '1' if it is a jump */
 static void gcall_or_jmp(int is_jmp)
 {
     int r;
-    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
-        /* constant case */
-        if (vtop->r & VT_SYM) {
-            /* relocation case */
-            greloc(cur_text_section, vtop->sym, 
-                   ind + 1, R_386_PC32);
-        } else {
-            /* put an empty PC32 relocation */
-            put_elf_reloc(symtab_section, cur_text_section, 
-                          ind + 1, R_386_PC32, 0);
-        }
-        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
+        /* constant and relocation case */
+        greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
+        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
     } else {
         /* otherwise, indirect call */
@@ -360,8 +356,62 @@
         o(0xd0 + r + (is_jmp << 4));
     }
+    if (!is_jmp) {
+        int rt;
+        /* extend the return value to the whole register if necessary
+           visual studio and gcc do not always set the whole eax register
+           when assigning the return value of a function  */
+        rt = vtop->type.ref->type.t;
+        switch (rt & VT_BTYPE) {
+            case VT_BYTE:
+                if (rt & VT_UNSIGNED) {
+                    o(0xc0b60f); /* movzx %al, %eax */
+                }
+                else {
+                    o(0xc0be0f); /* movsx %al, %eax */
+                }
+                break;
+            case VT_SHORT:
+                if (rt & VT_UNSIGNED) {
+                    o(0xc0b70f); /* movzx %ax, %eax */
+                }
+                else {
+                    o(0xc0bf0f); /* movsx %ax, %eax */
+                }
+                break;
+            default:
+                break;
+        }
+    }
 }
 
 static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
 static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+#ifdef TCC_TARGET_PE
+    int size, align;
+    *ret_align = 1; // Never have to re-align return values for x86
+    *regsize = 4;
+    size = type_size(vt, &align);
+    if (size > 8 || (size & (size - 1)))
+        return 0;
+    if (size == 8)
+        ret->t = VT_LLONG;
+    else if (size == 4)
+        ret->t = VT_INT;
+    else if (size == 2)
+        ret->t = VT_SHORT;
+    else
+        ret->t = VT_BYTE;
+    ret->ref = NULL;
+    return 1;
+#else
+    *ret_align = 1; // Never have to re-align return values for x86
+    return 0;
+#endif
+}
 
 /* Generate function call. The function address is pushed first, then
@@ -422,5 +472,5 @@
     save_regs(0); /* save used temporary registers */
     func_sym = vtop->type.ref;
-    func_call = FUNC_CALL(func_sym->r);
+    func_call = func_sym->f.func_call;
     /* fast call case */
     if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
@@ -443,11 +493,11 @@
         }
     }
+#ifndef TCC_TARGET_PE
+    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
+        args_size -= 4;
+#endif
     gcall_or_jmp(0);
 
-#ifdef TCC_TARGET_PE
-    if ((func_sym->type.t & VT_BTYPE) == VT_STRUCT)
-        args_size -= 4;
-#endif
-    if (args_size && func_call != FUNC_STDCALL)
+    if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
         gadd_sp(args_size);
     vtop--;
@@ -455,7 +505,7 @@
 
 #ifdef TCC_TARGET_PE
-#define FUNC_PROLOG_SIZE 10
+#define FUNC_PROLOG_SIZE (10 + USE_EBX)
 #else
-#define FUNC_PROLOG_SIZE 9
+#define FUNC_PROLOG_SIZE (9 + USE_EBX)
 #endif
 
@@ -470,5 +520,5 @@
 
     sym = func_type->ref;
-    func_call = FUNC_CALL(sym->r);
+    func_call = sym->f.func_call;
     addr = 8;
     loc = 0;
@@ -492,5 +542,12 @@
        implicit pointer parameter */
     func_vt = sym->type;
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+#ifdef TCC_TARGET_PE
+    size = type_size(&func_vt,&align);
+    if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
+        && (size > 8 || (size & (size - 1)))) {
+#else
     if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+#endif
         /* XXX: fastcall case ? */
         func_vc = addr;
@@ -524,8 +581,8 @@
     }
     func_ret_sub = 0;
-    /* pascal type call ? */
-    if (func_call == FUNC_STDCALL)
+    /* pascal type call or fastcall ? */
+    if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
         func_ret_sub = addr - 8;
-#ifdef TCC_TARGET_PE
+#ifndef TCC_TARGET_PE
     else if (func_vc)
         func_ret_sub = 4;
@@ -535,7 +592,8 @@
     /* leave some room for bound checking code */
     if (tcc_state->do_bounds_check) {
+        func_bound_offset = lbounds_section->data_offset;
+        func_bound_ind = ind;
         oad(0xb8, 0); /* lbound section pointer */
         oad(0xb8, 0); /* call to function */
-        func_bound_offset = lbounds_section->data_offset;
     }
 #endif
@@ -545,18 +603,20 @@
 ST_FUNC void gfunc_epilog(void)
 {
-    int v, saved_ind;
+    addr_t v, saved_ind;
 
 #ifdef CONFIG_TCC_BCHECK
     if (tcc_state->do_bounds_check
      && func_bound_offset != lbounds_section->data_offset) {
-        int saved_ind;
-        int *bounds_ptr;
-        Sym *sym, *sym_data;
+        addr_t saved_ind;
+        addr_t *bounds_ptr;
+        Sym *sym_data;
+
         /* add end of table info */
-        bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
+        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
         *bounds_ptr = 0;
+
         /* generate bound local allocation */
         saved_ind = ind;
-        ind = func_sub_sp_offset;
+        ind = func_bound_ind;
         sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
                                func_bound_offset, lbounds_section->data_offset);
@@ -564,21 +624,24 @@
                ind + 1, R_386_32);
         oad(0xb8, 0); /* mov %eax, xxx */
-        sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
-        greloc(cur_text_section, sym, 
-               ind + 1, R_386_PC32);
-        oad(0xe8, -4);
+        gen_static_call(TOK___bound_local_new);
         ind = saved_ind;
+
         /* generate bound check local freeing */
         o(0x5250); /* save returned value, if any */
-        greloc(cur_text_section, sym_data,
-               ind + 1, R_386_32);
+        greloc(cur_text_section, sym_data, ind + 1, R_386_32);
         oad(0xb8, 0); /* mov %eax, xxx */
-        sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
-        greloc(cur_text_section, sym, 
-               ind + 1, R_386_PC32);
-        oad(0xe8, -4);
+        gen_static_call(TOK___bound_local_delete);
         o(0x585a); /* restore returned value, if any */
     }
 #endif
+
+    /* align local size to word & save local variables */
+    v = (-loc + 3) & -4;
+
+#if USE_EBX
+    o(0x8b);
+    gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
+#endif
+
     o(0xc9); /* leave */
     if (func_ret_sub == 0) {
@@ -589,15 +652,10 @@
         g(func_ret_sub >> 8);
     }
-    /* align local size to word & save local variables */
-    
-    v = (-loc + 3) & -4; 
     saved_ind = ind;
     ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
 #ifdef TCC_TARGET_PE
     if (v >= 4096) {
-        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
         oad(0xb8, v); /* mov stacksize, %eax */
-        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
-        greloc(cur_text_section, sym, ind-4, R_386_PC32);
+        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
     } else
 #endif
@@ -606,8 +664,9 @@
         o(0xec81);  /* sub esp, stacksize */
         gen_le32(v);
-#if FUNC_PROLOG_SIZE == 10
+#ifdef TCC_TARGET_PE
         o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
 #endif
     }
+    o(0x53 * USE_EBX); /* push ebx */
     ind = saved_ind;
 }
@@ -616,5 +675,5 @@
 ST_FUNC int gjmp(int t)
 {
-    return psym(0xe9, t);
+    return gjmp2(0xe9, t);
 }
 
@@ -632,43 +691,54 @@
 }
 
+ST_FUNC void gtst_addr(int inv, int a)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+	inv ^= (vtop--)->c.i;
+	a -= ind + 2;
+	if (a == (char)a) {
+	    g(inv - 32);
+	    g(a);
+	} else {
+	    g(0x0f);
+	    oad(inv - 16, a - 4);
+	}
+    } else if ((v & ~1) == VT_JMP) {
+	if ((v & 1) != inv) {
+	    gjmp_addr(a);
+	    gsym(vtop->c.i);
+	} else {
+	    gsym(vtop->c.i);
+	    o(0x05eb);
+	    gjmp_addr(a);
+	}
+	vtop--;
+    }
+}
+
 /* generate a test. set 'inv' to invert test. Stack entry is popped */
 ST_FUNC int gtst(int inv, int t)
 {
-    int v, *p;
-
-    v = vtop->r & VT_VALMASK;
-    if (v == VT_CMP) {
+    int v = vtop->r & VT_VALMASK;
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
         /* fast case : can jump directly since flags are set */
         g(0x0f);
-        t = psym((vtop->c.i - 16) ^ inv, t);
+        t = gjmp2((vtop->c.i - 16) ^ inv, t);
     } else if (v == VT_JMP || v == VT_JMPI) {
         /* && or || optimization */
         if ((v & 1) == inv) {
             /* insert vtop->c jump list in t */
-            p = &vtop->c.i;
-            while (*p != 0)
-                p = (int *)(cur_text_section->data + *p);
-            *p = t;
-            t = vtop->c.i;
+            uint32_t n1, n = vtop->c.i;
+            if (n) {
+                while ((n1 = read32le(cur_text_section->data + n)))
+                    n = n1;
+                write32le(cur_text_section->data + n, t);
+                t = vtop->c.i;
+            }
         } else {
             t = gjmp(t);
             gsym(vtop->c.i);
-        }
-    } else {
-        if (is_float(vtop->type.t) || 
-            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
-            vpushi(0);
-            gen_op(TOK_NE);
-        }
-        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-            /* constant jmp optimization */
-            if ((vtop->c.i != 0) != inv) 
-                t = gjmp(t);
-        } else {
-            v = gv(RC_INT);
-            o(0x85);
-            o(0xc0 + v * 9);
-            g(0x0f);
-            t = psym(0x85 ^ inv, t);
         }
     }
@@ -695,7 +765,7 @@
             if (c == (char)c) {
                 /* generate inc and dec for smaller code */
-                if (c==1 && opc==0) {
+                if (c==1 && opc==0 && op != TOK_ADDC1) {
                     o (0x40 | r); // inc
-                } else if (c==1 && opc==5) {
+                } else if (c==1 && opc==5 && op != TOK_SUBC1) {
                     o (0x48 | r); // dec
                 } else {
@@ -789,4 +859,6 @@
         vtop--;
         save_reg(TREG_EDX);
+        /* save EAX too if used otherwise */
+        save_reg_upstack(TREG_EAX, 1);
         if (op == TOK_UMULL) {
             o(0xf7); /* mul fr */
@@ -816,5 +888,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
-   two operands are guaranted to have the same floating point type */
+   two operands are guaranteed to have the same floating point type */
 /* XXX: need to use ST1 too */
 ST_FUNC void gen_opf(int op)
@@ -855,5 +927,8 @@
         if (swapped)
             o(0xc9d9); /* fxch %st(1) */
-        o(0xe9da); /* fucompp */
+        if (op == TOK_EQ || op == TOK_NE)
+            o(0xe9da); /* fucompp */
+        else
+            o(0xd9de); /* fcompp */
         o(0xe0df); /* fnstsw %ax */
         if (op == TOK_EQ) {
@@ -901,5 +976,5 @@
         }
         ft = vtop->type.t;
-        fc = vtop->c.ul;
+        fc = vtop->c.i;
         if ((ft & VT_BTYPE) == VT_LDOUBLE) {
             o(0xde); /* fxxxp %st, %st(1) */
@@ -913,5 +988,5 @@
                 v1.type.t = VT_INT;
                 v1.r = VT_LOCAL | VT_LVAL;
-                v1.c.ul = fc;
+                v1.c.i = fc;
                 load(r, &v1);
                 fc = 0;
@@ -959,53 +1034,18 @@
 
 /* convert fp to int 't' type */
-/* XXX: handle long long case */
 ST_FUNC void gen_cvt_ftoi(int t)
 {
-    int r, r2, size;
-    Sym *sym;
-    CType ushort_type;
-
-    ushort_type.t = VT_SHORT | VT_UNSIGNED;
-    ushort_type.ref = 0;
-
-    gv(RC_FLOAT);
-    if (t != VT_INT)
-        size = 8;
-    else 
-        size = 4;
-    
-    o(0x2dd9); /* ldcw xxx */
-    sym = external_global_sym(TOK___tcc_int_fpu_control, 
-                              &ushort_type, VT_LVAL);
-    greloc(cur_text_section, sym, 
-           ind, R_386_32);
-    gen_le32(0);
-    
-    oad(0xec81, size); /* sub $xxx, %esp */
-    if (size == 4)
-        o(0x1cdb); /* fistpl */
+    int bt = vtop->type.t & VT_BTYPE;
+    if (bt == VT_FLOAT)
+        vpush_global_sym(&func_old_type, TOK___fixsfdi);
+    else if (bt == VT_LDOUBLE)
+        vpush_global_sym(&func_old_type, TOK___fixxfdi);
     else
-        o(0x3cdf); /* fistpll */
-    o(0x24);
-    o(0x2dd9); /* ldcw xxx */
-    sym = external_global_sym(TOK___tcc_fpu_control, 
-                              &ushort_type, VT_LVAL);
-    greloc(cur_text_section, sym, 
-           ind, R_386_32);
-    gen_le32(0);
-
-    r = get_reg(RC_INT);
-    o(0x58 + r); /* pop r */
-    if (size == 8) {
-        if (t == VT_LLONG) {
-            vtop->r = r; /* mark reg as used */
-            r2 = get_reg(RC_INT);
-            o(0x58 + r2); /* pop r2 */
-            vtop->r2 = r2;
-        } else {
-            o(0x04c483); /* add $4, %esp */
-        }
-    }
-    vtop->r = r;
+        vpush_global_sym(&func_old_type, TOK___fixdfdi);
+    vswap();
+    gfunc_call(1);
+    vpushi(0);
+    vtop->r = REG_IRET;
+    vtop->r2 = REG_LRET;
 }
 
@@ -1030,6 +1070,4 @@
 ST_FUNC void gen_bounded_ptr_add(void)
 {
-    Sym *sym;
-
     /* prepare fast i386 function call (args in eax and edx) */
     gv2(RC_EAX, RC_EDX);
@@ -1038,13 +1076,10 @@
     save_regs(0);
     /* do a fast function call */
-    sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
-    greloc(cur_text_section, sym, 
-           ind + 1, R_386_PC32);
-    oad(0xe8, -4);
+    gen_static_call(TOK___bound_ptr_add);
     /* returned pointer is in eax */
     vtop++;
     vtop->r = TREG_EAX | VT_BOUNDED;
     /* address of bounding function call point */
-    vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
+    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
 }
 
@@ -1053,6 +1088,6 @@
 ST_FUNC void gen_bounded_ptr_deref(void)
 {
-    int func;
-    int size, align;
+    addr_t func;
+    int  size, align;
     Elf32_Rel *rel;
     Sym *sym;
@@ -1083,5 +1118,5 @@
     /* patch relocation */
     /* XXX: find a better solution ? */
-    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
+    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
     sym = external_global_sym(func, &func_old_type, 0);
     if (!sym->c)
@@ -1091,4 +1126,37 @@
 #endif
 
+/* Save the stack pointer onto the stack */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    /* mov %esp,addr(%ebp)*/
+    o(0x89);
+    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    o(0x8b);
+    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+    /* alloca does more than just adjust %rsp on Windows */
+    vpush_global_sym(&func_old_type, TOK_alloca);
+    vswap(); /* Move alloca ref past allocation size */
+    gfunc_call(1);
+#else
+    int r;
+    r = gv(RC_INT); /* allocation size */
+    /* sub r,%rsp */
+    o(0x2b);
+    o(0xe0 | r);
+    /* We align to 16 bytes rather than align */
+    /* and ~15, %esp */
+    o(0xf0e483);
+    vpop();
+#endif
+}
+
 /* end of X86 code generator */
 /*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c	(revision 331)
@@ -0,0 +1,247 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_386
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_386_32
+#define R_DATA_PTR  R_386_32
+#define R_JMP_SLOT  R_386_JMP_SLOT
+#define R_GLOB_DAT  R_386_GLOB_DAT
+#define R_COPY      R_386_COPY
+#define R_RELATIVE  R_386_RELATIVE
+
+#define R_NUM       R_386_NUM
+
+#define ELF_START_ADDR 0x08048000
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_386_RELATIVE:
+	case R_386_16:
+        case R_386_32:
+	case R_386_GOTPC:
+	case R_386_GOTOFF:
+	case R_386_GOT32:
+	case R_386_GOT32X:
+	case R_386_GLOB_DAT:
+	case R_386_COPY:
+            return 0;
+
+	case R_386_PC16:
+	case R_386_PC32:
+	case R_386_PLT32:
+	case R_386_JMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_386_RELATIVE:
+	case R_386_16:
+	case R_386_GLOB_DAT:
+	case R_386_JMP_SLOT:
+	case R_386_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_386_32:
+	    /* This relocations shouldn't normally need GOT or PLT
+	       slots if it weren't for simplicity in the code generator.
+	       See our caller for comments.  */
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_386_PC16:
+	case R_386_PC32:
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_386_GOTPC:
+	case R_386_GOTOFF:
+            return BUILD_GOT_ONLY;
+
+	case R_386_GOT32:
+	case R_386_GOT32X:
+	case R_386_PLT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    int modrm;
+    unsigned plt_offset, relofs;
+
+    /* on i386 if we build a DLL, we add a %ebx offset */
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        modrm = 0xa3;
+    else
+        modrm = 0x25;
+
+    /* empty PLT: create PLT0 entry that pushes the library identifier
+       (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+       (GOT + 2 * PTR_SIZE) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 16);
+        p[0] = 0xff; /* pushl got + PTR_SIZE */
+        p[1] = modrm + 0x10;
+        write32le(p + 2, PTR_SIZE);
+        p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+        p[7] = modrm;
+        write32le(p + 8, PTR_SIZE * 2);
+    }
+    plt_offset = plt->data_offset;
+
+    /* The PLT slot refers to the relocation entry it needs via offset.
+       The reloc entry is created below, so its offset is the current
+       data_offset */
+    relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+    /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+    p = section_ptr_add(plt, 16);
+    p[0] = 0xff; /* jmp *(got + x) */
+    p[1] = modrm;
+    write32le(p + 2, got_offset);
+    p[6] = 0x68; /* push $xxx */
+    write32le(p + 7, relofs);
+    p[11] = 0xe9; /* jmp plt_start */
+    write32le(p + 12, -(plt->data_offset));
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        add32le(p + 2, s1->got->sh_addr);
+        add32le(p + 8, s1->got->sh_addr);
+        p += 16;
+        while (p < p_end) {
+            add32le(p + 2, s1->got->sh_addr);
+            p += 16;
+        }
+    }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+    qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index, esym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+
+    switch (type) {
+        case R_386_32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                qrel->r_offset = rel->r_offset;
+                if (esym_index) {
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
+                    qrel++;
+                    return;
+                } else {
+                    qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
+                    qrel++;
+                }
+            }
+            add32le(ptr, val);
+            return;
+        case R_386_PC32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
+                    qrel++;
+                    return;
+                }
+            }
+            add32le(ptr, val - addr);
+            return;
+        case R_386_PLT32:
+            add32le(ptr, val - addr);
+            return;
+        case R_386_GLOB_DAT:
+        case R_386_JMP_SLOT:
+            write32le(ptr, val);
+            return;
+        case R_386_GOTPC:
+            add32le(ptr, s1->got->sh_addr - addr);
+            return;
+        case R_386_GOTOFF:
+            add32le(ptr, val - s1->got->sh_addr);
+            return;
+        case R_386_GOT32:
+        case R_386_GOT32X:
+            /* we load the got offset */
+            add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+            return;
+        case R_386_16:
+            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
+            output_file:
+                tcc_error("can only produce 16-bit binary files");
+            }
+            write16le(ptr, read16le(ptr) + val);
+            return;
+        case R_386_PC16:
+            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
+                goto output_file;
+            write16le(ptr, read16le(ptr) + val - addr);
+            return;
+        case R_386_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        case R_386_COPY:
+            /* This relocation must copy initialized data from the library
+            to the program .bss segment. Currently made like for ARM
+            (to remove noise of default case). Is this true?
+            */
+            return;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
+                type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/i386-tok.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h	(revision 331)
@@ -92,5 +92,14 @@
  DEF_ASM(gs)
  DEF_ASM(st)
-
+ DEF_ASM(rip)
+
+#ifdef TCC_TARGET_X86_64
+ /* The four low parts of sp/bp/si/di that exist only on
+    x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */
+ DEF_ASM(spl)
+ DEF_ASM(bpl)
+ DEF_ASM(sil)
+ DEF_ASM(dil)
+#endif
  /* generic two operands */
  DEF_BWLX(mov)
@@ -127,10 +136,6 @@
  DEF_BWLX(sar)
 
- DEF_ASM(shldw)
- DEF_ASM(shldl)
- DEF_ASM(shld)
- DEF_ASM(shrdw)
- DEF_ASM(shrdl)
- DEF_ASM(shrd)
+ DEF_WLX(shld)
+ DEF_WLX(shrd)
 
  DEF_ASM(pushw)
@@ -151,5 +156,5 @@
  DEF_BWL(out)
 
- DEF_WL(movzb)
+ DEF_WLX(movzb)
  DEF_ASM(movzwl)
  DEF_ASM(movsbw)
@@ -157,4 +162,7 @@
  DEF_ASM(movswl)
 #ifdef TCC_TARGET_X86_64
+ DEF_ASM(movsbq)
+ DEF_ASM(movswq)
+ DEF_ASM(movzwq)
  DEF_ASM(movslq)
 #endif
@@ -173,8 +181,9 @@
  DEF_ASM(ljmp)
 
- DEF_ASMTEST(j)
-
- DEF_ASMTEST(set)
- DEF_ASMTEST(cmov)
+ DEF_ASMTEST(j,)
+
+ DEF_ASMTEST(set,)
+ DEF_ASMTEST(set,b)
+ DEF_ASMTEST(cmov,)
 
  DEF_WLX(bsf)
@@ -185,4 +194,5 @@
  DEF_WLX(btc)
 
+ DEF_WLX(lar)
  DEF_WLX(lsl)
 
@@ -192,5 +202,5 @@
 
  DEF_ASM(fcom)
- DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
+ DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
  DEF_FP1(com)
 
Index: EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/il-gen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c	(revision 331)
@@ -18,17 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifdef TARGET_DEFS_ONLY
+
+#error this code has bit-rotted since 2003
 
 /* number of available registers */
 #define NB_REGS             3
-#define NB_ASM_REGS         8 // TODO:
-#define ELF_PAGE_SIZE  0x1000 // TODO:
-#define MAX_ALIGN           8 // TODO:
-#define R_DATA_32   R_386_32 // TODO:
-#define R_DATA_PTR  R_386_32 // TODO:
-#define R_JMP_SLOT  R_386_JMP_SLOT // TODO:
-#define R_COPY      R_386_COPY // TODO:
-#define ELF_START_ADDR 0x08048000 // TODO:
-#define EM_TCC_TARGET 0xFF // TODO:
 
 /* a register can belong to several classes. The classes must be
@@ -52,4 +44,10 @@
 };
 
+const int reg_classes[NB_REGS] = {
+    /* ST0 */ RC_ST | RC_ST0,
+    /* ST1 */ RC_ST | RC_ST1,
+    /* ST2 */ RC_ST,
+};
+
 /* return registers for function */
 #define REG_IRET REG_ST0 /* single word int return register */
@@ -58,9 +56,9 @@
 
 /* defined if function parameters must be evaluated in reverse order */
-//#define INVERT_FUNC_PARAMS
+/* #define INVERT_FUNC_PARAMS */
 
 /* defined if structures are passed as pointers. Otherwise structures
    are directly pushed on stack. */
-//#define FUNC_STRUCT_PARAM_AS_PTR
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
 
 /* pointer size, in bytes */
@@ -82,24 +80,11 @@
 
 enum ILOPCodes {
-#define ENUM_ILOPCODES_DEF
 #define OP(name, str, n) IL_OP_ ## name = n,
 #include "il-opcodes.h"
 #undef OP
-#undef ENUM_ILOPCODES_DEF
 };
 
-/******************************************************/
-#else /* ! TARGET_DEFS_ONLY */
- /******************************************************/
-#include "tcc.h"
-
-const int reg_classes[NB_REGS] = {
-	/* ST0 */ RC_ST | RC_ST0,
-	/* ST1 */ RC_ST | RC_ST1,
-	/* ST2 */ RC_ST,
-};
-
 char *il_opcodes_str[] = {
-#define OP(name, str, n) /*[n] = */str,
+#define OP(name, str, n) [n] = str,
 #include "il-opcodes.h"
 #undef OP
@@ -115,9 +100,5 @@
 static void out_byte(int c)
 {
-    int ind1 = ind + 1;
-    if (ind1 > cur_text_section->data_allocated)
-        section_realloc(cur_text_section, ind1);
-    *(char *)(cur_text_section->data + ind) = c;
-    ind++;
+    *(char *)ind++ = c;
 }
 
@@ -219,11 +200,9 @@
     case VT_FUNC:
         s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
-        if (s == NULL)
-            break;
-        il_type_to_str(buf, buf_size, s->type.t, varstr);
+        il_type_to_str(buf, buf_size, s->t, varstr);
         pstrcat(buf, buf_size, "(");
         sa = s->next;
         while (sa != NULL) {
-            il_type_to_str(buf1, sizeof(buf1), sa->type.t, NULL);
+            il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
             pstrcat(buf, buf_size, buf1);
             sa = sa->next;
@@ -235,10 +214,8 @@
     case VT_PTR:
         s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
-        if (s == NULL)
-            break;
         pstrcpy(buf1, sizeof(buf1), "*");
         if (varstr)
             pstrcat(buf1, sizeof(buf1), varstr);
-        il_type_to_str(buf, buf_size, s->type.t, buf1);
+        il_type_to_str(buf, buf_size, s->t, buf1);
         goto no_var;
     }
@@ -250,5 +227,5 @@
 }
 
-#define Reloc void
+
 /* patch relocation entry with value 'val' */
 void greloc_patch1(Reloc *p, int val)
@@ -285,5 +262,5 @@
     v = sv->r & VT_VALMASK;
     fc = sv->c.i;
-    ft = sv->type.t;
+    ft = sv->t;
 
     if (sv->r & VT_LVAL) {
@@ -364,5 +341,5 @@
     v = sv->r & VT_VALMASK;
     fc = sv->c.i;
-    ft = sv->type.t;
+    ft = sv->t;
     if (v == VT_LOCAL) {
         if (fc >= ARG_BASE) {
@@ -412,5 +389,5 @@
 void gfunc_param(GFuncContext *c)
 {
-    if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+    if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
         tcc_error("structures passed as value not handled yet");
     } else {
@@ -429,10 +406,10 @@
     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
         /* XXX: more info needed from tcc */
-        il_type_to_str(buf, sizeof(buf), vtop->type.t, "xxx");
+        il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
         fprintf(il_outfile, " call %s\n", buf);
     } else {
         /* indirect call */
         gv(RC_INT);
-        il_type_to_str(buf, sizeof(buf), vtop->type.t, NULL);
+        il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
         fprintf(il_outfile, " calli %s\n", buf);
     }
@@ -461,12 +438,12 @@
         
     sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
-    if (sym == NULL)
-        return;
+    func_call = sym->r;
 
     addr = ARG_BASE;
     /* if the function returns a structure, then add an
        implicit pointer parameter */
-    func_vt = sym->type;
-    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+    func_vt = sym->t;
+    func_var = (sym->c == FUNC_ELLIPSIS);
+    if ((func_vt & VT_BTYPE) == VT_STRUCT) {
         func_vc = addr;
         addr++;
@@ -474,5 +451,5 @@
     /* define parameters */
     while ((sym = sym->next) != NULL) {
-        u = sym->type.t;
+        u = sym->t;
         sym_push(sym->v & ~SYM_FIELD, u,
                  VT_LOCAL | lvalue_type(sym->type.t), addr);
@@ -555,18 +532,4 @@
             gsym(vtop->c.i);
         }
-    } else {
-        if (is_float(vtop->type.t)) {
-            vpushi(0);
-            gen_op(TOK_NE);
-        }
-#define VT_FORWARD 0
-        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
-            /* constant jmp optimization */
-            if ((vtop->c.i != 0) != inv) 
-                t = gjmp(t);
-        } else {
-            v = gv(RC_INT);
-            t = out_opj(IL_OP_BRTRUE - inv, t);
-        }
     }
     vtop--;
@@ -640,5 +603,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
-   two operands are guaranted to have the same floating point type */
+   two operands are guaranteed to have the same floating point type */
 void gen_opf(int op)
 {
@@ -690,26 +653,5 @@
 }
 
-void ggoto(void) { }
-void gen_bounded_ptr_add(void) {}
-void gen_bounded_ptr_deref(int t) {}
-void gen_expr32(void) {}
-void asm_opcode(TCCState *s1, int opcode) {}
-void asm_compute_constraints(ASMOperand *operands,
-	int nb_operands, int nb_outputs,
-	const uint8_t *clobber_regs,
-	int *pout_reg) {}
-void subst_asm_operand(CString *add_str,
-	SValue *sv, int modifier) {}
-void asm_gen_code(ASMOperand *operands, int nb_operands,
-	int nb_outputs, int is_output,
-	uint8_t *clobber_regs,
-	int out_reg) {}
-void asm_clobber(uint8_t *clobber_regs, const char *str) {}
-void gen_le32(int c) {}
-void g(int c) {}
-void gen_le16(int v) {}
-
 /* end of CIL code generator */
 /*************************************************************/
-#endif
-/*************************************************************/
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/il-opcodes.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h	(revision 331)
@@ -138,7 +138,4 @@
 OP(CONV_R_UN, "conv.r.un", 0x76)
 OP(ANN_DATA_S, "ann.data.s", 0x77)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0x78)
-#endif
 OP(UNBOX, "unbox", 0x79)
 OP(THROW, "throw", 0x7a)
@@ -183,22 +180,4 @@
 OP(STELEM_R8, "stelem.r8", 0xa1)
 OP(STELEM_REF, "stelem.ref", 0xa2)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0xa3)
-OP(0, NULL, 0xa4)
-OP(0, NULL, 0xa5)
-OP(0, NULL, 0xa6)
-OP(0, NULL, 0xa7)
-OP(0, NULL, 0xa8)
-OP(0, NULL, 0xa9)
-OP(0, NULL, 0xaa)
-OP(0, NULL, 0xab)
-OP(0, NULL, 0xac)
-OP(0, NULL, 0xad)
-OP(0, NULL, 0xae)
-OP(0, NULL, 0xaf)
-OP(0, NULL, 0xb0)
-OP(0, NULL, 0xb1)
-OP(0, NULL, 0xb2)
-#endif
 OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
 OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
@@ -209,19 +188,6 @@
 OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
 OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0xbb)
-OP(0, NULL, 0xbc)
-OP(0, NULL, 0xbd)
-OP(0, NULL, 0xbe)
-OP(0, NULL, 0xbf)
-OP(0, NULL, 0xc0)
-OP(0, NULL, 0xc1)
-#endif
 OP(REFANYVAL, "refanyval", 0xc2)
 OP(CKFINITE, "ckfinite", 0xc3)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0xc4)
-OP(0, NULL, 0xc5)
-#endif
 OP(MKREFANY, "mkrefany", 0xc6)
 OP(ANN_CALL, "ann.call", 0xc7)
@@ -251,37 +217,4 @@
 OP(STIND_I, "stind.i", 0xdf)
 OP(CONV_U, "conv.u", 0xe0)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0xe1)
-OP(0, NULL, 0xe2)
-OP(0, NULL, 0xe3)
-OP(0, NULL, 0xe4)
-OP(0, NULL, 0xe5)
-OP(0, NULL, 0xe6)
-OP(0, NULL, 0xe7)
-OP(0, NULL, 0xe8)
-OP(0, NULL, 0xe9)
-OP(0, NULL, 0xea)
-OP(0, NULL, 0xeb)
-OP(0, NULL, 0xec)
-OP(0, NULL, 0xed)
-OP(0, NULL, 0xee)
-OP(0, NULL, 0xef)
-OP(0, NULL, 0xf0)
-OP(0, NULL, 0xf1)
-OP(0, NULL, 0xf2)
-OP(0, NULL, 0xf3)
-OP(0, NULL, 0xf4)
-OP(0, NULL, 0xf5)
-OP(0, NULL, 0xf6)
-OP(0, NULL, 0xf7)
-OP(0, NULL, 0xf8)
-OP(0, NULL, 0xf9)
-OP(0, NULL, 0xfa)
-OP(0, NULL, 0xfb)
-OP(0, NULL, 0xfc)
-OP(0, NULL, 0xfd)
-OP(0, NULL, 0xfe)
-OP(0, NULL, 0xff)
-#endif
 
 /* prefix instructions. we use an opcode >= 256 to ease coding */
@@ -303,7 +236,4 @@
 OP(STLOC, "stloc", 0x10e)
 OP(LOCALLOC, "localloc", 0x10f)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0x110)
-#endif
 OP(ENDFILTER, "endfilter", 0x111)
 OP(UNALIGNED, "unaligned", 0x112)
@@ -316,15 +246,6 @@
 OP(ANN_REF, "ann.ref", 0x119)
 OP(RETHROW, "rethrow", 0x11a)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0x11b)
-#endif
 OP(SIZEOF, "sizeof", 0x11c)
 OP(REFANYTYPE, "refanytype", 0x11d)
-#ifndef ENUM_ILOPCODES_DEF
-OP(0, NULL, 0x11e)
-OP(0, NULL, 0x11f)
-OP(0, NULL, 0x120)
-OP(0, NULL, 0x121)
-#endif
 OP(ANN_DATA, "ann.data", 0x122)
 OP(ANN_ARG, "ann.arg", 0x123)
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/float.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/include/float.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/float.h	(revision 331)
@@ -28,5 +28,5 @@
 
 /* horrible intel long double */
-#ifdef __i386__
+#if defined __i386__ || defined __x86_64__
 
 #define LDBL_MANT_DIG 64
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/include/stdarg.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h	(revision 331)
@@ -5,24 +5,62 @@
 #ifndef _WIN64
 
-typedef void *va_list;
+//This should be in sync with the declaration on our lib/libtcc1.c
+/* GCC compatible definition of va_list. */
+typedef struct {
+    unsigned int gp_offset;
+    unsigned int fp_offset;
+    union {
+        unsigned int overflow_offset;
+        char *overflow_arg_area;
+    };
+    char *reg_save_area;
+} __va_list_struct;
 
-va_list __va_start(void *fp);
-void *__va_arg(va_list ap, int arg_type, int size);
-va_list __va_copy(va_list src);
-void __va_end(va_list ap);
+typedef __va_list_struct va_list[1];
 
-#define va_start(ap, last) ((ap) = __va_start(__builtin_frame_address(0)))
+void __va_start(__va_list_struct *ap, void *fp);
+void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
+
+#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0))
 #define va_arg(ap, type)                                                \
-    (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type))))
-#define va_copy(dest, src) ((dest) = __va_copy(src))
-#define va_end(ap) __va_end(ap)
+    (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type))))
+#define va_copy(dest, src) (*(dest) = *(src))
+#define va_end(ap)
+
+/* avoid conflicting definition for va_list on Macs. */
+#define _VA_LIST_T
 
 #else /* _WIN64 */
 typedef char *va_list;
-#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+7)&~7)
-#define va_arg(ap,type) (ap += (sizeof(type)+7)&~7, *(type *)(ap - ((sizeof(type)+7)&~7)))
+#define va_start(ap,last) __builtin_va_start(ap,last)
+#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
+	? **(t **)((ap += 8) - 8) : *(t  *)((ap += 8) - 8))
+#define va_copy(dest, src) ((dest) = (src))
+#define va_end(ap)
+#endif
+
+#elif __arm__
+typedef char *va_list;
+#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
+#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
+                               & ~(_tcc_alignof(type) - 1))
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
+                        &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
 #define va_copy(dest, src) (dest) = (src)
 #define va_end(ap)
-#endif
+
+#elif defined(__aarch64__)
+typedef struct {
+    void *__stack;
+    void *__gr_top;
+    void *__vr_top;
+    int   __gr_offs;
+    int   __vr_offs;
+} va_list;
+#define va_start(ap, last) __va_start(ap, last)
+#define va_arg(ap, type) __va_arg(ap, type)
+#define va_end(ap)
+#define va_copy(dest, src) ((dest) = (src))
 
 #else /* __i386__ */
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/include/stdbool.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h	(revision 331)
@@ -7,4 +7,5 @@
 #define true	1
 #define false	0
+#define __bool_true_false_are_defined 1
 
 #endif /* _STDBOOL_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/include/stddef.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h	(revision 331)
@@ -14,12 +14,23 @@
 typedef signed short int int16_t;
 typedef signed int int32_t;
+#ifdef __LP64__
+typedef signed long int int64_t;
+#else
 typedef signed long long int int64_t;
+#endif
 typedef unsigned char uint8_t;
 typedef unsigned short int uint16_t;
 typedef unsigned int uint32_t;
+#ifdef __LP64__
+typedef unsigned long int uint64_t;
+#else
 typedef unsigned long long int uint64_t;
 #endif
+#endif
 
+#ifndef NULL
 #define NULL ((void*)0)
+#endif
+
 #define offsetof(type, field) ((size_t)&((type *)0)->field)
 
@@ -27,2 +38,17 @@
 
 #endif
+
+/* Older glibc require a wint_t from <stddef.h> (when requested
+   by __need_wint_t, as otherwise stddef.h isn't allowed to
+   define this type).   Note that this must be outside the normal
+   _STDDEF_H guard, so that it works even when we've included the file
+   already (without requiring wint_t).  Some other libs define _WINT_T
+   if they've already provided that type, so we can use that as guard.
+   TCC defines __WINT_TYPE__ for us.  */
+#if defined (__need_wint_t)
+#ifndef _WINT_T
+#define _WINT_T
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/tcclib.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/include/tcclib.h	(revision 321)
+++ 	(revision )
@@ -1,78 +1,0 @@
-/* Simple libc header for TCC 
- * 
- * Add any function you want from the libc there. This file is here
- * only for your convenience so that you do not need to put the whole
- * glibc include files on your floppy disk 
- */
-#ifndef _TCCLIB_H
-#define _TCCLIB_H
-
-#include <stddef.h>
-#include <stdarg.h>
-
-/* stdlib.h */
-void *calloc(size_t nmemb, size_t size);
-void *malloc(size_t size);
-void free(void *ptr);
-void *realloc(void *ptr, size_t size);
-int atoi(const char *nptr);
-long int strtol(const char *nptr, char **endptr, int base);
-unsigned long int strtoul(const char *nptr, char **endptr, int base);
-void exit(int);
-
-/* stdio.h */
-typedef struct __FILE FILE;
-#define EOF (-1)
-extern FILE *stdin;
-extern FILE *stdout;
-extern FILE *stderr;
-FILE *fopen(const char *path, const char *mode);
-FILE *fdopen(int fildes, const char *mode);
-FILE *freopen(const  char *path, const char *mode, FILE *stream);
-int fclose(FILE *stream);
-size_t  fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
-size_t  fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
-int fgetc(FILE *stream);
-char *fgets(char *s, int size, FILE *stream);
-int getc(FILE *stream);
-int getchar(void);
-char *gets(char *s);
-int ungetc(int c, FILE *stream);
-int fflush(FILE *stream);
-
-int printf(const char *format, ...);
-int fprintf(FILE *stream, const char *format, ...);
-int sprintf(char *str, const char *format, ...);
-int snprintf(char *str, size_t size, const  char  *format, ...);
-int asprintf(char **strp, const char *format, ...);
-int dprintf(int fd, const char *format, ...);
-int vprintf(const char *format, va_list ap);
-int vfprintf(FILE  *stream,  const  char *format, va_list ap);
-int vsprintf(char *str, const char *format, va_list ap);
-int vsnprintf(char *str, size_t size, const char  *format, va_list ap);
-int vasprintf(char  **strp,  const  char *format, va_list ap);
-int vdprintf(int fd, const char *format, va_list ap);
-
-void perror(const char *s);
-
-/* string.h */
-char *strcat(char *dest, const char *src);
-char *strchr(const char *s, int c);
-char *strrchr(const char *s, int c);
-char *strcpy(char *dest, const char *src);
-void *memcpy(void *dest, const void *src, size_t n);
-void *memmove(void *dest, const void *src, size_t n);
-void *memset(void *s, int c, size_t n);
-char *strdup(const char *s);
-
-/* dlfcn.h */
-#define RTLD_LAZY       0x001
-#define RTLD_NOW        0x002
-#define RTLD_GLOBAL     0x100
-
-void *dlopen(const char *filename, int flag);
-const char *dlerror(void);
-void *dlsym(void *handle, char *symbol);
-int dlclose(void *handle);
-
-#endif /* _TCCLIB_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile	(revision 331)
@@ -5,98 +5,69 @@
 TOP = ..
 include $(TOP)/Makefile
-VPATH = $(top_srcdir)/lib $(top_srcdir)/win32/lib
+VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+BIN = $(TOP)/$(X)libtcc1.a
 
-ifndef TARGET
- ifdef CONFIG_WIN64
-  TARGET = x86_64-win32
- else
- ifdef CONFIG_WIN32
-  TARGET = i386-win32
- else
- ifeq ($(ARCH),i386)
-  TARGET = i386
-  ifneq ($(TARGETOS),Darwin)
-   XCC = $(CC)
-  endif
- else
- ifeq ($(ARCH),x86-64)
-  TARGET = x86_64
-  ifneq ($(TARGETOS),Darwin)
-   XCC = $(CC)
-  endif
- endif
- endif
- endif
- endif
- BCHECK_O = bcheck.o
+XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
+XCC = $(XTCC)
+XAR = $(XTCC) -ar
+XFLAGS-unx = -B$(TOPSRC)
+XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
+XFLAGS = $(XFLAGS$(XCFG))
+XCFG = $(or $(findstring -win,$T),-unx)
+
+# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
+arm-libtcc1-usegcc ?= no
+
+ifeq "$($(T)-libtcc1-usegcc)" "yes"
+ XCC = $(CC)
+ XAR = $(AR)
+ XFLAGS = $(CFLAGS) -fPIC
 endif
 
-DIR = $(TARGET)
+# only for native compiler
+$(X)BCHECK_O = bcheck.o
 
-native : ../libtcc1.a
-cross : $(DIR)/libtcc1.a
-
-native : TCC = $(TOP)/tcc$(EXESUF)
-cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
-
-I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
-X86_64_O = libtcc1.o alloca86_64.o
-WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
-WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
-
-ifeq "$(TARGET)" "i386-win32"
- OBJ = $(addprefix $(DIR)/,$(WIN32_O))
- TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE
- XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
- XAR = $(DIR)/tiny_libmaker$(EXESUF)
-else
-ifeq "$(TARGET)" "x86_64-win32"
- OBJ = $(addprefix $(DIR)/,$(WIN64_O))
- TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
- XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
- XAR = $(DIR)/tiny_libmaker$(EXESUF)
-else
-ifeq "$(TARGET)" "i386"
- OBJ = $(addprefix $(DIR)/,$(I386_O))
- TGT = -DTCC_TARGET_I386
- XCC ?= $(TCC) -B$(TOP)
-else
-ifeq "$(TARGET)" "x86_64"
- OBJ = $(addprefix $(DIR)/,$(X86_64_O))
- TGT = -DTCC_TARGET_X86_64
- XCC ?= $(TCC) -B$(TOP)
-else
- $(error libtcc1.a not supported on target '$(TARGET)')
-endif
-endif
-endif
-endif
-
-XFLAGS = $(CPPFLAGS) $(CFLAGS) $(TGT)
-
-ifeq ($(TARGETOS),Darwin)
- XAR = $(DIR)/tiny_libmaker$(EXESUF)
- XFLAGS += -D_ANSI_SOURCE
+ifeq ($(CONFIG_musl)$(CONFIG_uClibc),yes)
  BCHECK_O =
 endif
 
-ifdef XAR
-AR = $(XAR)
+ifdef CONFIG_OSX
+ XFLAGS += -D_ANSI_SOURCE
 endif
 
-$(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
-	$(AR) rcs $@ $(OBJ)
-$(DIR)/%.o : %.c
+I386_O = libtcc1.o alloca86.o alloca86-bt.o
+X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
+ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
+ARM64_O = lib-arm64.o
+WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
+
+OBJ-i386 = $(I386_O) $(BCHECK_O)
+OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
+OBJ-x86_64-osx = $(X86_64_O) va_list.o
+OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-arm64 = $(ARM64_O)
+OBJ-arm = $(ARM_O)
+OBJ-arm-fpa = $(ARM_O)
+OBJ-arm-fpa-ld = $(ARM_O)
+OBJ-arm-vfp = $(ARM_O)
+OBJ-arm-eabi = $(ARM_O)
+OBJ-arm-eabihf = $(ARM_O)
+OBJ-arm-wince = $(ARM_O) $(WIN_O)
+
+$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
+	$(XAR) rcs $@ $^
+
+$(X)%.o : %.c
 	$(XCC) -c $< -o $@ $(XFLAGS)
-$(DIR)/%.o : %.S
+
+$(X)%.o : %.S
 	$(XCC) -c $< -o $@ $(XFLAGS)
-$(DIR)/%$(EXESUF) : $(TOP)/win32/tools/%.c
-	$(CC) -o $@ $< $(XFLAGS) $(LDFLAGS)
 
-$(OBJ) $(XAR) : $(DIR)/exists
-$(DIR)/exists :
-	mkdir -p $(DIR)
-	@echo $@ > $@
+$(X)crt1w.o : crt1.c
+$(X)wincrt1w.o : wincrt1.c
 
 clean :
-	rm -rfv i386-win32 x86_64-win32 i386 x86_64
+	rm -f *.a *.o $(BIN)
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S	(revision 331)
@@ -0,0 +1,17 @@
+	.text
+	.align	2
+	.global	alloca
+	.type	alloca, %function
+alloca:
+#ifdef __TINYC__
+        .int 0xe060d00d
+        .int 0xe3cdd007
+        .int 0xe1a0000d
+        .int 0xe1a0f00e
+#else
+	rsb	sp, r0, sp
+	bic	sp, sp, #7
+	mov	r0, sp
+	mov	pc, lr
+#endif
+	.size	alloca, .-alloca
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/alloca86-bt.S	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S	(revision 331)
@@ -12,11 +12,11 @@
     jz      p6
 
-#ifdef TCC_TARGET_PE
+#ifdef _WIN32
 p4:
     cmp     $4096,%eax
-    jle     p5
+    jbe     p5
+    test    %eax,-4096(%esp)
     sub     $4096,%esp
     sub     $4096,%eax
-    test    %eax,(%esp)
     jmp p4
 
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/alloca86.S	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S	(revision 331)
@@ -11,11 +11,11 @@
     jz      p3
 
-#ifdef TCC_TARGET_PE
+#ifdef _WIN32
 p1:
     cmp     $4096,%eax
-    jle     p2
+    jbe     p2
+    test    %eax,-4096(%esp)
     sub     $4096,%esp
     sub     $4096,%eax
-    test    %eax,(%esp)
     jmp p1
 p2:
@@ -29,7 +29,3 @@
     ret
 
-/* mark stack as nonexecutable */
-#if defined __ELF__ && defined __linux__
-    .section    .note.GNU-stack,"",@progbits
-#endif
 /* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S	(revision 331)
@@ -0,0 +1,56 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl __bound_alloca
+__bound_alloca:
+
+#ifdef _WIN32
+    # bound checking is not implemented
+    pop     %rdx
+    mov     %rcx,%rax
+    add     $15,%rax
+    and     $-16,%rax
+    jz      p3
+
+p1:
+    cmp     $4096,%rax
+    jbe     p2
+    test    %rax,-4096(%rsp)
+    sub     $4096,%rsp
+    sub     $4096,%rax
+    jmp p1
+p2:
+
+    sub     %rax,%rsp
+    mov     %rsp,%rax
+    add     $32,%rax
+
+p3:
+    push    %rdx
+    ret
+#else
+    pop     %rdx
+    mov     %rdi,%rax
+    mov     %rax,%rsi	# size, a second parm to the __bound_new_region
+
+    add     $15,%rax
+    and     $-16,%rax
+    jz      p3
+
+
+    sub     %rax,%rsp
+    mov     %rsp,%rdi	# pointer, a first parm to the __bound_new_region
+    mov     %rsp,%rax
+
+    push    %rdx
+    push    %rax
+    call   __bound_new_region
+    pop     %rax
+    pop     %rdx
+
+p3:
+    push    %rdx
+    ret
+#endif
+
+/* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/alloca86_64.S	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S	(revision 331)
@@ -6,5 +6,5 @@
 alloca:
     pop     %rdx
-#ifdef TCC_TARGET_PE
+#ifdef _WIN32
     mov     %rcx,%rax
 #else
@@ -15,11 +15,11 @@
     jz      p3
 
-#ifdef TCC_TARGET_PE
+#ifdef _WIN32
 p1:
     cmp     $4096,%rax
-    jle     p2
+    jbe     p2
+    test    %rax,-4096(%rsp)
     sub     $4096,%rsp
     sub     $4096,%rax
-    test    %rax,(%rsp)
     jmp p1
 p2:
@@ -28,15 +28,7 @@
     sub     %rax,%rsp
     mov     %rsp,%rax
-#ifdef TCC_TARGET_PE
-    add     $32,%rax
-#endif
-
 p3:
     push    %rdx
     ret
 
-/* mark stack as nonexecutable */
-#if defined __ELF__ && defined __linux__
-    .section    .note.GNU-stack,"",@progbits
-#endif
 /* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c	(revision 331)
@@ -0,0 +1,501 @@
+/* TCC ARM runtime EABI
+   Copyright (C) 2013 Thomas Preud'homme
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.*/
+
+#ifdef __TINYC__
+#define INT_MIN (-2147483647 - 1)
+#define INT_MAX 2147483647
+#define UINT_MAX 0xffffffff
+#define LONG_MIN (-2147483647L - 1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 0xffffffffUL
+#define LLONG_MAX 9223372036854775807LL
+#define LLONG_MIN (-9223372036854775807LL - 1)
+#define ULLONG_MAX 0xffffffffffffffffULL
+#else
+#include <limits.h>
+#endif
+
+/* We rely on the little endianness and EABI calling convention for this to
+   work */
+
+typedef struct double_unsigned_struct {
+    unsigned low;
+    unsigned high;
+} double_unsigned_struct;
+
+typedef struct unsigned_int_struct {
+    unsigned low;
+    int high;
+} unsigned_int_struct;
+
+#define REGS_RETURN(name, type) \
+    void name ## _return(type ret) {}
+
+
+/* Float helper functions */
+
+#define FLOAT_EXP_BITS 8
+#define FLOAT_FRAC_BITS 23
+
+#define DOUBLE_EXP_BITS 11
+#define DOUBLE_FRAC_BITS 52
+
+#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
+
+REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
+REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
+
+/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
+
+
+/* float to [unsigned] long long conversion */
+#define DEFINE__AEABI_F2XLZ(name, with_sign)                                 \
+void __aeabi_ ## name(unsigned val)                                          \
+{                                                                            \
+    int exp, high_shift, sign;                                               \
+    double_unsigned_struct ret;                                              \
+                                                                             \
+    /* compute sign */                                                       \
+    sign = val >> 31;                                                        \
+                                                                             \
+    /* compute real exponent */                                              \
+    exp = val >> FLOAT_FRAC_BITS;                                            \
+    exp &= (1 << FLOAT_EXP_BITS) - 1;                                        \
+    exp -= ONE_EXP(FLOAT);                                                   \
+                                                                             \
+    /* undefined behavior if truncated value cannot be represented */        \
+    if (with_sign) {                                                         \
+        if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+            return;                                                          \
+    } else {                                                                 \
+        if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */  \
+            return;                                                          \
+    }                                                                        \
+                                                                             \
+    val &= (1 << FLOAT_FRAC_BITS) - 1;                                       \
+    if (exp >= 32) {                                                         \
+        ret.high = 1 << (exp - 32);                                          \
+        if (exp - 32 >= FLOAT_FRAC_BITS) {                                   \
+            ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS);                 \
+            ret.low = 0;                                                     \
+        } else {                                                             \
+            high_shift = FLOAT_FRAC_BITS - (exp - 32);                       \
+            ret.high |= val >> high_shift;                                   \
+            ret.low = val << (32 - high_shift);                              \
+        }                                                                    \
+    } else {                                                                 \
+        ret.high = 0;                                                        \
+        ret.low = 1 << exp;                                                  \
+        if (exp > FLOAT_FRAC_BITS)                                           \
+            ret.low |= val << (exp - FLOAT_FRAC_BITS);                       \
+        else                                                                 \
+            ret.low |= val >> (FLOAT_FRAC_BITS - exp);                       \
+    }                                                                        \
+                                                                             \
+    /* encode negative integer using 2's complement */                       \
+    if (with_sign && sign) {                                                 \
+        ret.low = ~ret.low;                                                  \
+        ret.high = ~ret.high;                                                \
+        if (ret.low == UINT_MAX) {                                           \
+            ret.low = 0;                                                     \
+            ret.high++;                                                      \
+        } else                                                               \
+            ret.low++;                                                       \
+    }                                                                        \
+                                                                             \
+    double_unsigned_struct_return(ret);                                      \
+}
+
+/* float to unsigned long long conversion */
+DEFINE__AEABI_F2XLZ(f2ulz, 0)
+
+/* float to long long conversion */
+DEFINE__AEABI_F2XLZ(f2lz, 1)
+
+/* double to [unsigned] long long conversion */
+#define DEFINE__AEABI_D2XLZ(name, with_sign)                                 \
+void __aeabi_ ## name(double_unsigned_struct val)                            \
+{                                                                            \
+    int exp, high_shift, sign;                                               \
+    double_unsigned_struct ret;                                              \
+                                                                             \
+    /* compute sign */                                                       \
+    sign = val.high >> 31;                                                   \
+                                                                             \
+    /* compute real exponent */                                              \
+    exp = (val.high >> (DOUBLE_FRAC_BITS - 32));                             \
+    exp &= (1 << DOUBLE_EXP_BITS) - 1;                                       \
+    exp -= ONE_EXP(DOUBLE);                                                  \
+                                                                             \
+    /* undefined behavior if truncated value cannot be represented */        \
+    if (with_sign) {                                                         \
+        if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+            return;                                                          \
+    } else {                                                                 \
+        if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */  \
+            return;                                                          \
+    }                                                                        \
+                                                                             \
+    val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1;                          \
+    if (exp >= 32) {                                                         \
+        ret.high = 1 << (exp - 32);                                          \
+        if (exp >= DOUBLE_FRAC_BITS) {                                       \
+            high_shift = exp - DOUBLE_FRAC_BITS;                             \
+            ret.high |= val.high << high_shift;                              \
+            ret.high |= val.low >> (32 - high_shift);                        \
+            ret.low = val.low << high_shift;                                 \
+        } else {                                                             \
+            high_shift = DOUBLE_FRAC_BITS - exp;                             \
+            ret.high |= val.high >> high_shift;                              \
+            ret.low = val.high << (32 - high_shift);                         \
+            ret.low |= val.low >> high_shift;                                \
+        }                                                                    \
+    } else {                                                                 \
+        ret.high = 0;                                                        \
+        ret.low = 1 << exp;                                                  \
+        if (exp > DOUBLE_FRAC_BITS - 32) {                                   \
+            high_shift = exp - DOUBLE_FRAC_BITS - 32;                        \
+            ret.low |= val.high << high_shift;                               \
+            ret.low |= val.low >> (32 - high_shift);                         \
+        } else                                                               \
+            ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp);            \
+    }                                                                        \
+                                                                             \
+    /* encode negative integer using 2's complement */                       \
+    if (with_sign && sign) {                                                 \
+        ret.low = ~ret.low;                                                  \
+        ret.high = ~ret.high;                                                \
+        if (ret.low == UINT_MAX) {                                           \
+            ret.low = 0;                                                     \
+            ret.high++;                                                      \
+        } else                                                               \
+            ret.low++;                                                       \
+    }                                                                        \
+                                                                             \
+    double_unsigned_struct_return(ret);                                      \
+}
+
+/* double to unsigned long long conversion */
+DEFINE__AEABI_D2XLZ(d2ulz, 0)
+
+/* double to long long conversion */
+DEFINE__AEABI_D2XLZ(d2lz, 1)
+
+/* long long to float conversion */
+#define DEFINE__AEABI_XL2F(name, with_sign)                             \
+unsigned __aeabi_ ## name(unsigned long long v)                         \
+{                                                                       \
+    int s /* shift */, flb /* first lost bit */, sign = 0;              \
+    unsigned p = 0 /* power */, ret;                                    \
+    double_unsigned_struct val;                                         \
+                                                                        \
+    /* fraction in negative float is encoded in 1's complement */       \
+    if (with_sign && (v & (1ULL << 63))) {                              \
+        sign = 1;                                                       \
+        v = ~v + 1;                                                     \
+    }                                                                   \
+    val.low = v;                                                        \
+    val.high = v >> 32;                                                 \
+    /* fill fraction bits */                                            \
+    for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1);      \
+    if (p) {                                                            \
+        ret = val.high & (p - 1);                                       \
+        if (s < FLOAT_FRAC_BITS) {                                      \
+            ret <<= FLOAT_FRAC_BITS - s;                                \
+            ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s));             \
+            flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1;    \
+        } else {                                                        \
+            flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1;               \
+            ret >>= s - FLOAT_FRAC_BITS;                                \
+        }                                                               \
+        s += 32;                                                        \
+    } else {                                                            \
+        for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1);   \
+        if (p) {                                                        \
+            ret = val.low & (p - 1);                                    \
+            if (s <= FLOAT_FRAC_BITS) {                                 \
+                ret <<= FLOAT_FRAC_BITS - s;                            \
+                flb = 0;                                                \
+	    } else {                                                    \
+                flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1;           \
+                ret >>= s - FLOAT_FRAC_BITS;                            \
+	    }                                                           \
+        } else                                                          \
+            return 0;                                                   \
+    }                                                                   \
+    if (flb)                                                            \
+        ret++;                                                          \
+                                                                        \
+    /* fill exponent bits */                                            \
+    ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS;                     \
+                                                                        \
+    /* fill sign bit */                                                 \
+    ret |= sign << 31;                                                  \
+                                                                        \
+    return ret;                                                         \
+}
+
+/* unsigned long long to float conversion */
+DEFINE__AEABI_XL2F(ul2f, 0)
+
+/* long long to float conversion */
+DEFINE__AEABI_XL2F(l2f, 1)
+
+/* long long to double conversion */
+#define __AEABI_XL2D(name, with_sign)                                   \
+void __aeabi_ ## name(unsigned long long v)                             \
+{                                                                       \
+    int s /* shift */, high_shift, sign = 0;                            \
+    unsigned tmp, p = 0;                                                \
+    double_unsigned_struct val, ret;                                    \
+                                                                        \
+    /* fraction in negative float is encoded in 1's complement */       \
+    if (with_sign && (v & (1ULL << 63))) {                              \
+        sign = 1;                                                       \
+        v = ~v + 1;                                                     \
+    }                                                                   \
+    val.low = v;                                                        \
+    val.high = v >> 32;                                                 \
+                                                                        \
+    /* fill fraction bits */                                            \
+    for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1);      \
+    if (p) {                                                            \
+        tmp = val.high & (p - 1);                                       \
+        if (s < DOUBLE_FRAC_BITS - 32) {                                \
+            high_shift = DOUBLE_FRAC_BITS - 32 - s;                     \
+            ret.high = tmp << high_shift;                               \
+            ret.high |= val.low >> (32 - high_shift);                   \
+            ret.low = val.low << high_shift;                            \
+        } else {                                                        \
+            high_shift = s - (DOUBLE_FRAC_BITS - 32);                   \
+            ret.high = tmp >> high_shift;                               \
+            ret.low = tmp << (32 - high_shift);                         \
+            ret.low |= val.low >> high_shift;                           \
+            if ((val.low >> (high_shift - 1)) & 1) {                    \
+                if (ret.low == UINT_MAX) {                              \
+                    ret.high++;                                         \
+                    ret.low = 0;                                        \
+		} else                                                  \
+                    ret.low++;                                          \
+            }                                                           \
+        }                                                               \
+        s += 32;                                                        \
+    } else {                                                            \
+        for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1);   \
+        if (p) {                                                        \
+            tmp = val.low & (p - 1);                                    \
+            if (s <= DOUBLE_FRAC_BITS - 32) {                           \
+                high_shift = DOUBLE_FRAC_BITS - 32 - s;                 \
+                ret.high = tmp << high_shift;                           \
+                ret.low = 0;                                            \
+	    } else {                                                    \
+                high_shift = s - (DOUBLE_FRAC_BITS - 32);               \
+                ret.high = tmp >> high_shift;                           \
+                ret.low = tmp << (32 - high_shift);                     \
+            }                                                           \
+        } else {                                                        \
+            ret.high = ret.low = 0;                                     \
+            double_unsigned_struct_return(ret);                         \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    /* fill exponent bits */                                            \
+    ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32);       \
+                                                                        \
+    /* fill sign bit */                                                 \
+    ret.high |= sign << 31;                                             \
+                                                                        \
+    double_unsigned_struct_return(ret);                                 \
+}
+
+/* unsigned long long to double conversion */
+__AEABI_XL2D(ul2d, 0)
+
+/* long long to double conversion */
+__AEABI_XL2D(l2d, 1)
+
+
+/* Long long helper functions */
+
+/* TODO: add error in case of den == 0 (see 則4.3.1 and 則4.3.2) */
+
+#define define_aeabi_xdivmod_signed_type(basetype, type) \
+typedef struct type {                                    \
+    basetype quot;                                       \
+    unsigned basetype rem;                               \
+} type
+
+#define define_aeabi_xdivmod_unsigned_type(basetype, type) \
+typedef struct type {                                      \
+    basetype quot;                                         \
+    basetype rem;                                          \
+} type
+
+#define AEABI_UXDIVMOD(name,type, rettype, typemacro)                     \
+static inline rettype aeabi_ ## name (type num, type den)                 \
+{                                                                         \
+    rettype ret;                                                          \
+    type quot = 0;                                                        \
+                                                                          \
+    /* Increase quotient while it is less than numerator */               \
+    while (num >= den) {                                                  \
+        type q = 1;                                                       \
+                                                                          \
+        /* Find closest power of two */                                   \
+        while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
+            q <<= 1;                                                      \
+                                                                          \
+        /* Compute difference between current quotient and numerator */   \
+        num -= q * den;                                                   \
+        quot += q;                                                        \
+    }                                                                     \
+    ret.quot = quot;                                                      \
+    ret.rem = num;                                                        \
+    return ret;                                                           \
+}
+
+#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro)     \
+void __aeabi_ ## name(type numerator, type denominator)                       \
+{                                                                             \
+    unsigned type num, den;                                                   \
+    urettype uxdiv_ret;                                                       \
+    rettype ret;                                                              \
+                                                                              \
+    if (numerator >= 0)                                                       \
+      num = numerator;                                                        \
+    else                                                                      \
+      num = 0 - numerator;                                                    \
+    if (denominator >= 0)                                                     \
+      den = denominator;                                                      \
+    else                                                                      \
+      den = 0 - denominator;                                                  \
+    uxdiv_ret = aeabi_ ## uiname(num, den);                                   \
+    /* signs differ */                                                        \
+    if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
+        ret.quot = 0 - uxdiv_ret.quot;                                        \
+    else                                                                      \
+        ret.quot = uxdiv_ret.quot;                                            \
+    if (numerator < 0)                                                        \
+        ret.rem = 0 - uxdiv_ret.rem;                                          \
+    else                                                                      \
+        ret.rem = uxdiv_ret.rem;                                              \
+                                                                              \
+    rettype ## _return(ret);                                                  \
+}
+
+define_aeabi_xdivmod_signed_type(long long, lldiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
+define_aeabi_xdivmod_signed_type(int, idiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
+
+REGS_RETURN(lldiv_t, lldiv_t)
+REGS_RETURN(ulldiv_t, ulldiv_t)
+REGS_RETURN(idiv_t, idiv_t)
+REGS_RETURN(uidiv_t, uidiv_t)
+
+AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
+
+__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
+
+void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
+{
+    ulldiv_t_return(aeabi_uldivmod(num, den));
+}
+
+void __aeabi_llsl(double_unsigned_struct val, int shift)
+{
+    double_unsigned_struct ret;
+
+    if (shift >= 32) {
+        val.high = val.low;
+        val.low = 0;
+        shift -= 32;
+    }
+    if (shift > 0) {
+        ret.low = val.low << shift;
+        ret.high = (val.high << shift) | (val.low >> (32 - shift));
+        double_unsigned_struct_return(ret);
+	return;
+    }
+    double_unsigned_struct_return(val);
+}
+
+#define aeabi_lsr(val, shift, fill, type)                          \
+    type ## _struct ret;                                           \
+                                                                   \
+    if (shift >= 32) {                                             \
+        val.low = val.high;                                        \
+        val.high = fill;                                           \
+        shift -= 32;                                               \
+    }                                                              \
+    if (shift > 0) {                                               \
+        ret.high = val.high >> shift;                              \
+        ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
+        type ## _struct_return(ret);                               \
+	return;                                                    \
+    }                                                              \
+    type ## _struct_return(val);
+
+void __aeabi_llsr(double_unsigned_struct val, int shift)
+{
+    aeabi_lsr(val, shift, 0, double_unsigned);
+}
+
+void __aeabi_lasr(unsigned_int_struct val, int shift)
+{
+    aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
+}
+
+
+/* Integer division functions */
+
+AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
+
+int __aeabi_idiv(int numerator, int denominator)
+{
+    unsigned num, den;
+    uidiv_t ret;
+
+    if (numerator >= 0)
+        num = numerator;
+    else
+        num = 0 - numerator;
+    if (denominator >= 0)
+        den = denominator;
+    else
+        den = 0 - denominator;
+    ret = aeabi_uidivmod(num, den);
+    if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
+        ret.quot *= -1;
+    return ret.quot;
+}
+
+unsigned __aeabi_uidiv(unsigned num, unsigned den)
+{
+    return aeabi_uidivmod(num, den).quot;
+}
+
+__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
+
+void __aeabi_uidivmod(unsigned num, unsigned den)
+{
+    uidiv_t_return(aeabi_uidivmod(num, den));
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c	(revision 331)
@@ -0,0 +1,58 @@
+/* armflush.c - flush the instruction cache
+
+   __clear_cache is used in tccrun.c,  It is a built-in
+   intrinsic with gcc.  However tcc in order to compile
+   itself needs this function */
+
+#ifdef __TINYC__
+
+/* syscall wrapper */
+unsigned syscall(unsigned syscall_nr, ...);
+
+/* arm-tcc supports only fake asm currently */
+__asm__(
+    ".global syscall\n"
+    "syscall:\n"
+    ".int 0xe92d4080\n"  // push    {r7, lr}
+    ".int 0xe1a07000\n"  // mov     r7, r0
+    ".int 0xe1a00001\n"  // mov     r0, r1
+    ".int 0xe1a01002\n"  // mov     r1, r2
+    ".int 0xe1a02003\n"  // mov     r2, r3
+    ".int 0xef000000\n"  // svc     0x00000000
+    ".int 0xe8bd8080\n"  // pop     {r7, pc}
+    );
+
+/* from unistd.h: */
+#if defined(__thumb__) || defined(__ARM_EABI__)
+# define __NR_SYSCALL_BASE      0x0
+#else
+# define __NR_SYSCALL_BASE      0x900000
+#endif
+#define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)
+
+#else
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+
+#endif
+
+/* Flushing for tccrun */
+void __clear_cache(void *beginning, void *end)
+{
+/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
+ * However, there is no ARM asm parser in tcc so we use it for now */
+#if 1
+    syscall(__ARM_NR_cacheflush, beginning, end, 0);
+#else
+    __asm__ ("push {r7}\n\t"
+             "mov r7, #0xf0002\n\t"
+             "mov r2, #0\n\t"
+             "swi 0\n\t"
+             "pop {r7}\n\t"
+             "ret");
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/bcheck.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c	(revision 331)
@@ -22,17 +22,28 @@
 #include <stdarg.h>
 #include <string.h>
-#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \
-    && !defined(__DragonFly__) && !defined(__OpenBSD__)
+
+#if !defined(__FreeBSD__) \
+ && !defined(__FreeBSD_kernel__) \
+ && !defined(__DragonFly__) \
+ && !defined(__OpenBSD__) \
+ && !defined(__NetBSD__)
 #include <malloc.h>
 #endif
+
 #if !defined(_WIN32)
 #include <unistd.h>
 #endif
 
-//#define BOUND_DEBUG
+/* #define BOUND_DEBUG */
+
+#ifdef BOUND_DEBUG
+ #define dprintf(a...) fprintf(a)
+#else
+ #define dprintf(a...)
+#endif
 
 /* define so that bound array is static (faster, but use memory if
    bound checking not used) */
-//#define BOUND_STATIC
+/* #define BOUND_STATIC */
 
 /* use malloc hooks. Currently the code cannot be reliable if no hooks */
@@ -40,9 +51,12 @@
 #define HAVE_MEMALIGN
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
-    || defined(__DragonFly__) || defined(__dietlibc__) \
-    || defined(__UCLIBC__) || defined(__OpenBSD__) \
-    || defined(_WIN32) || defined(TCC_UCLIBC)
-#warning Bound checking does not support malloc (etc.) in this environment.
+#if defined(__FreeBSD__) \
+ || defined(__FreeBSD_kernel__) \
+ || defined(__DragonFly__) \
+ || defined(__OpenBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__dietlibc__) \
+ || defined(_WIN32)
+//#warning Bound checking does not support malloc (etc.) in this environment.
 #undef CONFIG_TCC_MALLOC_HOOKS
 #undef HAVE_MEMALIGN
@@ -51,13 +65,13 @@
 #define BOUND_T1_BITS 13
 #define BOUND_T2_BITS 11
-#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
-
-#define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
-#define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
-#define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
-#define BOUND_E_BITS  4
+#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS)
+#define BOUND_E_BITS  (sizeof(size_t))
+
+#define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS)
+#define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS)
+#define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS)
 
 #define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
-#define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
+#define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS)
 
 
@@ -65,20 +79,24 @@
 #define INVALID_POINTER ((void *)(-2))
 /* size of an empty region */
-#define EMPTY_SIZE        0xffffffff
+#define EMPTY_SIZE  ((size_t)(-1))
 /* size of an invalid region */
 #define INVALID_SIZE      0
 
 typedef struct BoundEntry {
-    unsigned long start;
-    unsigned long size;
+    size_t start;
+    size_t size;
     struct BoundEntry *next;
-    unsigned long is_invalid; /* true if pointers outside region are invalid */
+    size_t is_invalid; /* true if pointers outside region are invalid */
 } BoundEntry;
 
 /* external interface */
 void __bound_init(void);
-void __bound_new_region(void *p, unsigned long size);
+void __bound_new_region(void *p, size_t size);
 int __bound_delete_region(void *p);
 
+#ifdef __attribute__
+  /* an __attribute__ macro is defined in the system headers */
+  #undef __attribute__ 
+#endif
 #define FASTCALL __attribute__((regparm(3)))
 
@@ -105,5 +123,5 @@
 
 /* runtime error output */
-extern void rt_error(unsigned long pc, const char *fmt, ...);
+extern void rt_error(size_t pc, const char *fmt, ...);
 
 #ifdef BOUND_STATIC
@@ -117,10 +135,10 @@
 static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
 {
-    unsigned long addr, tmp;
+    size_t addr, tmp;
     BoundEntry *e;
 
     e = e1;
     while (e != NULL) {
-        addr = (unsigned long)p;
+        addr = (size_t)p;
         addr -= e->start;
         if (addr <= e->size) {
@@ -147,5 +165,6 @@
 {
     __bound_error_msg = fmt;
-    *(int *)0 = 0; /* force a runtime error */
+    fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt);
+    *(void **)0 = 0; /* force a runtime error */
 }
 
@@ -157,11 +176,13 @@
 /* return '(p + offset)' for pointer arithmetic (a pointer can reach
    the end of a region in this case */
-void * FASTCALL __bound_ptr_add(void *p, int offset)
-{
-    unsigned long addr = (unsigned long)p;
+void * FASTCALL __bound_ptr_add(void *p, size_t offset)
+{
+    size_t addr = (size_t)p;
     BoundEntry *e;
-#if defined(BOUND_DEBUG)
-    printf("add: 0x%x %d\n", (int)p, offset);
-#endif
+
+    dprintf(stderr, "%s %s: %p %x\n",
+        __FILE__, __FUNCTION__, p, (unsigned)offset);
+
+    __bound_init();
 
     e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
@@ -172,9 +193,12 @@
     if (addr > e->size) {
         e = __bound_find_region(e, p);
-        addr = (unsigned long)p - e->start;
+        addr = (size_t)p - e->start;
     }
     addr += offset;
-    if (addr > e->size)
+    if (addr >= e->size) {
+	fprintf(stderr,"%s %s: %p is outside of the region\n",
+            __FILE__, __FUNCTION__, p + offset);
         return INVALID_POINTER; /* return an invalid pointer */
+    }
     return p + offset;
 }
@@ -183,9 +207,13 @@
    be strictly inside the region */
 #define BOUND_PTR_INDIR(dsize)                                          \
-void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset)        \
+void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset)     \
 {                                                                       \
-    unsigned long addr = (unsigned long)p;                              \
+    size_t addr = (size_t)p;                                            \
     BoundEntry *e;                                                      \
                                                                         \
+    dprintf(stderr, "%s %s: %p %x start\n",                             \
+        __FILE__, __FUNCTION__, p, (unsigned)offset);	                \
+									\
+    __bound_init();							\
     e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];            \
     e = (BoundEntry *)((char *)e +                                      \
@@ -195,9 +223,14 @@
     if (addr > e->size) {                                               \
         e = __bound_find_region(e, p);                                  \
-        addr = (unsigned long)p - e->start;                             \
+        addr = (size_t)p - e->start;                                    \
     }                                                                   \
     addr += offset + dsize;                                             \
-    if (addr > e->size)                                                 \
+    if (addr > e->size) {                                               \
+	fprintf(stderr,"%s %s: %p is outside of the region\n",          \
+            __FILE__, __FUNCTION__, p + offset);                        \
         return INVALID_POINTER; /* return an invalid pointer */         \
+    }									\
+    dprintf(stderr, "%s %s: return p+offset = %p\n",                    \
+        __FILE__, __FUNCTION__, p + offset);                            \
     return p + offset;                                                  \
 }
@@ -210,8 +243,17 @@
 BOUND_PTR_INDIR(16)
 
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+/*
+ * At least gcc 6.2 complains when __builtin_frame_address is used with
+ * nonzero argument.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-address"
+#endif
+
 /* return the frame pointer of the caller */
 #define GET_CALLER_FP(fp)\
 {\
-    fp = (unsigned long)__builtin_frame_address(1);\
+    fp = (size_t)__builtin_frame_address(1);\
 }
 
@@ -219,5 +261,7 @@
 void FASTCALL __bound_local_new(void *p1) 
 {
-    unsigned long addr, size, fp, *p = p1;
+    size_t addr, size, fp, *p = p1;
+
+    dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
     GET_CALLER_FP(fp);
     for(;;) {
@@ -230,4 +274,5 @@
         __bound_new_region((void *)addr, size);
     }
+    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
 }
 
@@ -235,5 +280,5 @@
 void FASTCALL __bound_local_delete(void *p1) 
 {
-    unsigned long addr, fp, *p = p1;
+    size_t addr, fp, *p = p1;
     GET_CALLER_FP(fp);
     for(;;) {
@@ -247,8 +292,12 @@
 }
 
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+#pragma GCC diagnostic pop
+#endif
+
 static BoundEntry *__bound_new_page(void)
 {
     BoundEntry *page;
-    int i;
+    size_t i;
 
     page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
@@ -278,9 +327,9 @@
 }
 
-static inline BoundEntry *get_page(int index)
+static BoundEntry *get_page(size_t index)
 {
     BoundEntry *page;
     page = __bound_t1[index];
-    if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
+    if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) {
         /* create a new page if necessary */
         page = __bound_new_page();
@@ -291,9 +340,9 @@
 
 /* mark a region as being invalid (can only be used during init) */
-static void mark_invalid(unsigned long addr, unsigned long size)
-{
-    unsigned long start, end;
+static void mark_invalid(size_t addr, size_t size)
+{
+    size_t start, end;
     BoundEntry *page;
-    int t1_start, t1_end, i, j, t2_start, t2_end;
+    size_t t1_start, t1_end, i, j, t2_start, t2_end;
 
     start = addr;
@@ -307,5 +356,5 @@
 
 #if 0
-    printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
+    dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
 #endif
     
@@ -346,8 +395,16 @@
 void __bound_init(void)
 {
-    int i;
+    size_t i;
     BoundEntry *page;
-    unsigned long start, size;
-    int *p;
+    size_t start, size;
+    size_t *p;
+
+    static int inited;
+    if (inited)
+	return;
+
+    inited = 1;
+
+    dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
 
     /* save malloc hooks and install bound check hooks */
@@ -375,5 +432,5 @@
 
     /* invalid pointer zone */
-    start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
+    start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
     size = BOUND_T23_SIZE;
     mark_invalid(start, size);
@@ -406,5 +463,5 @@
      *     start_brk from /proc/self/stat
      */
-    start = (unsigned long)sbrk(0);
+    start = (size_t)sbrk(0);
     size = 128 * 0x100000;
     mark_invalid(start, size);
@@ -412,18 +469,32 @@
 
     /* add all static bound check values */
-    p = (int *)&__bounds_start;
+    p = (size_t *)&__bounds_start;
     while (p[0] != 0) {
         __bound_new_region((void *)p[0], p[1]);
         p += 2;
     }
+
+    dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
+}
+
+void __bound_main_arg(void **p)
+{
+    void *start = p;
+    while (*p++);
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n",
+            __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start));
+
+    __bound_new_region(start, (void *) p - start);
 }
 
 void __bound_exit(void)
 {
+    dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
     restore_malloc_hooks();
 }
 
 static inline void add_region(BoundEntry *e, 
-                              unsigned long start, unsigned long size)
+                              size_t start, size_t size)
 {
     BoundEntry *e1;
@@ -445,11 +516,16 @@
 
 /* create a new region. It should not already exist in the region list */
-void __bound_new_region(void *p, unsigned long size)
-{
-    unsigned long start, end;
+void __bound_new_region(void *p, size_t size)
+{
+    size_t start, end;
     BoundEntry *page, *e, *e2;
-    int t1_start, t1_end, i, t2_start, t2_end;
-
-    start = (unsigned long)p;
+    size_t t1_start, t1_end, i, t2_start, t2_end;
+
+    dprintf(stderr, "%s, %s(%p, %x) start\n",
+        __FILE__, __FUNCTION__, p, (unsigned)size);
+
+    __bound_init();
+
+    start = (size_t)p;
     end = start + size;
     t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
@@ -462,8 +538,5 @@
     t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
         ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
-#ifdef BOUND_DEBUG
-    printf("new %lx %lx %x %x %x %x\n", 
-           start, end, t1_start, t1_end, t2_start, t2_end);
-#endif
+
 
     e = (BoundEntry *)((char *)page + t2_start);
@@ -507,14 +580,15 @@
         add_region(e, start, size);
     }
+
+    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
 }
 
 /* delete a region */
-static inline void delete_region(BoundEntry *e, 
-                                 void *p, unsigned long empty_size)
-{
-    unsigned long addr;
+static inline void delete_region(BoundEntry *e, void *p, size_t empty_size)
+{
+    size_t addr;
     BoundEntry *e1;
 
-    addr = (unsigned long)p;
+    addr = (size_t)p;
     addr -= e->start;
     if (addr <= e->size) {
@@ -540,5 +614,5 @@
             if (e == NULL)
                 break;
-            addr = (unsigned long)p - e->start;
+            addr = (size_t)p - e->start;
             if (addr <= e->size) {
                 /* found: remove entry */
@@ -555,9 +629,13 @@
 int __bound_delete_region(void *p)
 {
-    unsigned long start, end, addr, size, empty_size;
+    size_t start, end, addr, size, empty_size;
     BoundEntry *page, *e, *e2;
-    int t1_start, t1_end, t2_start, t2_end, i;
-
-    start = (unsigned long)p;
+    size_t t1_start, t1_end, t2_start, t2_end, i;
+
+    dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
+
+    __bound_init();
+
+    start = (size_t)p;
     t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
     t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
@@ -571,5 +649,5 @@
         e = __bound_find_region(e, p);
     /* test if invalid region */
-    if (e->size == EMPTY_SIZE || (unsigned long)p != e->start) 
+    if (e->size == EMPTY_SIZE || (size_t)p != e->start) 
         return -1;
     /* compute the size we put in invalid regions */
@@ -625,12 +703,15 @@
         delete_region(e, p, empty_size);
     }
+
+    dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
+
     return 0;
 }
 
 /* return the size of the region starting at p, or EMPTY_SIZE if non
-   existant region. */
-static unsigned long get_region_size(void *p)
-{
-    unsigned long addr = (unsigned long)p;
+   existent region. */
+static size_t get_region_size(void *p)
+{
+    size_t addr = (size_t)p;
     BoundEntry *e;
 
@@ -642,5 +723,5 @@
     if (addr > e->size)
         e = __bound_find_region(e, p);
-    if (e->start != (unsigned long)p)
+    if (e->start != (size_t)p)
         return EMPTY_SIZE;
     return e->size;
@@ -710,4 +791,8 @@
     if (!ptr)
         return NULL;
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+           __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
     __bound_new_region(ptr, size);
     return ptr;
@@ -739,4 +824,8 @@
     if (!ptr)
         return NULL;
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+           __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
     __bound_new_region(ptr, size);
     return ptr;
@@ -756,5 +845,5 @@
 {
     void *ptr1;
-    int old_size;
+    size_t old_size;
 
     if (size == 0) {
@@ -791,7 +880,7 @@
 {
     BoundEntry *page, *e;
-    int i, j;
-
-    printf("region dump:\n");
+    size_t i, j;
+
+    fprintf(stderr, "region dump:\n");
     for(i=0;i<BOUND_T1_SIZE;i++) {
         page = __bound_t1[i];
@@ -800,12 +889,12 @@
             /* do not print invalid or empty entries */
             if (e->size != EMPTY_SIZE && e->start != 0) {
-                printf("%08x:", 
+                fprintf(stderr, "%08x:", 
                        (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + 
                        (j << BOUND_T3_BITS));
                 do {
-                    printf(" %08lx:%08lx", e->start, e->start + e->size);
+                    fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
                     e = e->next;
                 } while (e != NULL);
-                printf("\n");
+                fprintf(stderr, "\n");
             }
         }
@@ -821,5 +910,5 @@
     if (size == 0)
         return;
-    p = __bound_ptr_add((void *)p, size);
+    p = __bound_ptr_add((void *)p, size - 1);
     if (p == INVALID_POINTER)
         bound_error("invalid pointer");
@@ -828,4 +917,9 @@
 void *__bound_memcpy(void *dst, const void *src, size_t size)
 {
+    void* p;
+
+    dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n",
+            __FILE__, __FUNCTION__, dst, src, (unsigned)size);
+
     __bound_check(dst, size);
     __bound_check(src, size);
@@ -833,5 +927,9 @@
     if (src >= dst && src < dst + size)
         bound_error("overlapping regions in memcpy()");
-    return memcpy(dst, src, size);
+
+    p = memcpy(dst, src, size);
+
+    dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p);
+    return p;
 }
 
@@ -853,5 +951,5 @@
 {
     const char *p;
-    int len;
+    size_t len;
 
     len = 0;
@@ -869,7 +967,13 @@
 char *__bound_strcpy(char *dst, const char *src)
 {
-    int len;
+    size_t len;
+    void *p;
+
+    dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n",
+            __FILE__, __FUNCTION__, dst, src);
     len = __bound_strlen(src);
-    return __bound_memcpy(dst, src, len + 1);
-}
-
+    p = __bound_memcpy(dst, src, len + 1);
+    dprintf(stderr, "%s %s: strcpy end, p = %p\n",
+            __FILE__, __FUNCTION__, p);
+    return p;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c	(revision 331)
@@ -0,0 +1,664 @@
+/*
+ *  TCC runtime library for arm64.
+ *
+ *  Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef __TINYC__
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+void *memcpy(void*,void*,__SIZE_TYPE__);
+#else
+#include <stdint.h>
+#include <string.h>
+#endif
+
+void __clear_cache(void *beg, void *end)
+{
+    __arm64_clear_cache(beg, end);
+}
+
+typedef struct {
+    uint64_t x0, x1;
+} u128_t;
+
+static long double f3_zero(int sgn)
+{
+    long double f;
+    u128_t x = { 0, (uint64_t)sgn << 63 };
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_infinity(int sgn)
+{
+    long double f;
+    u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_NaN(void)
+{
+    long double f;
+#if 0
+    // ARM's default NaN usually has just the top fraction bit set:
+    u128_t x = {  0, 0x7fff800000000000 };
+#else
+    // GCC's library sets all fraction bits:
+    u128_t x = { -1, 0x7fffffffffffffff };
+#endif
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt)
+{
+    u128_t x = { mnt.x0,
+                 mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
+    memcpy(f, &x, 16);
+    return 1;
+}
+
+static int fp3_detect_NaNs(long double *f,
+                           int a_sgn, int a_exp, u128_t a,
+                           int b_sgn, int b_exp, u128_t b)
+{
+    // Detect signalling NaNs:
+    if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
+        return fp3_convert_NaN(f, a_sgn, a);
+    if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
+        return fp3_convert_NaN(f, b_sgn, b);
+
+    // Detect quiet NaNs:
+    if (a_exp == 32767 && (a.x0 | a.x1 << 16))
+        return fp3_convert_NaN(f, a_sgn, a);
+    if (b_exp == 32767 && (b.x0 | b.x1 << 16))
+        return fp3_convert_NaN(f, b_sgn, b);
+
+    return 0;
+}
+
+static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
+{
+    u128_t x;
+    memcpy(&x, &f, 16);
+    *sgn = x.x1 >> 63;
+    *exp = x.x1 >> 48 & 32767;
+    x.x1 = x.x1 << 16 >> 16;
+    if (*exp)
+        x.x1 |= (uint64_t)1 << 48;
+    else
+        *exp = 1;
+    *mnt = x;
+}
+
+static u128_t f3_normalise(int32_t *exp, u128_t mnt)
+{
+    int sh;
+    if (!(mnt.x0 | mnt.x1))
+        return mnt;
+    if (!mnt.x1) {
+        mnt.x1 = mnt.x0;
+        mnt.x0 = 0;
+        *exp -= 64;
+    }
+    for (sh = 32; sh; sh >>= 1) {
+        if (!(mnt.x1 >> (64 - sh))) {
+            mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh);
+            mnt.x0 = mnt.x0 << sh;
+            *exp -= sh;
+        }
+    }
+    return mnt;
+}
+
+static u128_t f3_sticky_shift(int32_t sh, u128_t x)
+{
+  if (sh >= 128) {
+      x.x0 = !!(x.x0 | x.x1);
+      x.x1 = 0;
+      return x;
+  }
+  if (sh >= 64) {
+      x.x0 = x.x1 | !!x.x0;
+      x.x1 = 0;
+      sh -= 64;
+  }
+  if (sh > 0) {
+      x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh));
+      x.x1 = x.x1 >> sh;
+  }
+  return x;
+}
+
+static long double f3_round(int sgn, int32_t exp, u128_t x)
+{
+    long double f;
+    int error;
+
+    if (exp > 0) {
+        x = f3_sticky_shift(13, x);
+    }
+    else {
+        x = f3_sticky_shift(14 - exp, x);
+        exp = 0;
+    }
+
+    error = x.x0 & 3;
+    x.x0 = x.x0 >> 2 | x.x1 << 62;
+    x.x1 = x.x1 >> 2;
+
+    if (error == 3 || ((error == 2) & (x.x0 & 1))) {
+        if (!++x.x0) {
+            ++x.x1;
+            if (x.x1 == (uint64_t)1 << 48)
+                exp = 1;
+            else if (x.x1 == (uint64_t)1 << 49) {
+                ++exp;
+                x.x0 = x.x0 >> 1 | x.x1 << 63;
+                x.x1 = x.x1 >> 1;
+            }
+        }
+    }
+
+    if (exp >= 32767)
+        return f3_infinity(sgn);
+
+    x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_add(long double fa, long double fb, int neg)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    b_sgn ^= neg;
+
+    // Handle infinities and zeroes:
+    if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
+        return f3_NaN();
+    if (a_exp == 32767)
+        return f3_infinity(a_sgn);
+    if (b_exp == 32767)
+        return f3_infinity(b_sgn);
+    if (!(a.x0 | a.x1 | b.x0 | b.x1))
+        return f3_zero(a_sgn & b_sgn);
+
+    a.x1 = a.x1 << 3 | a.x0 >> 61;
+    a.x0 = a.x0 << 3;
+    b.x1 = b.x1 << 3 | b.x0 >> 61;
+    b.x0 = b.x0 << 3;
+
+    if (a_exp <= b_exp) {
+        a = f3_sticky_shift(b_exp - a_exp, a);
+        a_exp = b_exp;
+    }
+    else {
+        b = f3_sticky_shift(a_exp - b_exp, b);
+        b_exp = a_exp;
+    }
+
+    x_sgn = a_sgn;
+    x_exp = a_exp;
+    if (a_sgn == b_sgn) {
+        x.x0 = a.x0 + b.x0;
+        x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
+    }
+    else {
+        x.x0 = a.x0 - b.x0;
+        x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
+        if (x.x1 >> 63) {
+            x_sgn ^= 1;
+            x.x0 = -x.x0;
+            x.x1 = -x.x1 - !!x.x0;
+        }
+    }
+
+    if (!(x.x0 | x.x1))
+        return f3_zero(0);
+
+    x = f3_normalise(&x_exp, x);
+
+    return f3_round(x_sgn, x_exp + 12, x);
+}
+
+long double __addtf3(long double a, long double b)
+{
+    return f3_add(a, b, 0);
+}
+
+long double __subtf3(long double a, long double b)
+{
+    return f3_add(a, b, 1);
+}
+
+long double __multf3(long double fa, long double fb)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    // Handle infinities and zeroes:
+    if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
+        (b_exp == 32767 && !(a.x0 | a.x1)))
+        return f3_NaN();
+    if (a_exp == 32767 || b_exp == 32767)
+        return f3_infinity(a_sgn ^ b_sgn);
+    if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
+        return f3_zero(a_sgn ^ b_sgn);
+
+    a = f3_normalise(&a_exp, a);
+    b = f3_normalise(&b_exp, b);
+
+    x_sgn = a_sgn ^ b_sgn;
+    x_exp = a_exp + b_exp - 16352;
+
+    {
+        // Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
+        // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
+        uint64_t a0 = a.x0 << 28 >> 34;
+        uint64_t b0 = b.x0 << 28 >> 34;
+        uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
+        uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
+        uint64_t a2 = a.x1 << 32 >> 34;
+        uint64_t b2 = b.x1 << 32 >> 34;
+        uint64_t a3 = a.x1 >> 32;
+        uint64_t b3 = b.x1 >> 32;
+        // Use 16 small multiplications and additions that do not overflow:
+        uint64_t x0 = a0 * b0;
+        uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
+        uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
+        uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+        uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
+        uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
+        uint64_t x6 = (x5 >> 30) + a3 * b3;
+        // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
+        // Take the top 128 bits, setting bottom bit if any lower bits were set:
+        uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
+                       !!(x3 << 38 | (x2 | x1 | x0) << 34));
+        uint64_t y1 = x6;
+        // Top bit may be zero. Renormalise:
+        if (!(y1 >> 63)) {
+            y1 = y1 << 1 | y0 >> 63;
+            y0 = y0 << 1;
+            --x_exp;
+        }
+        x.x0 = y0;
+        x.x1 = y1;
+    }
+
+    return f3_round(x_sgn, x_exp, x);
+}
+
+long double __divtf3(long double fa, long double fb)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn, i;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    // Handle infinities and zeroes:
+    if ((a_exp == 32767 && b_exp == 32767) ||
+        (!(a.x0 | a.x1) && !(b.x0 | b.x1)))
+        return f3_NaN();
+    if (a_exp == 32767 || !(b.x0 | b.x1))
+        return f3_infinity(a_sgn ^ b_sgn);
+    if (!(a.x0 | a.x1) || b_exp == 32767)
+        return f3_zero(a_sgn ^ b_sgn);
+
+    a = f3_normalise(&a_exp, a);
+    b = f3_normalise(&b_exp, b);
+
+    x_sgn = a_sgn ^ b_sgn;
+    x_exp = a_exp - b_exp + 16395;
+
+    a.x0 = a.x0 >> 1 | a.x1 << 63;
+    a.x1 = a.x1 >> 1;
+    b.x0 = b.x0 >> 1 | b.x1 << 63;
+    b.x1 = b.x1 >> 1;
+    x.x0 = 0;
+    x.x1 = 0;
+    for (i = 0; i < 116; i++) {
+        x.x1 = x.x1 << 1 | x.x0 >> 63;
+        x.x0 = x.x0 << 1;
+        if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
+            a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
+            a.x0 = a.x0 - b.x0;
+            x.x0 |= 1;
+        }
+        a.x1 = a.x1 << 1 | a.x0 >> 63;
+        a.x0 = a.x0 << 1;
+    }
+    x.x0 |= !!(a.x0 | a.x1);
+
+    x = f3_normalise(&x_exp, x);
+
+    return f3_round(x_sgn, x_exp, x);
+}
+
+long double __extendsftf2(float f)
+{
+    long double fx;
+    u128_t x;
+    uint32_t a;
+    uint64_t aa;
+    memcpy(&a, &f, 4);
+    aa = a;
+    x.x0 = 0;
+    if (!(a << 1))
+        x.x1 = aa << 32;
+    else if (a << 1 >> 24 == 255)
+        x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
+                (uint64_t)!!(a << 9) << 47);
+    else
+        x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
+                aa << 41 >> 16);
+    memcpy(&fx, &x, 16);
+    return fx;
+}
+
+long double __extenddftf2(double f)
+{
+    long double fx;
+    u128_t x;
+    uint64_t a;
+    memcpy(&a, &f, 8);
+    x.x0 = a << 60;
+    if (!(a << 1))
+        x.x1 = a;
+    else if (a << 1 >> 53 == 2047)
+        x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
+                (uint64_t)!!(a << 12) << 47);
+    else
+        x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
+    memcpy(&fx, &x, 16);
+    return fx;
+}
+
+float __trunctfsf2(long double f)
+{
+    u128_t mnt;
+    int32_t exp;
+    int sgn;
+    uint32_t x;
+    float fx;
+
+    f3_unpack(&sgn, &exp, &mnt, f);
+
+    if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+        x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
+    else if (exp > 16510)
+        x = 0x7f800000 | (uint32_t)sgn << 31;
+    else if (exp < 16233)
+        x = (uint32_t)sgn << 31;
+    else {
+        exp -= 16257;
+        x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
+        if (exp < 0) {
+            x = x >> -exp | !!(x << (32 + exp));
+            exp = 0;
+        }
+        if ((x & 3) == 3 || (x & 7) == 6)
+            x += 4;
+        x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
+    }
+    memcpy(&fx, &x, 4);
+    return fx;
+}
+
+double __trunctfdf2(long double f)
+{
+    u128_t mnt;
+    int32_t exp;
+    int sgn;
+    uint64_t x;
+    double fx;
+
+    f3_unpack(&sgn, &exp, &mnt, f);
+
+    if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+        x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
+             mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
+    else if (exp > 17406)
+        x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
+    else if (exp < 15308)
+        x = (uint64_t)sgn << 63;
+    else {
+        exp -= 15361;
+        x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
+        if (exp < 0) {
+            x = x >> -exp | !!(x << (64 + exp));
+            exp = 0;
+        }
+        if ((x & 3) == 3 || (x & 7) == 6)
+            x += 4;
+        x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
+    }
+    memcpy(&fx, &x, 8);
+    return fx;
+}
+
+int32_t __fixtfsi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    int32_t x;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_exp < 16369)
+        return 0;
+    if (a_exp > 16413)
+        return a_sgn ? -0x80000000 : 0x7fffffff;
+    x = a.x1 >> (16431 - a_exp);
+    return a_sgn ? -x : x;
+}
+
+int64_t __fixtfdi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    int64_t x;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_exp < 16383)
+        return 0;
+    if (a_exp > 16445)
+        return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
+    x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+    return a_sgn ? -x : x;
+}
+
+uint32_t __fixunstfsi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_sgn || a_exp < 16369)
+        return 0;
+    if (a_exp > 16414)
+        return -1;
+    return a.x1 >> (16431 - a_exp);
+}
+
+uint64_t __fixunstfdi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_sgn || a_exp < 16383)
+        return 0;
+    if (a_exp > 16446)
+        return -1;
+    return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+}
+
+long double __floatsitf(int32_t a)
+{
+    int sgn = 0;
+    int exp = 16414;
+    uint32_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        if (a < 0) {
+            sgn = 1;
+            mnt = -mnt;
+        }
+        for (i = 16; i; i >>= 1)
+            if (!(mnt >> (32 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
+                (uint64_t)(mnt << 1) << 16);
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatditf(int64_t a)
+{
+    int sgn = 0;
+    int exp = 16446;
+    uint64_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        if (a < 0) {
+            sgn = 1;
+            mnt = -mnt;
+        }
+        for (i = 32; i; i >>= 1)
+            if (!(mnt >> (64 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x0 = mnt << 49;
+        x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatunsitf(uint32_t a)
+{
+    int exp = 16414;
+    uint32_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        for (i = 16; i; i >>= 1)
+            if (!(mnt >> (32 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatunditf(uint64_t a)
+{
+    int exp = 16446;
+    uint64_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        for (i = 32; i; i >>= 1)
+            if (!(mnt >> (64 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x0 = mnt << 49;
+        x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static int f3_cmp(long double fa, long double fb)
+{
+    u128_t a, b;
+    memcpy(&a, &fa, 16);
+    memcpy(&b, &fb, 16);
+    return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
+            ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
+             (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
+            a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
+            a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
+            a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
+            a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
+            b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
+}
+
+int __eqtf2(long double a, long double b)
+{
+    return !!f3_cmp(a, b);
+}
+
+int __netf2(long double a, long double b)
+{
+    return !!f3_cmp(a, b);
+}
+
+int __lttf2(long double a, long double b)
+{
+    return f3_cmp(a, b);
+}
+
+int __letf2(long double a, long double b)
+{
+    return f3_cmp(a, b);
+}
+
+int __gttf2(long double a, long double b)
+{
+    return -f3_cmp(b, a);
+}
+
+int __getf2(long double a, long double b)
+{
+    return -f3_cmp(b, a);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/lib/libtcc1.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c	(revision 331)
@@ -104,12 +104,12 @@
 union float_long {
     float f;
-    long l;
+    unsigned int l;
 };
 
 /* XXX: we don't support several builtin supports for now */
-#ifndef __x86_64__
+#if !defined __x86_64__ && !defined __arm__
 
 /* XXX: use gcc/tcc intrinsic ? */
-#if defined(__i386__)
+#if defined __i386__
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
   __asm__ ("subl %5,%1\n\tsbbl %3,%0"					\
@@ -479,11 +479,4 @@
 }
 
-#if defined(__i386__)
-/* FPU control word for rounding to nearest mode */
-unsigned short __tcc_fpu_control = 0x137f;
-/* FPU control word for round to zero mode for int conversion */
-unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
-#endif
-
 #endif /* !__x86_64__ */
 
@@ -558,4 +551,11 @@
 }
 
+long long __fixsfdi (float a1)
+{
+    long long ret; int s;
+    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+
 unsigned long long __fixunsdfdi (double a1)
 {
@@ -583,4 +583,12 @@
 }
 
+long long __fixdfdi (double a1)
+{
+    long long ret; int s;
+    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+
+#ifndef __arm__
 unsigned long long __fixunsxfdi (long double a1)
 {
@@ -606,86 +614,9 @@
 }
 
-#if defined(__x86_64__) && !defined(_WIN64)
-
-/* helper functions for stdarg.h */
-
-#include <stdlib.h>
-#ifndef __TINYC__
-/* gives "incompatible types for redefinition of __va_arg" below */
-#include <stdio.h>
-#endif
-
-enum __va_arg_type {
-    __va_gen_reg, __va_float_reg, __va_stack
-};
-
-/* GCC compatible definition of va_list. */
-struct __va_list_struct {
-    unsigned int gp_offset;
-    unsigned int fp_offset;
-    union {
-        unsigned int overflow_offset;
-        char *overflow_arg_area;
-    };
-    char *reg_save_area;
-};
-
-void *__va_start(void *fp)
-{
-    struct __va_list_struct *ap =
-        (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct));
-    *ap = *(struct __va_list_struct *)((char *)fp - 16);
-    ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
-    ap->reg_save_area = (char *)fp - 176 - 16;
-    return ap;
-}
-
-void *__va_arg(struct __va_list_struct *ap,
-               enum __va_arg_type arg_type,
-               int size)
-{
-    size = (size + 7) & ~7;
-    switch (arg_type) {
-    case __va_gen_reg:
-        if (ap->gp_offset < 48) {
-            ap->gp_offset += 8;
-            return ap->reg_save_area + ap->gp_offset - 8;
-        }
-        size = 8;
-        goto use_overflow_area;
-
-    case __va_float_reg:
-        if (ap->fp_offset < 128 + 48) {
-            ap->fp_offset += 16;
-            return ap->reg_save_area + ap->fp_offset - 16;
-        }
-        size = 8;
-        goto use_overflow_area;
-
-    case __va_stack:
-    use_overflow_area:
-        ap->overflow_arg_area += size;
-        return ap->overflow_arg_area - size;
-
-    default:
-#ifndef __TINYC__
-        fprintf(stderr, "unknown ABI type for __va_arg\n");
-#endif
-        abort();
-    }
-}
-
-void *__va_copy(struct __va_list_struct *src)
-{
-    struct __va_list_struct *dest =
-        (struct __va_list_struct *)malloc(sizeof(struct __va_list_struct));
-    *dest = *src;
-    return dest;
-}
-
-void __va_end(struct __va_list_struct *ap)
-{
-    free(ap);
-}
-
-#endif /* __x86_64__ */
+long long __fixxfdi (long double a1)
+{
+    long long ret; int s;
+    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+#endif /* !ARM */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c	(revision 331)
@@ -0,0 +1,65 @@
+/* va_list.c - tinycc support for va_list on X86_64 */
+
+#if defined __x86_64__
+
+/* Avoid include files, they may not be available when cross compiling */
+extern void *memset(void *s, int c, __SIZE_TYPE__ n);
+extern void abort(void);
+
+/* This should be in sync with our include/stdarg.h */
+enum __va_arg_type {
+    __va_gen_reg, __va_float_reg, __va_stack
+};
+
+/* GCC compatible definition of va_list. */
+typedef struct {
+    unsigned int gp_offset;
+    unsigned int fp_offset;
+    union {
+        unsigned int overflow_offset;
+        char *overflow_arg_area;
+    };
+    char *reg_save_area;
+} __va_list_struct;
+
+void __va_start(__va_list_struct *ap, void *fp)
+{
+    memset(ap, 0, sizeof(__va_list_struct));
+    *ap = *(__va_list_struct *)((char *)fp - 16);
+    ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
+    ap->reg_save_area = (char *)fp - 176 - 16;
+}
+
+void *__va_arg(__va_list_struct *ap,
+               enum __va_arg_type arg_type,
+               int size, int align)
+{
+    size = (size + 7) & ~7;
+    align = (align + 7) & ~7;
+    switch (arg_type) {
+    case __va_gen_reg:
+        if (ap->gp_offset + size <= 48) {
+            ap->gp_offset += size;
+            return ap->reg_save_area + ap->gp_offset - size;
+        }
+        goto use_overflow_area;
+
+    case __va_float_reg:
+        if (ap->fp_offset < 128 + 48) {
+            ap->fp_offset += 16;
+            return ap->reg_save_area + ap->fp_offset - 16;
+        }
+        size = 8;
+        goto use_overflow_area;
+
+    case __va_stack:
+    use_overflow_area:
+        ap->overflow_arg_area += size;
+        ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
+        return ap->overflow_arg_area - size;
+
+    default: /* should never happen */
+        abort();
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/libtcc.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c	(revision 331)
@@ -1,5 +1,5 @@
 /*
  *  TCC - Tiny C Compiler
- * 
+ *
  *  Copyright (c) 2001-2004 Fabrice Bellard
  *
@@ -33,7 +33,9 @@
 ST_DATA struct TCCState *tcc_state;
 
+static int nb_states;
+
 /********************************************************/
 
-#ifdef ONE_SOURCE
+#if ONE_SOURCE
 #include "tccpp.c"
 #include "tccgen.c"
@@ -42,25 +44,28 @@
 #ifdef TCC_TARGET_I386
 #include "i386-gen.c"
+#include "i386-link.c"
+#include "i386-asm.c"
 #endif
 #ifdef TCC_TARGET_ARM
 #include "arm-gen.c"
+#include "arm-link.c"
+#include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+#include "arm64-gen.c"
+#include "arm64-link.c"
 #endif
 #ifdef TCC_TARGET_C67
 #include "c67-gen.c"
+#include "c67-link.c"
+#include "tcccoff.c"
 #endif
 #ifdef TCC_TARGET_X86_64
 #include "x86_64-gen.c"
-#endif
-#ifdef TCC_TARGET_IL
-#include "il-gen.c"
+#include "x86_64-link.c"
+#include "i386-asm.c"
 #endif
 #ifdef CONFIG_TCC_ASM
 #include "tccasm.c"
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-#include "i386-asm.c"
-#endif
-#endif
-#ifdef TCC_TARGET_COFF
-#include "tcccoff.c"
 #endif
 #ifdef TCC_TARGET_PE
@@ -82,7 +87,6 @@
 
 /********************************************************/
-
 #ifdef _WIN32
-char *normalize_slashes(char *path)
+ST_FUNC char *normalize_slashes(char *path)
 {
     char *p;
@@ -93,5 +97,4 @@
 }
 
-#if 0
 static HMODULE tcc_module;
 
@@ -102,8 +105,6 @@
     GetModuleFileNameA(tcc_module, path, sizeof path);
     p = tcc_basename(normalize_slashes(strlwr(path)));
-    if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
-        p -= 5;
-    else if (p > path)
-        p--;
+    if (p > path)
+        --p;
     *p = 0;
     tcc_set_lib_path(s, path);
@@ -119,17 +120,6 @@
 #endif
 
-#ifndef CONFIG_TCC_STATIC
-void dlclose(void *p)
-{
-    FreeLibrary((HMODULE)p);
-}
-#endif
-#else
-extern void tcc_set_lib_path_w32(TCCState *s);
-extern void dlclose(void *p);
-#endif
-
 #ifdef LIBTCC_AS_DLL
-BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
 {
     if (DLL_PROCESS_ATTACH == dwReason)
@@ -142,5 +132,5 @@
 /********************************************************/
 /* copy a string and truncate it. */
-PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
 {
     char *q, *q_end;
@@ -162,14 +152,14 @@
 
 /* strcat and truncate. */
-PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
 {
     int len;
     len = strlen(buf);
-    if (len < buf_size) 
+    if (len < buf_size)
         pstrcpy(buf + len, buf_size - len, s);
     return buf;
 }
 
-PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num)
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
 {
     memcpy(out, in, num);
@@ -205,16 +195,9 @@
 #undef realloc
 
-#ifdef MEM_DEBUG
-ST_DATA int mem_cur_size;
-ST_DATA int mem_max_size;
-unsigned malloc_usable_size(void*);
-#endif
+#ifndef MEM_DEBUG
 
 PUB_FUNC void tcc_free(void *ptr)
 {
-#ifdef MEM_DEBUG
-    mem_cur_size -= malloc_usable_size(ptr);
-#endif
-	free(ptr);
+    free(ptr);
 }
 
@@ -224,10 +207,5 @@
     ptr = malloc(size);
     if (!ptr && size)
-        tcc_error("memory full");
-#ifdef MEM_DEBUG
-    mem_cur_size += malloc_usable_size(ptr);
-    if (mem_cur_size > mem_max_size)
-        mem_max_size = mem_cur_size;
-#endif
+        tcc_error("memory full (malloc)");
     return ptr;
 }
@@ -244,16 +222,7 @@
 {
     void *ptr1;
-#ifdef MEM_DEBUG
-    mem_cur_size -= malloc_usable_size(ptr);
-#endif
     ptr1 = realloc(ptr, size);
     if (!ptr1 && size)
-        tcc_error("memory full");
-#ifdef MEM_DEBUG
-    /* NOTE: count not correct if alloc error, but not critical */
-    mem_cur_size += malloc_usable_size(ptr1);
-    if (mem_cur_size > mem_max_size)
-        mem_max_size = mem_cur_size;
-#endif
+        tcc_error("memory full (realloc)");
     return ptr1;
 }
@@ -267,10 +236,161 @@
 }
 
-PUB_FUNC void tcc_memstats(void)
-{
-#ifdef MEM_DEBUG
-    printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
-#endif
-}
+PUB_FUNC void tcc_memcheck(void)
+{
+}
+
+#else
+
+#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
+#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
+#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
+#define MEM_DEBUG_FILE_LEN 40
+#define MEM_DEBUG_CHECK3(header) \
+    ((mem_debug_header_t*)((char*)header + header->size))->magic3
+#define MEM_USER_PTR(header) \
+    ((char *)header + offsetof(mem_debug_header_t, magic3))
+#define MEM_HEADER_PTR(ptr) \
+    (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
+
+struct mem_debug_header {
+    unsigned magic1;
+    unsigned size;
+    struct mem_debug_header *prev;
+    struct mem_debug_header *next;
+    int line_num;
+    char file_name[MEM_DEBUG_FILE_LEN + 1];
+    unsigned magic2;
+    ALIGNED(16) unsigned magic3;
+};
+
+typedef struct mem_debug_header mem_debug_header_t;
+
+static mem_debug_header_t *mem_debug_chain;
+static unsigned mem_cur_size;
+static unsigned mem_max_size;
+
+static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
+{
+    mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
+    if (header->magic1 != MEM_DEBUG_MAGIC1 ||
+        header->magic2 != MEM_DEBUG_MAGIC2 ||
+        MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
+        header->size == (unsigned)-1) {
+        fprintf(stderr, "%s check failed\n", msg);
+        if (header->magic1 == MEM_DEBUG_MAGIC1)
+            fprintf(stderr, "%s:%u: block allocated here.\n",
+                header->file_name, header->line_num);
+        exit(1);
+    }
+    return header;
+}
+
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
+{
+    int ofs;
+    mem_debug_header_t *header;
+
+    header = malloc(sizeof(mem_debug_header_t) + size);
+    if (!header)
+        tcc_error("memory full (malloc)");
+
+    header->magic1 = MEM_DEBUG_MAGIC1;
+    header->magic2 = MEM_DEBUG_MAGIC2;
+    header->size = size;
+    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+    header->line_num = line;
+    ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
+    strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
+    header->file_name[MEM_DEBUG_FILE_LEN] = 0;
+
+    header->next = mem_debug_chain;
+    header->prev = NULL;
+    if (header->next)
+        header->next->prev = header;
+    mem_debug_chain = header;
+
+    mem_cur_size += size;
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+
+    return MEM_USER_PTR(header);
+}
+
+PUB_FUNC void tcc_free_debug(void *ptr)
+{
+    mem_debug_header_t *header;
+    if (!ptr)
+        return;
+    header = malloc_check(ptr, "tcc_free");
+    mem_cur_size -= header->size;
+    header->size = (unsigned)-1;
+    if (header->next)
+        header->next->prev = header->prev;
+    if (header->prev)
+        header->prev->next = header->next;
+    if (header == mem_debug_chain)
+        mem_debug_chain = header->next;
+    free(header);
+}
+
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
+{
+    void *ptr;
+    ptr = tcc_malloc_debug(size,file,line);
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
+{
+    mem_debug_header_t *header;
+    int mem_debug_chain_update = 0;
+    if (!ptr)
+        return tcc_malloc_debug(size, file, line);
+    header = malloc_check(ptr, "tcc_realloc");
+    mem_cur_size -= header->size;
+    mem_debug_chain_update = (header == mem_debug_chain);
+    header = realloc(header, sizeof(mem_debug_header_t) + size);
+    if (!header)
+        tcc_error("memory full (realloc)");
+    header->size = size;
+    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+    if (header->next)
+        header->next->prev = header;
+    if (header->prev)
+        header->prev->next = header;
+    if (mem_debug_chain_update)
+        mem_debug_chain = header;
+    mem_cur_size += size;
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+    return MEM_USER_PTR(header);
+}
+
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
+{
+    char *ptr;
+    ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
+    strcpy(ptr, str);
+    return ptr;
+}
+
+PUB_FUNC void tcc_memcheck(void)
+{
+    if (mem_cur_size) {
+        mem_debug_header_t *header = mem_debug_chain;
+        fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
+            mem_cur_size, mem_max_size);
+        while (header) {
+            fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
+                header->file_name, header->line_num, header->size);
+            header = header->next;
+        }
+#if MEM_DEBUG-0 == 2
+        exit(2);
+#endif
+    }
+}
+#endif /* MEM_DEBUG */
 
 #define free(p) use_tcc_free(p)
@@ -281,11 +401,11 @@
 /* dynarrays */
 
-ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
 {
     int nb, nb_alloc;
     void **pp;
-    
+
     nb = *nb_ptr;
-    pp = *ptab;
+    pp = *(void ***)ptab;
     /* every power of two we double array size */
     if ((nb & (nb - 1)) == 0) {
@@ -295,5 +415,5 @@
             nb_alloc = nb * 2;
         pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
-        *ptab = pp;
+        *(void***)ptab = pp;
     }
     pp[nb++] = data;
@@ -311,5 +431,5 @@
 }
 
-static void tcc_split_path(TCCState *s, void ***p_ary, int *p_nb_ary, const char *in)
+static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
 {
     const char *p;
@@ -319,241 +439,20 @@
 
         cstr_new(&str);
-        for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
+        for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
             if (c == '{' && p[1] && p[2] == '}') {
                 c = p[1], p += 2;
                 if (c == 'B')
-                    cstr_cat(&str, s->tcc_lib_path);
+                    cstr_cat(&str, s->tcc_lib_path, -1);
             } else {
                 cstr_ccat(&str, c);
             }
         }
-        cstr_ccat(&str, '\0');
-        dynarray_add(p_ary, p_nb_ary, str.data);
+        if (str.size) {
+            cstr_ccat(&str, '\0');
+            dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
+        }
+        cstr_free(&str);
         in = p+1;
     } while (*p);
-}
-
-/********************************************************/
-
-ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
-{
-    Section *sec;
-
-    sec = tcc_mallocz(sizeof(Section) + strlen(name));
-    strcpy(sec->name, name);
-    sec->sh_type = sh_type;
-    sec->sh_flags = sh_flags;
-    switch(sh_type) {
-    case SHT_HASH:
-    case SHT_REL:
-    case SHT_RELA:
-    case SHT_DYNSYM:
-    case SHT_SYMTAB:
-    case SHT_DYNAMIC:
-        sec->sh_addralign = 4;
-        break;
-    case SHT_STRTAB:
-        sec->sh_addralign = 1;
-        break;
-    default:
-        sec->sh_addralign = 32; /* default conservative alignment */
-        break;
-    }
-
-    if (sh_flags & SHF_PRIVATE) {
-        dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
-    } else {
-        sec->sh_num = s1->nb_sections;
-        dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
-    }
-
-    return sec;
-}
-
-static void free_section(Section *s)
-{
-    tcc_free(s->data);
-}
-
-/* realloc section and set its content to zero */
-ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
-{
-    unsigned long size;
-    unsigned char *data;
-    
-    size = sec->data_allocated;
-    if (size == 0)
-        size = 1;
-    while (size < new_size)
-        size = size * 2;
-    data = tcc_realloc(sec->data, size);
-    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
-    sec->data = data;
-    sec->data_allocated = size;
-}
-
-/* reserve at least 'size' bytes in section 'sec' from
-   sec->data_offset. */
-ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
-{
-    unsigned long offset, offset1;
-
-    offset = sec->data_offset;
-    offset1 = offset + size;
-    if (offset1 > sec->data_allocated)
-        section_realloc(sec, offset1);
-    sec->data_offset = offset1;
-    return sec->data + offset;
-}
-
-/* reserve at least 'size' bytes from section start */
-ST_FUNC void section_reserve(Section *sec, unsigned long size)
-{
-    if (size > sec->data_allocated)
-        section_realloc(sec, size);
-    if (size > sec->data_offset)
-        sec->data_offset = size;
-}
-
-/* return a reference to a section, and create it if it does not
-   exists */
-ST_FUNC Section *find_section(TCCState *s1, const char *name)
-{
-    Section *sec;
-    int i;
-    for(i = 1; i < s1->nb_sections; i++) {
-        sec = s1->sections[i];
-        if (!strcmp(name, sec->name)) 
-            return sec;
-    }
-    /* sections are created as PROGBITS */
-    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
-}
-
-/* update sym->c so that it points to an external symbol in section
-   'section' with value 'value' */
-ST_FUNC void put_extern_sym2(Sym *sym, Section *section, 
-                            addr_t value, unsigned long size,
-                            int can_add_underscore)
-{
-    int sym_type, sym_bind, sh_num, info, other;
-    ElfW(Sym) *esym;
-    const char *name;
-    char buf1[256];
-
-    if (section == NULL)
-        sh_num = SHN_UNDEF;
-    else if (section == SECTION_ABS) 
-        sh_num = SHN_ABS;
-    else
-        sh_num = section->sh_num;
-
-    if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
-        sym_type = STT_FUNC;
-    } else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
-        sym_type = STT_NOTYPE;
-    } else {
-        sym_type = STT_OBJECT;
-    }
-
-    if (sym->type.t & VT_STATIC)
-        sym_bind = STB_LOCAL;
-    else {
-        if (sym->type.t & VT_WEAK)
-            sym_bind = STB_WEAK;
-        else
-            sym_bind = STB_GLOBAL;
-    }
-
-    if (!sym->c) {
-        name = get_tok_str(sym->v, NULL);
-#ifdef CONFIG_TCC_BCHECK
-        if (tcc_state->do_bounds_check) {
-            char buf[32];
-
-            /* XXX: avoid doing that for statics ? */
-            /* if bound checking is activated, we change some function
-               names by adding the "__bound" prefix */
-            switch(sym->v) {
-#ifdef TCC_TARGET_PE
-            /* XXX: we rely only on malloc hooks */
-            case TOK_malloc: 
-            case TOK_free: 
-            case TOK_realloc: 
-            case TOK_memalign: 
-            case TOK_calloc: 
-#endif
-            case TOK_memcpy: 
-            case TOK_memmove:
-            case TOK_memset:
-            case TOK_strlen:
-            case TOK_strcpy:
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-            case TOK_alloca:
-#endif
-                strcpy(buf, "__bound_");
-                strcat(buf, name);
-                name = buf;
-                break;
-            }
-        }
-#endif
-        other = 0;
-
-#ifdef TCC_TARGET_PE
-        if (sym->type.t & VT_EXPORT)
-            other |= 1;
-        if (sym_type == STT_FUNC && sym->type.ref) {
-            int attr = sym->type.ref->r;
-            if (FUNC_EXPORT(attr))
-                other |= 1;
-            if (FUNC_CALL(attr) == FUNC_STDCALL && can_add_underscore) {
-                sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr) * PTR_SIZE);
-                name = buf1;
-                other |= 2;
-                can_add_underscore = 0;
-            }
-        } else {
-            if (find_elf_sym(tcc_state->dynsymtab_section, name))
-                other |= 4;
-            if (sym->type.t & VT_IMPORT)
-                other |= 4;
-        }
-#endif
-        if (tcc_state->leading_underscore && can_add_underscore) {
-            buf1[0] = '_';
-            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
-            name = buf1;
-        }
-        if (sym->asm_label) {
-            name = sym->asm_label;
-        }
-        info = ELFW(ST_INFO)(sym_bind, sym_type);
-        sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
-    } else {
-        esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
-        esym->st_value = value;
-        esym->st_size = size;
-        esym->st_shndx = sh_num;
-    }
-}
-
-ST_FUNC void put_extern_sym(Sym *sym, Section *section, 
-                           addr_t value, unsigned long size)
-{
-    put_extern_sym2(sym, section, value, size, 1);
-}
-
-/* add a new relocation entry to symbol 'sym' in section 's' */
-ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
-{
-    int c = 0;
-    if (sym) {
-        if (0 == sym->c)
-            put_extern_sym(sym, NULL, 0, 0);
-        c = sym->c;
-    }
-    /* now we can add ELF relocation info */
-    put_elf_reloc(symtab_section, s, offset, type, c);
 }
 
@@ -579,15 +478,16 @@
     char buf[2048];
     BufferedFile **pf, *f;
-    
+
     buf[0] = '\0';
     /* use upper file if inline ":asm:" or token ":paste:" */
-    for (f = file; f && f->filename[0] == ':'; f = f->prev);
+    for (f = file; f && f->filename[0] == ':'; f = f->prev)
+     ;
     if (f) {
         for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
             strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
                 (*pf)->filename, (*pf)->line_num);
-        if (f->line_num > 0) {
+        if (s1->error_set_jmp_enabled) {
             strcat_printf(buf, sizeof(buf), "%s:%d: ",
-                f->filename, f->line_num);
+                f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
         } else {
             strcat_printf(buf, sizeof(buf), "%s: ",
@@ -605,5 +505,10 @@
     if (!s1->error_func) {
         /* default case: stderr */
+        if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
+            /* print a newline during tcc -E */
+            printf("\n"), fflush(stdout);
+        fflush(stdout); /* flush -v output */
         fprintf(stderr, "%s\n", buf);
+        fflush(stderr); /* print error/warning now (win32) */
     } else {
         s1->error_func(s1->error_opaque, buf);
@@ -669,18 +574,16 @@
     int buflen = initlen ? initlen : IO_BUF_SIZE;
 
-    bf = tcc_malloc(sizeof(BufferedFile) + buflen);
+    bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
     bf->buf_ptr = bf->buffer;
     bf->buf_end = bf->buffer + initlen;
     bf->buf_end[0] = CH_EOB; /* put eob symbol */
     pstrcpy(bf->filename, sizeof(bf->filename), filename);
-#ifdef _WIN32
-    normalize_slashes(bf->filename);
-#endif
+    bf->true_filename = bf->filename;
     bf->line_num = 1;
-    bf->ifndef_macro = 0;
     bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
     bf->fd = -1;
     bf->prev = file;
     file = bf;
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
 }
 
@@ -692,4 +595,6 @@
         total_lines += bf->line_num;
     }
+    if (bf->true_filename != bf->filename)
+        tcc_free(bf->true_filename);
     file = bf->prev;
     tcc_free(bf);
@@ -700,5 +605,5 @@
     int fd;
     if (strcmp(filename, "-") == 0)
-        fd = 0, filename = "stdin";
+        fd = 0, filename = "<stdin>";
     else
         fd = open(filename, O_RDONLY | O_BINARY);
@@ -708,83 +613,22 @@
     if (fd < 0)
         return -1;
-
     tcc_open_bf(s1, filename, 0);
+#ifdef _WIN32
+    normalize_slashes(file->filename);
+#endif
     file->fd = fd;
     return fd;
 }
 
-/* compile the C file opened in 'file'. Return non zero if errors. */
+/* compile the file opened in 'file'. Return non zero if errors. */
 static int tcc_compile(TCCState *s1)
 {
     Sym *define_start;
-    SValue *pvtop;
-    char buf[512];
-    volatile int section_sym;
-
-#ifdef INC_DEBUG
-    printf("%s: **** new file\n", file->filename);
-#endif
-    preprocess_init(s1);
-
-    cur_text_section = NULL;
-    funcname = "";
-    anon_sym = SYM_FIRST_ANOM; 
-
-    /* file info: full path + filename */
-    section_sym = 0; /* avoid warning */
-    if (s1->do_debug) {
-        section_sym = put_elf_sym(symtab_section, 0, 0, 
-                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, 
-                                  text_section->sh_num, NULL);
-        getcwd(buf, sizeof(buf));
-#ifdef _WIN32
-        normalize_slashes(buf);
-#endif
-        pstrcat(buf, sizeof(buf), "/");
-        put_stabs_r(buf, N_SO, 0, 0, 
-                    text_section->data_offset, text_section, section_sym);
-        put_stabs_r(file->filename, N_SO, 0, 0, 
-                    text_section->data_offset, text_section, section_sym);
-    }
-    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
-       symbols can be safely used */
-    put_elf_sym(symtab_section, 0, 0, 
-                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, 
-                SHN_ABS, file->filename);
-
-    /* define some often used types */
-    int_type.t = VT_INT;
-
-    char_pointer_type.t = VT_BYTE;
-    mk_pointer(&char_pointer_type);
-
-#if PTR_SIZE == 4
-    size_type.t = VT_INT;
-#else
-    size_type.t = VT_LLONG;
-#endif
-
-    func_old_type.t = VT_FUNC;
-    func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
-#ifdef TCC_TARGET_ARM
-    arm_init_types();
-#endif
-
-#if 0
-    /* define 'void *alloca(unsigned int)' builtin function */
-    {
-        Sym *s1;
-
-        p = anon_sym++;
-        sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
-        s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
-        s1->next = NULL;
-        sym->next = s1;
-        sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
-    }
-#endif
+    int filetype, is_asm;
 
     define_start = define_stack;
-    nocode_wanted = 1;
+    filetype = s1->filetype;
+    is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
+    tccelf_begin_file(s1);
 
     if (setjmp(s1->error_jmp_buf) == 0) {
@@ -792,33 +636,26 @@
         s1->error_set_jmp_enabled = 1;
 
-        ch = file->buf_ptr[0];
-        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
-        parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
-        pvtop = vtop;
-        next();
-        decl(VT_CONST);
-        if (tok != TOK_EOF)
-            expect("declaration");
-        if (pvtop != vtop)
-            tcc_warning("internal compiler error: vstack leak? (%d)", vtop - pvtop);
-
-        /* end of translation unit info */
-        if (s1->do_debug) {
-            put_stabs_r(NULL, N_SO, 0, 0, 
-                        text_section->data_offset, text_section, section_sym);
+        preprocess_start(s1, is_asm);
+        if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+            tcc_preprocess(s1);
+        } else if (is_asm) {
+#ifdef CONFIG_TCC_ASM
+            tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
+#else
+            tcc_error_noabort("asm not supported");
+#endif
+        } else {
+            tccgen_compile(s1);
         }
     }
-
     s1->error_set_jmp_enabled = 0;
 
-    /* reset define stack, but leave -Dsymbols (may be incorrect if
-       they are undefined) */
-    free_defines(define_start); 
-
-    gen_inline_functions();
-
-    sym_pop(&global_stack, NULL);
-    sym_pop(&local_stack, NULL);
-
+    preprocess_end(s1);
+    free_inline_functions(s1);
+    /* reset define stack, but keep -D and built-ins */
+    free_defines(define_start);
+    sym_pop(&global_stack, NULL, 0);
+    sym_pop(&local_stack, NULL, 0);
+    tccelf_end_file(s1);
     return s1->nb_errors != 0 ? -1 : 0;
 }
@@ -827,6 +664,6 @@
 {
     int len, ret;
+
     len = strlen(str);
-
     tcc_open_bf(s, "<string>", len);
     memcpy(file->buffer, str, len);
@@ -853,8 +690,6 @@
 
     /* parse with define parser */
-    ch = file->buf_ptr[0];
     next_nomacro();
     parse_define();
-
     tcc_close();
 }
@@ -875,26 +710,14 @@
 static void tcc_cleanup(void)
 {
-    int i, n;
     if (NULL == tcc_state)
         return;
+    while (file)
+        tcc_close();
+    tccpp_delete(tcc_state);
     tcc_state = NULL;
-
-    /* free -D defines */
-    free_defines(NULL);
-
-    /* free tokens */
-    n = tok_ident - TOK_IDENT;
-    for(i = 0; i < n; i++)
-        tcc_free(table_ident[i]);
-    tcc_free(table_ident);
-
     /* free sym_pools */
     dynarray_reset(&sym_pools, &nb_sym_pools);
-    /* string buffer */
-    cstr_free(&tokcstr);
     /* reset symbol stack */
     sym_free_first = NULL;
-    /* cleanup from error/setjmp */
-    macro_ptr = NULL;
 }
 
@@ -902,6 +725,4 @@
 {
     TCCState *s;
-    char buffer[100];
-    int a,b,c;
 
     tcc_cleanup();
@@ -911,4 +732,21 @@
         return NULL;
     tcc_state = s;
+    ++nb_states;
+
+    s->alacarte_link = 1;
+    s->nocommon = 1;
+    s->warn_implicit_function_declaration = 1;
+    s->ms_extensions = 1;
+
+#ifdef CHAR_IS_UNSIGNED
+    s->char_is_unsigned = 1;
+#endif
+#ifdef TCC_TARGET_I386
+    s->seg_size = 32;
+#endif
+    /* enable this if you want symbols with leading underscore on windows: */
+#if 0 /* def TCC_TARGET_PE */
+    s->leading_underscore = 1;
+#endif
 #ifdef _WIN32
     tcc_set_lib_path_w32(s);
@@ -916,7 +754,6 @@
     tcc_set_lib_path(s, CONFIG_TCCDIR);
 #endif
-    s->output_type = TCC_OUTPUT_MEMORY;
-    preprocess_new();
-    s->include_stack_ptr = s->include_stack;
+    tccelf_new(s);
+    tccpp_new(s);
 
     /* we add dummy defines for some special macros to speed up tests
@@ -926,13 +763,17 @@
     define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
     define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
-
-    /* define __TINYC__ 92X  */
-    sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
-    sprintf(buffer, "%d", a*10000 + b*100 + c);
-    tcc_define_symbol(s, "__TINYC__", buffer);
+    define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
+    {
+        /* define __TINYC__ 92X  */
+        char buffer[32]; int a,b,c;
+        sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
+        sprintf(buffer, "%d", a*10000 + b*100 + c);
+        tcc_define_symbol(s, "__TINYC__", buffer);
+    }
 
     /* standard defines */
     tcc_define_symbol(s, "__STDC__", NULL);
     tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
+    tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
 
     /* target defines */
@@ -952,4 +793,18 @@
     tcc_define_symbol(s, "arm", NULL);
     tcc_define_symbol(s, "__APCS_32__", NULL);
+    tcc_define_symbol(s, "__ARMEL__", NULL);
+#if defined(TCC_ARM_EABI)
+    tcc_define_symbol(s, "__ARM_EABI__", NULL);
+#endif
+#if defined(TCC_ARM_HARDFLOAT)
+    s->float_abi = ARM_HARD_FLOAT;
+    tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
+#else
+    s->float_abi = ARM_SOFTFP_FLOAT;
+#endif
+#elif defined(TCC_TARGET_ARM64)
+    tcc_define_symbol(s, "__aarch64__", NULL);
+#elif defined TCC_TARGET_C67
+    tcc_define_symbol(s, "__C67__", NULL);
 #endif
 
@@ -963,76 +818,76 @@
     tcc_define_symbol(s, "__unix", NULL);
     tcc_define_symbol(s, "unix", NULL);
-# if defined(__linux)
+# if defined(__linux__)
     tcc_define_symbol(s, "__linux__", NULL);
     tcc_define_symbol(s, "__linux", NULL);
 # endif
 # if defined(__FreeBSD__)
-#  define str(s) #s
-    tcc_define_symbol(s, "__FreeBSD__", str( __FreeBSD__));
-#  undef str
+    tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__");
+    /* No 'Thread Storage Local' on FreeBSD with tcc */
+    tcc_define_symbol(s, "__NO_TLS", NULL);
 # endif
 # if defined(__FreeBSD_kernel__)
     tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
 # endif
+# if defined(__NetBSD__)
+    tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
+# endif
+# if defined(__OpenBSD__)
+    tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
+# endif
 #endif
 
     /* TinyCC & gcc defines */
-#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+#if PTR_SIZE == 4
+    /* 32bit systems. */
+    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
+    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
+    tcc_define_symbol(s, "__ILP32__", NULL);
+#elif LONG_SIZE == 4
+    /* 64bit Windows. */
     tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
     tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
+    tcc_define_symbol(s, "__LLP64__", NULL);
 #else
+    /* Other 64bit systems. */
     tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
     tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
+    tcc_define_symbol(s, "__LP64__", NULL);
 #endif
 
 #ifdef TCC_TARGET_PE
     tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
+    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
 #else
     tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
-#endif
-
-#ifndef TCC_TARGET_PE
+    /* wint_t is unsigned int by default, but (signed) int on BSDs
+       and unsigned short on windows.  Other OSes might have still
+       other conventions, sigh.  */
+# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
+  || defined(__NetBSD__) || defined(__OpenBSD__)
+    tcc_define_symbol(s, "__WINT_TYPE__", "int");
+#  ifdef __FreeBSD__
+    /* define __GNUC__ to have some useful stuff from sys/cdefs.h
+       that are unconditionally used in FreeBSDs other system headers :/ */
+    tcc_define_symbol(s, "__GNUC__", "2");
+    tcc_define_symbol(s, "__GNUC_MINOR__", "7");
+    tcc_define_symbol(s, "__builtin_alloca", "alloca");
+#  endif
+# else
+    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
     /* glibc defines */
-    tcc_define_symbol(s, "__REDIRECT(name, proto, alias)", "name proto __asm__ (#alias)");
-    tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)", "name proto __asm__ (#alias) __THROW");
-    /* default library paths */
-    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
-    /* paths for crt objects */
-    tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
-#endif
-
-    /* no section zero */
-    dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
-
-    /* create standard sections */
-    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
-    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
-    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
-
-    /* symbols are always generated for linking stage */
-    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
-                                ".strtab",
-                                ".hashtab", SHF_PRIVATE); 
-    strtab_section = symtab_section->link;
-    s->symtab = symtab_section;
-    
-    /* private symbol table for dynamic symbols */
-    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
-                                      ".dynstrtab", 
-                                      ".dynhashtab", SHF_PRIVATE);
-    s->alacarte_link = 1;
-    s->nocommon = 1;
-    s->section_align = ELF_PAGE_SIZE;
-
-#ifdef CHAR_IS_UNSIGNED
-    s->char_is_unsigned = 1;
-#endif
-    /* enable this if you want symbols with leading underscore on windows: */
-#if 0 //def TCC_TARGET_PE
-    s->leading_underscore = 1;
-#endif
-#ifdef TCC_TARGET_I386
-    s->seg_size = 32;
-#endif
+    tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
+        "name proto __asm__ (#alias)");
+    tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
+        "name proto __asm__ (#alias) __THROW");
+# endif
+# if defined(TCC_MUSL)
+    tcc_define_symbol(s, "__DEFINED_va_list", "");
+    tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
+    tcc_define_symbol(s, "__isoc_va_list", "void *");
+# endif /* TCC_MUSL */
+    /* Some GCC builtins that are simple to express as macros.  */
+    tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
+#endif /* ndef TCC_TARGET_PE */
     return s;
 }
@@ -1040,26 +895,8 @@
 LIBTCCAPI void tcc_delete(TCCState *s1)
 {
-    int i;
-
     tcc_cleanup();
 
-    /* free all sections */
-    for(i = 1; i < s1->nb_sections; i++)
-        free_section(s1->sections[i]);
-    dynarray_reset(&s1->sections, &s1->nb_sections);
-
-    for(i = 0; i < s1->nb_priv_sections; i++)
-        free_section(s1->priv_sections[i]);
-    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
-        
-    /* free any loaded DLLs */
-    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
-        DLLReference *ref = s1->loaded_dlls[i];
-        if ( ref->handle )
-            dlclose(ref->handle);
-    }
-    
-    /* free loaded dlls array */
-    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
+    /* free sections */
+    tccelf_delete(s1);
 
     /* free library paths */
@@ -1071,4 +908,5 @@
     dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
     dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
+    dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);
 
     tcc_free(s1->tcc_lib_path);
@@ -1081,20 +919,71 @@
     dynarray_reset(&s1->files, &s1->nb_files);
     dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
+    dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
+    dynarray_reset(&s1->argv, &s1->argc);
 
 #ifdef TCC_IS_NATIVE
-# ifdef HAVE_SELINUX
-    munmap (s1->write_mem, s1->mem_size);
-    munmap (s1->runtime_mem, s1->mem_size);    
-# else
-    tcc_free(s1->runtime_mem);
+    /* free runtime memory */
+    tcc_run_free(s1);
+#endif
+
+    tcc_free(s1);
+    if (0 == --nb_states)
+        tcc_memcheck();
+}
+
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
+{
+    s->output_type = output_type;
+
+    /* always elf for objects */
+    if (output_type == TCC_OUTPUT_OBJ)
+        s->output_format = TCC_OUTPUT_FORMAT_ELF;
+
+    if (s->char_is_unsigned)
+        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
+
+    if (!s->nostdinc) {
+        /* default include paths */
+        /* -isystem paths have already been handled */
+        tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
+    }
+
+#ifdef CONFIG_TCC_BCHECK
+    if (s->do_bounds_check) {
+        /* if bound checking, then add corresponding sections */
+        tccelf_bounds_new(s);
+        /* define symbol */
+        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
+    }
+#endif
+    if (s->do_debug) {
+        /* add debug sections */
+        tccelf_stab_new(s);
+    }
+
+    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
+
+#ifdef TCC_TARGET_PE
+# ifdef _WIN32
+    if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
+        tcc_add_systemdir(s);
 # endif
-#endif
-
-    tcc_free(s1);
+#else
+    /* paths for crt objects */
+    tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
+    /* add libc crt1/crti objects */
+    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
+        !s->nostdlib) {
+        if (output_type != TCC_OUTPUT_DLL)
+            tcc_add_crt(s, "crt1.o");
+        tcc_add_crt(s, "crti.o");
+    }
+#endif
+    return 0;
 }
 
 LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
 {
-    tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname);
+    tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
     return 0;
 }
@@ -1102,5 +991,5 @@
 LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
 {
-    tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
+    tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
     return 0;
 }
@@ -1108,18 +997,5 @@
 ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
 {
-    const char *ext;
-    ElfW(Ehdr) ehdr;
-    int fd, ret, size;
-
-    /* find source file type with extension */
-    ext = tcc_fileextension(filename);
-    if (ext[0])
-        ext++;
-
-#ifdef CONFIG_TCC_ASM
-    /* if .S file, define __ASSEMBLER__ like gcc does */
-    if (!strcmp(ext, "S"))
-        tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
-#endif
+    int ret;
 
     /* open the file */
@@ -1132,97 +1008,60 @@
 
     /* update target deps */
-    dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
+    dynarray_add(&s1->target_deps, &s1->nb_target_deps,
             tcc_strdup(filename));
 
-    if (flags & AFF_PREPROCESS) {
-        ret = tcc_preprocess(s1);
-        goto the_end;
-    }
-
-    if (!ext[0] || !PATHCMP(ext, "c")) {
-        /* C file assumed */
-        ret = tcc_compile(s1);
-        goto the_end;
-    }
-
-#ifdef CONFIG_TCC_ASM
-    if (!strcmp(ext, "S")) {
-        /* preprocessed assembler */
-        ret = tcc_assemble(s1, 1);
-        goto the_end;
-    }
-
-    if (!strcmp(ext, "s")) {
-        /* non preprocessed assembler */
-        ret = tcc_assemble(s1, 0);
-        goto the_end;
-    }
-#endif
-
-    fd = file->fd;
-    /* assume executable format: auto guess file type */
-    size = read(fd, &ehdr, sizeof(ehdr));
-    lseek(fd, 0, SEEK_SET);
-    if (size <= 0) {
-        tcc_error_noabort("could not read header");
-        goto the_end;
-    }
-
-    if (size == sizeof(ehdr) &&
-        ehdr.e_ident[0] == ELFMAG0 &&
-        ehdr.e_ident[1] == ELFMAG1 &&
-        ehdr.e_ident[2] == ELFMAG2 &&
-        ehdr.e_ident[3] == ELFMAG3) {
-
-        /* do not display line number if error */
-        file->line_num = 0;
-        if (ehdr.e_type == ET_REL) {
+    if (flags & AFF_TYPE_BIN) {
+        ElfW(Ehdr) ehdr;
+        int fd, obj_type;
+
+        fd = file->fd;
+        obj_type = tcc_object_type(fd, &ehdr);
+        lseek(fd, 0, SEEK_SET);
+
+#ifdef TCC_TARGET_MACHO
+        if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib"))
+            obj_type = AFF_BINTYPE_DYN;
+#endif
+
+        switch (obj_type) {
+        case AFF_BINTYPE_REL:
             ret = tcc_load_object_file(s1, fd, 0);
-            goto the_end;
-
-        }
+            break;
 #ifndef TCC_TARGET_PE
-        if (ehdr.e_type == ET_DYN) {
+        case AFF_BINTYPE_DYN:
             if (s1->output_type == TCC_OUTPUT_MEMORY) {
+                ret = 0;
 #ifdef TCC_IS_NATIVE
-                void *h;
-                h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
-                if (h)
-#endif
-                    ret = 0;
+                if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
+                    ret = -1;
+#endif
             } else {
-                ret = tcc_load_dll(s1, fd, filename, 
+                ret = tcc_load_dll(s1, fd, filename,
                                    (flags & AFF_REFERENCED_DLL) != 0);
             }
-            goto the_end;
+            break;
+#endif
+        case AFF_BINTYPE_AR:
+            ret = tcc_load_archive(s1, fd);
+            break;
+#ifdef TCC_TARGET_COFF
+        case AFF_BINTYPE_C67:
+            ret = tcc_load_coff(s1, fd);
+            break;
+#endif
+        default:
+#ifdef TCC_TARGET_PE
+            ret = pe_load_file(s1, filename, fd);
+#else
+            /* as GNU ld, consider it is an ld script if not recognized */
+            ret = tcc_load_ldscript(s1);
+#endif
+            if (ret < 0)
+                tcc_error_noabort("unrecognized file type");
+            break;
         }
-#endif
-        tcc_error_noabort("unrecognized ELF file");
-        goto the_end;
-    }
-
-    if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
-        file->line_num = 0; /* do not display line number if error */
-        ret = tcc_load_archive(s1, fd);
-        goto the_end;
-    }
-
-#ifdef TCC_TARGET_COFF
-    if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
-        ret = tcc_load_coff(s1, fd);
-        goto the_end;
-    }
-#endif
-
-#ifdef TCC_TARGET_PE
-    ret = pe_load_file(s1, filename, fd);
-#else
-    /* as GNU ld, consider it is an ld script if not recognized */
-    ret = tcc_load_ldscript(s1);
-#endif
-    if (ret < 0)
-        tcc_error_noabort("unrecognized file type");
-
-the_end:
+    } else {
+        ret = tcc_compile(s1);
+    }
     tcc_close();
     return ret;
@@ -1231,13 +1070,30 @@
 LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
 {
-    if (s->output_type == TCC_OUTPUT_PREPROCESS)
-        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
-    else
-        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
+    int filetype = s->filetype;
+    int flags = AFF_PRINT_ERROR;
+    if (filetype == 0) {
+        /* use a file extension to detect a filetype */
+        const char *ext = tcc_fileextension(filename);
+        if (ext[0]) {
+            ext++;
+            if (!strcmp(ext, "S"))
+                filetype = AFF_TYPE_ASMPP;
+            else if (!strcmp(ext, "s"))
+                filetype = AFF_TYPE_ASM;
+            else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
+                filetype = AFF_TYPE_C;
+            else
+                flags |= AFF_TYPE_BIN;
+        } else {
+            filetype = AFF_TYPE_C;
+        }
+        s->filetype = filetype;
+    }
+    return tcc_add_file_internal(s, filename, flags);
 }
 
 LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
 {
-    tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname);
+    tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
     return 0;
 }
@@ -1251,5 +1107,5 @@
     for(i = 0; i < nb_paths; i++) {
         snprintf(buf, sizeof(buf), fmt, paths[i], filename);
-        if (tcc_add_file_internal(s, buf, flags) == 0)
+        if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
             return 0;
     }
@@ -1276,7 +1132,10 @@
 LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
 {
-#ifdef TCC_TARGET_PE
+#if defined TCC_TARGET_PE
     const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
     const char **pp = s->static_link ? libs + 4 : libs;
+#elif defined TCC_TARGET_MACHO
+    const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
+    const char **pp = s->static_link ? libs + 1 : libs;
 #else
     const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
@@ -1292,4 +1151,20 @@
 }
 
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
+{
+    int ret = tcc_add_library(s, libname);
+    if (ret < 0)
+        tcc_error_noabort("library '%s' not found", libname);
+    return ret;
+}
+
+/* handle #pragma comment(lib,) */
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
+{
+    int i;
+    for (i = 0; i < s1->nb_pragma_libs; i++)
+        tcc_add_library_err(s1, s1->pragma_libs[i]);
+}
+
 LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
 {
@@ -1299,65 +1174,7 @@
     pe_putimport(s, 0, name, (uintptr_t)val);
 #else
-    /* XXX: Same problem on linux but currently "solved" elsewhere
-       via the rather dirty 'runtime_plt_and_got' hack. */
-    add_elf_sym(symtab_section, (uintptr_t)val, 0,
+    set_elf_sym(symtab_section, (uintptr_t)val, 0,
         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
         SHN_ABS, name);
-#endif
-    return 0;
-}
-
-LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
-{
-    s->output_type = output_type;
-
-    if (!s->nostdinc) {
-        /* default include paths */
-        /* -isystem paths have already been handled */
-        tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
-    }
-
-    /* if bound checking, then add corresponding sections */
-#ifdef CONFIG_TCC_BCHECK
-    if (s->do_bounds_check) {
-        /* define symbol */
-        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
-        /* create bounds sections */
-        bounds_section = new_section(s, ".bounds", 
-                                     SHT_PROGBITS, SHF_ALLOC);
-        lbounds_section = new_section(s, ".lbounds", 
-                                      SHT_PROGBITS, SHF_ALLOC);
-    }
-#endif
-
-    if (s->char_is_unsigned) {
-        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
-    }
-
-    /* add debug sections */
-    if (s->do_debug) {
-        /* stab symbols */
-        stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
-        stab_section->sh_entsize = sizeof(Stab_Sym);
-        stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
-        put_elf_str(stabstr_section, "");
-        stab_section->link = stabstr_section;
-        /* put first entry */
-        put_stabs("", 0, 0, 0, 0);
-    }
-
-#ifdef TCC_TARGET_PE
-    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
-# ifdef _WIN32
-    tcc_add_systemdir(s);
-# endif
-#else
-    /* add libc crt1/crti objects */
-    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
-        !s->nostdlib) {
-        if (output_type != TCC_OUTPUT_DLL)
-            tcc_add_crt(s, "crt1.o");
-        tcc_add_crt(s, "crti.o");
-    }
 #endif
     return 0;
@@ -1379,68 +1196,43 @@
 } FlagDef;
 
-static const FlagDef warning_defs[] = {
-    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
-    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
-    { offsetof(TCCState, warn_error), 0, "error" },
-    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
-      "implicit-function-declaration" },
-};
-
-ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
-                    const char *name, int value)
-{
-    int i;
+static int no_flag(const char **pp)
+{
+    const char *p = *pp;
+    if (*p != 'n' || *++p != 'o' || *++p != '-')
+        return 0;
+    *pp = p + 1;
+    return 1;
+}
+
+ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
+{
+    int value, ret;
     const FlagDef *p;
     const char *r;
 
+    value = 1;
     r = name;
-    if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
-        r += 3;
-        value = !value;
-    }
-    for(i = 0, p = flags; i < nb_flags; i++, p++) {
-        if (!strcmp(r, p->name))
-            goto found;
-    }
-    return -1;
- found:
-    if (p->flags & FD_INVERT)
-        value = !value;
-    *(int *)((uint8_t *)s + p->offset) = value;
-    return 0;
-}
-
-/* set/reset a warning */
-static int tcc_set_warning(TCCState *s, const char *warning_name, int value)
-{
-    int i;
-    const FlagDef *p;
-
-    if (!strcmp(warning_name, "all")) {
-        for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
-            if (p->flags & WD_ALL)
-                *(int *)((uint8_t *)s + p->offset) = 1;
+    if (no_flag(&r))
+        value = 0;
+
+    for (ret = -1, p = flags; p->name; ++p) {
+        if (ret) {
+            if (strcmp(r, p->name))
+                continue;
+        } else {
+            if (0 == (p->flags & WD_ALL))
+                continue;
         }
-        return 0;
-    } else {
-        return set_flag(s, warning_defs, countof(warning_defs),
-                        warning_name, value);
-    }
-}
-
-static const FlagDef flag_defs[] = {
-    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
-    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
-    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
-    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
-};
-
-/* set/reset a flag */
-static int tcc_set_flag(TCCState *s, const char *flag_name, int value)
-{
-    return set_flag(s, flag_defs, countof(flag_defs),
-                    flag_name, value);
-}
-
+        if (p->offset) {
+            *(int*)((char *)s + p->offset) =
+                p->flags & FD_INVERT ? !value : value;
+            if (ret)
+                return 0;
+        } else {
+            ret = 0;
+        }
+    }
+    return ret;
+}
 
 static int strstart(const char *val, const char **str)
@@ -1470,4 +1262,5 @@
 {
     const char *p, *q;
+    int ret;
 
     /* there should be 1 or 2 dashes */
@@ -1477,7 +1270,14 @@
         str++;
 
-    /* then str & val should match (potentialy up to '=') */
+    /* then str & val should match (potentially up to '=') */
     p = str;
     q = val;
+
+    ret = 1;
+    if (q[0] == '?') {
+        ++q;
+        if (no_flag(&p))
+            ret = -1;
+    }
 
     while (*q != '\0' && *q != '=') {
@@ -1490,13 +1290,14 @@
     /* '=' near eos means ',' or '=' is ok */
     if (*q == '=') {
+        if (*p == 0)
+            *ptr = p;
         if (*p != ',' && *p != '=')
             return 0;
         p++;
-        q++;
-    }
-
-    if (ptr)
-        *ptr = p;
-    return 1;
+    } else if (*p) {
+        return 0;
+    }
+    *ptr = p;
+    return ret;
 }
 
@@ -1509,9 +1310,13 @@
 }
 
-static char *copy_linker_arg(const char *p)
-{
-    const char *q = p;
+static void copy_linker_arg(char **pp, const char *s, int sep)
+{
+    const char *q = s;
+    char *p = *pp;
+    int l = 0;
+    if (p && sep)
+        p[l = strlen(p)] = sep, ++l;
     skip_linker_arg(&q);
-    return pstrncpy(tcc_malloc(q - p + 1), p, q - p);
+    pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
 }
 
@@ -1519,9 +1324,10 @@
 static int tcc_set_linker(TCCState *s, const char *option)
 {
-    while (option && *option) {
-
-        const char *p = option;
+    while (*option) {
+
+        const char *p = NULL;
         char *end = NULL;
         int ignoring = 0;
+        int ret;
 
         if (link_option(option, "Bsymbolic", &p)) {
@@ -1530,5 +1336,5 @@
             s->nostdlib = 1;
         } else if (link_option(option, "fini=", &p)) {
-            s->fini_symbol = copy_linker_arg(p);
+            copy_linker_arg(&s->fini_symbol, p, 0);
             ignoring = 1;
         } else if (link_option(option, "image-base=", &p)
@@ -1537,10 +1343,10 @@
             s->has_text_addr = 1;
         } else if (link_option(option, "init=", &p)) {
-            s->init_symbol = copy_linker_arg(p);
+            copy_linker_arg(&s->init_symbol, p, 0);
             ignoring = 1;
         } else if (link_option(option, "oformat=", &p)) {
 #if defined(TCC_TARGET_PE)
             if (strstart("pe-", &p)) {
-#elif defined(TCC_TARGET_X86_64)
+#elif PTR_SIZE == 8
             if (strstart("elf64-", &p)) {
 #else
@@ -1557,11 +1363,21 @@
                 goto err;
 
+        } else if (link_option(option, "as-needed", &p)) {
+            ignoring = 1;
+        } else if (link_option(option, "O", &p)) {
+            ignoring = 1;
+        } else if (link_option(option, "export-all-symbols", &p)) {
+            s->rdynamic = 1;
         } else if (link_option(option, "rpath=", &p)) {
-            s->rpath = copy_linker_arg(p);
+            copy_linker_arg(&s->rpath, p, ':');
+        } else if (link_option(option, "enable-new-dtags", &p)) {
+            s->enable_new_dtags = 1;
         } else if (link_option(option, "section-alignment=", &p)) {
             s->section_align = strtoul(p, &end, 16);
         } else if (link_option(option, "soname=", &p)) {
-            s->soname = copy_linker_arg(p);
+            copy_linker_arg(&s->soname, p, 0);
 #ifdef TCC_TARGET_PE
+        } else if (link_option(option, "large-address-aware", &p)) {
+            s->pe_characteristics |= 0x20;
         } else if (link_option(option, "file-alignment=", &p)) {
             s->pe_file_align = strtoul(p, &end, 16);
@@ -1574,5 +1390,5 @@
             } else if (!strcmp(p, "console")) {
                 s->pe_subsystem = 3;
-            } else if (!strcmp(p, "gui")) {
+            } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
                 s->pe_subsystem = 2;
             } else if (!strcmp(p, "posix")) {
@@ -1593,18 +1409,19 @@
                 goto err;
 #endif
-        } else
-            goto err;
-
-        if (ignoring && s->warn_unsupported) err: {
-            char buf[100], *e;
-            pstrcpy(buf, sizeof buf, e = copy_linker_arg(option)), tcc_free(e);
-            if (ignoring)
-                tcc_warning("unsupported linker option '%s'", buf);
-            else
-                tcc_error("unsupported linker option '%s'", buf);
+        } else if (ret = link_option(option, "?whole-archive", &p), ret) {
+            s->alacarte_link = ret < 0;
+        } else if (p) {
+            return 0;
+        } else {
+    err:
+            tcc_error("unsupported linker option '%s'", option);
         }
+
+        if (ignoring && s->warn_unsupported)
+            tcc_warning("unsupported linker option '%s'", option);
+
         option = skip_linker_arg(&p);
     }
-    return 0;
+    return 1;
 }
 
@@ -1617,7 +1434,10 @@
 enum {
     TCC_OPTION_HELP,
+    TCC_OPTION_HELP2,
+    TCC_OPTION_v,
     TCC_OPTION_I,
     TCC_OPTION_D,
     TCC_OPTION_U,
+    TCC_OPTION_P,
     TCC_OPTION_L,
     TCC_OPTION_B,
@@ -1628,5 +1448,8 @@
     TCC_OPTION_g,
     TCC_OPTION_c,
+    TCC_OPTION_dumpversion,
+    TCC_OPTION_d,
     TCC_OPTION_static,
+    TCC_OPTION_std,
     TCC_OPTION_shared,
     TCC_OPTION_soname,
@@ -1634,18 +1457,23 @@
     TCC_OPTION_r,
     TCC_OPTION_s,
+    TCC_OPTION_traditional,
     TCC_OPTION_Wl,
+    TCC_OPTION_Wp,
     TCC_OPTION_W,
     TCC_OPTION_O,
+    TCC_OPTION_mfloat_abi,
     TCC_OPTION_m,
     TCC_OPTION_f,
     TCC_OPTION_isystem,
+    TCC_OPTION_iwithprefix,
+    TCC_OPTION_include,
     TCC_OPTION_nostdinc,
     TCC_OPTION_nostdlib,
     TCC_OPTION_print_search_dirs,
     TCC_OPTION_rdynamic,
+    TCC_OPTION_param,
     TCC_OPTION_pedantic,
     TCC_OPTION_pthread,
     TCC_OPTION_run,
-    TCC_OPTION_v,
     TCC_OPTION_w,
     TCC_OPTION_pipe,
@@ -1654,5 +1482,6 @@
     TCC_OPTION_MF,
     TCC_OPTION_x,
-    TCC_OPTION_dumpversion,
+    TCC_OPTION_ar,
+    TCC_OPTION_impdef
 };
 
@@ -1664,7 +1493,10 @@
     { "-help", TCC_OPTION_HELP, 0 },
     { "?", TCC_OPTION_HELP, 0 },
+    { "hh", TCC_OPTION_HELP2, 0 },
+    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
     { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
     { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
+    { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
     { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
@@ -1679,8 +1511,12 @@
     { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "c", TCC_OPTION_c, 0 },
+    { "dumpversion", TCC_OPTION_dumpversion, 0},
+    { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "static", TCC_OPTION_static, 0 },
+    { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "shared", TCC_OPTION_shared, 0 },
     { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
     { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
+    { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG },
     { "pedantic", TCC_OPTION_pedantic, 0},
     { "pthread", TCC_OPTION_pthread, 0},
@@ -1689,14 +1525,19 @@
     { "r", TCC_OPTION_r, 0 },
     { "s", TCC_OPTION_s, 0 },
+    { "traditional", TCC_OPTION_traditional, 0 },
     { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
-    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
+#ifdef TCC_TARGET_ARM
+    { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
+#endif
+    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
     { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
+    { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
     { "nostdinc", TCC_OPTION_nostdinc, 0 },
     { "nostdlib", TCC_OPTION_nostdlib, 0 },
-    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, 
-    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
     { "w", TCC_OPTION_w, 0 },
     { "pipe", TCC_OPTION_pipe, 0},
@@ -1705,6 +1546,38 @@
     { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
     { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
-    { "dumpversion", TCC_OPTION_dumpversion, 0},
+    { "ar", TCC_OPTION_ar, 0},
+#ifdef TCC_TARGET_PE
+    { "impdef", TCC_OPTION_impdef, 0},
+#endif
     { NULL, 0, 0 },
+};
+
+static const FlagDef options_W[] = {
+    { 0, 0, "all" },
+    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
+    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
+    { offsetof(TCCState, warn_error), 0, "error" },
+    { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
+    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
+      "implicit-function-declaration" },
+    { 0, 0, NULL }
+};
+
+static const FlagDef options_f[] = {
+    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
+    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
+    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
+    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
+    { offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
+    { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
+    { 0, 0, NULL }
+};
+
+static const FlagDef options_m[] = {
+    { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" },
+#ifdef TCC_TARGET_X86_64
+    { offsetof(TCCState, nosse), FD_INVERT, "sse" },
+#endif
+    { 0, 0, NULL }
 };
 
@@ -1719,25 +1592,107 @@
 }
 
-PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
+static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
+{
+    struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
+    f->type = filetype;
+    f->alacarte = s->alacarte_link;
+    strcpy(f->name, filename);
+    dynarray_add(&s->files, &s->nb_files, f);
+}
+
+static int args_parser_make_argv(const char *r, int *argc, char ***argv)
+{
+    int ret = 0, q, c;
+    CString str;
+    for(;;) {
+        while (c = (unsigned char)*r, c && c <= ' ')
+	    ++r;
+        if (c == 0)
+            break;
+        q = 0;
+        cstr_new(&str);
+        while (c = (unsigned char)*r, c) {
+            ++r;
+            if (c == '\\' && (*r == '"' || *r == '\\')) {
+                c = *r++;
+            } else if (c == '"') {
+                q = !q;
+                continue;
+            } else if (q == 0 && c <= ' ') {
+                break;
+            }
+            cstr_ccat(&str, c);
+        }
+        cstr_ccat(&str, 0);
+        //printf("<%s>\n", str.data), fflush(stdout);
+        dynarray_add(argv, argc, tcc_strdup(str.data));
+        cstr_free(&str);
+        ++ret;
+    }
+    return ret;
+}
+
+/* read list file */
+static void args_parser_listfile(TCCState *s,
+    const char *filename, int optind, int *pargc, char ***pargv)
+{
+    int fd, i;
+    size_t len;
+    char *p;
+    int argc = 0;
+    char **argv = NULL;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        tcc_error("listfile '%s' not found", filename);
+
+    len = lseek(fd, 0, SEEK_END);
+    p = tcc_malloc(len + 1), p[len] = 0;
+    lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);
+
+    for (i = 0; i < *pargc; ++i)
+        if (i == optind)
+            args_parser_make_argv(p, &argc, &argv);
+        else
+            dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
+
+    tcc_free(p);
+    dynarray_reset(&s->argv, &s->argc);
+    *pargc = s->argc = argc, *pargv = s->argv = argv;
+}
+
+PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
 {
     const TCCOption *popt;
     const char *optarg, *r;
-    int run = 0;
-    int pthread = 0;
-    int optind = 0;
-
-    /* collect -Wl options for input such as "-Wl,-rpath -Wl,<path>" */
-    CString linker_arg;
+    const char *run = NULL;
+    int last_o = -1;
+    int x;
+    CString linker_arg; /* collect -Wl options */
+    int tool = 0, arg_start = 0, noaction = optind;
+    char **argv = *pargv;
+    int argc = *pargc;
+
     cstr_new(&linker_arg);
 
     while (optind < argc) {
-
-        r = argv[optind++];
+        r = argv[optind];
+        if (r[0] == '@' && r[1] != '\0') {
+            args_parser_listfile(s, r + 1, optind, &argc, &argv);
+	    continue;
+        }
+        optind++;
+        if (tool) {
+            if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
+                ++s->verbose;
+            continue;
+        }
+reparse:
         if (r[0] != '-' || r[1] == '\0') {
-            /* add a new file */
-            dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
+            if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
+                args_parser_add_file(s, r, s->filetype);
             if (run) {
-                optind--;
-                /* argv[0] will be this file */
+                tcc_set_options(s, run);
+                arg_start = optind - 1;
                 break;
             }
@@ -1757,4 +1712,5 @@
                 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
                     if (optind >= argc)
+                arg_err:
                         tcc_error("argument to '%s' is missing", r);
                     optarg = argv[optind++];
@@ -1767,8 +1723,9 @@
         switch(popt->index) {
         case TCC_OPTION_HELP:
-            return 0;
+            return OPT_HELP;
+        case TCC_OPTION_HELP2:
+            return OPT_HELP2;
         case TCC_OPTION_I:
-            if (tcc_add_include_path(s, optarg) < 0)
-                tcc_error("too many include paths");
+            tcc_add_include_path(s, optarg);
             break;
         case TCC_OPTION_D:
@@ -1786,10 +1743,10 @@
             break;
         case TCC_OPTION_l:
-            dynarray_add((void ***)&s->files, &s->nb_files, tcc_strdup(r));
+            args_parser_add_file(s, optarg, AFF_TYPE_LIB);
             s->nb_libraries++;
             break;
         case TCC_OPTION_pthread:
             parse_option_D(s, "_REENTRANT");
-            pthread = 1;
+            s->option_pthread = 1;
             break;
         case TCC_OPTION_bench:
@@ -1811,19 +1768,40 @@
             break;
         case TCC_OPTION_c:
-            s->output_type = TCC_OUTPUT_OBJ;
+            x = TCC_OUTPUT_OBJ;
+        set_output_type:
+            if (s->output_type)
+                tcc_warning("-%s: overriding compiler action already specified", popt->name);
+            s->output_type = x;
+            break;
+        case TCC_OPTION_d:
+            if (*optarg == 'D')
+                s->dflag = 3;
+            else if (*optarg == 'M')
+                s->dflag = 7;
+            else if (*optarg == 't')
+                s->dflag = 16;
+            else if (isnum(*optarg))
+                g_debug = atoi(optarg);
+            else
+                goto unsupported_option;
             break;
         case TCC_OPTION_static:
             s->static_link = 1;
             break;
+        case TCC_OPTION_std:
+    	    /* silently ignore, a current purpose:
+    	       allow to use a tcc as a reference compiler for "make test" */
+            break;
         case TCC_OPTION_shared:
-            s->output_type = TCC_OUTPUT_DLL;
-            break;
+            x = TCC_OUTPUT_DLL;
+            goto set_output_type;
         case TCC_OPTION_soname:
             s->soname = tcc_strdup(optarg);
             break;
-        case TCC_OPTION_m:
-            s->option_m = tcc_strdup(optarg);
-            break;
         case TCC_OPTION_o:
+            if (s->outfile) {
+                tcc_warning("multiple -o option");
+                tcc_free(s->outfile);
+            }
             s->outfile = tcc_strdup(optarg);
             break;
@@ -1831,9 +1809,13 @@
             /* generate a .o merging several output files */
             s->option_r = 1;
-            s->output_type = TCC_OUTPUT_OBJ;
-            break;
+            x = TCC_OUTPUT_OBJ;
+            goto set_output_type;
         case TCC_OPTION_isystem:
             tcc_add_sysinclude_path(s, optarg);
             break;
+	case TCC_OPTION_include:
+	    dynarray_add(&s->cmd_include_files,
+			 &s->nb_cmd_include_files, tcc_strdup(optarg));
+	    break;
         case TCC_OPTION_nostdinc:
             s->nostdinc = 1;
@@ -1842,22 +1824,42 @@
             s->nostdlib = 1;
             break;
-        case TCC_OPTION_print_search_dirs:
-            s->print_search_dirs = 1;
-            break;
         case TCC_OPTION_run:
-            s->output_type = TCC_OUTPUT_MEMORY;
-            tcc_set_options(s, optarg);
-            run = 1;
-            break;
+#ifndef TCC_IS_NATIVE
+            tcc_error("-run is not available in a cross compiler");
+#endif
+            run = optarg;
+            x = TCC_OUTPUT_MEMORY;
+            goto set_output_type;
         case TCC_OPTION_v:
             do ++s->verbose; while (*optarg++ == 'v');
+            ++noaction;
             break;
         case TCC_OPTION_f:
-            if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
+            if (set_flag(s, options_f, optarg) < 0)
                 goto unsupported_option;
             break;
+#ifdef TCC_TARGET_ARM
+        case TCC_OPTION_mfloat_abi:
+            /* tcc doesn't support soft float yet */
+            if (!strcmp(optarg, "softfp")) {
+                s->float_abi = ARM_SOFTFP_FLOAT;
+                tcc_undefine_symbol(s, "__ARM_PCS_VFP");
+            } else if (!strcmp(optarg, "hard"))
+                s->float_abi = ARM_HARD_FLOAT;
+            else
+                tcc_error("unsupported float abi '%s'", optarg);
+            break;
+#endif
+        case TCC_OPTION_m:
+            if (set_flag(s, options_m, optarg) < 0) {
+                if (x = atoi(optarg), x != 32 && x != 64)
+                    goto unsupported_option;
+                if (PTR_SIZE != x/8)
+                    return x;
+                ++noaction;
+            }
+            break;
         case TCC_OPTION_W:
-            if (tcc_set_warning(s, optarg, 1) < 0 && 
-                s->warn_unsupported)
+            if (set_flag(s, options_W, optarg) < 0)
                 goto unsupported_option;
             break;
@@ -1871,9 +1873,16 @@
             if (linker_arg.size)
                 --linker_arg.size, cstr_ccat(&linker_arg, ',');
-            cstr_cat(&linker_arg, optarg);
-            cstr_ccat(&linker_arg, '\0');
-            break;
+            cstr_cat(&linker_arg, optarg, 0);
+            if (tcc_set_linker(s, linker_arg.data))
+                cstr_free(&linker_arg);
+            break;
+	case TCC_OPTION_Wp:
+	    r = optarg;
+	    goto reparse;
         case TCC_OPTION_E:
-            s->output_type = TCC_OUTPUT_PREPROCESS;
+            x = TCC_OUTPUT_PREPROCESS;
+            goto set_output_type;
+        case TCC_OPTION_P:
+            s->Pflag = atoi(optarg) + 1;
             break;
         case TCC_OPTION_MD:
@@ -1886,66 +1895,87 @@
             printf ("%s\n", TCC_VERSION);
             exit(0);
+            break;
+        case TCC_OPTION_x:
+            if (*optarg == 'c')
+                s->filetype = AFF_TYPE_C;
+            else if (*optarg == 'a')
+                s->filetype = AFF_TYPE_ASMPP;
+            else if (*optarg == 'n')
+                s->filetype = AFF_TYPE_NONE;
+            else
+                tcc_warning("unsupported language '%s'", optarg);
+            break;
         case TCC_OPTION_O:
+            last_o = atoi(optarg);
+            break;
+        case TCC_OPTION_print_search_dirs:
+            x = OPT_PRINT_DIRS;
+            goto extra_action;
+        case TCC_OPTION_impdef:
+            x = OPT_IMPDEF;
+            goto extra_action;
+        case TCC_OPTION_ar:
+            x = OPT_AR;
+        extra_action:
+            arg_start = optind - 1;
+            if (arg_start != noaction)
+                tcc_error("cannot parse %s here", r);
+            tool = x;
+            break;
+        case TCC_OPTION_traditional:
         case TCC_OPTION_pedantic:
         case TCC_OPTION_pipe:
         case TCC_OPTION_s:
-        case TCC_OPTION_x:
             /* ignored */
             break;
         default:
-            if (s->warn_unsupported) {
-            unsupported_option:
+unsupported_option:
+            if (s->warn_unsupported)
                 tcc_warning("unsupported option '%s'", r);
-            }
             break;
         }
     }
-
-    if (pthread && s->output_type != TCC_OUTPUT_OBJ)
-        tcc_set_options(s, "-lpthread");
-
-    tcc_set_linker(s, (const char *)linker_arg.data);
-    cstr_free(&linker_arg);
-
-    return optind;
-}
-
-LIBTCCAPI int tcc_set_options(TCCState *s, const char *str)
-{
-    const char *s1;
-    char **argv, *arg;
-    int argc, len;
-    int ret;
-
-    argc = 0, argv = NULL;
-    for(;;) {
-        while (is_space(*str))
-            str++;
-        if (*str == '\0')
-            break;
-        s1 = str;
-        while (*str != '\0' && !is_space(*str))
-            str++;
-        len = str - s1;
-        arg = tcc_malloc(len + 1);
-        pstrncpy(arg, s1, len);
-        dynarray_add((void ***)&argv, &argc, arg);
-    }
-    ret = tcc_parse_args(s, argc, argv);
+    if (last_o > 0)
+        tcc_define_symbol(s, "__OPTIMIZE__", NULL);
+    if (linker_arg.size) {
+        r = linker_arg.data;
+        goto arg_err;
+    }
+    *pargc = argc - arg_start;
+    *pargv = argv + arg_start;
+    if (tool)
+        return tool;
+    if (optind != noaction)
+        return 0;
+    if (s->verbose == 2)
+        return OPT_PRINT_DIRS;
+    if (s->verbose)
+        return OPT_V;
+    return OPT_HELP;
+}
+
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
+{
+    char **argv = NULL;
+    int argc = 0;
+    args_parser_make_argv(r, &argc, &argv);
+    tcc_parse_args(s, &argc, &argv, 0);
     dynarray_reset(&argv, &argc);
-    return ret;
-}
-
-PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
-{
-    double tt;
-    tt = (double)total_time / 1000000.0;
-    if (tt < 0.001)
-        tt = 0.001;
+}
+
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
+{
+    if (total_time < 1)
+        total_time = 1;
     if (total_bytes < 1)
         total_bytes = 1;
-    printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", 
+    fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
+                    "* %0.3f s, %u lines/s, %0.1f MB/s\n",
            tok_ident - TOK_IDENT, total_lines, total_bytes,
-           tt, (int)(total_lines / tt),
-           total_bytes / tt / 1000000.0);
-}
+           (double)total_time/1000,
+           (unsigned)total_lines*1000/total_time,
+           (double)total_bytes/1000/total_time);
+#ifdef MEM_DEBUG
+    fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/libtcc.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h	(revision 331)
@@ -28,5 +28,5 @@
 
 /* set options as from command line (multiple supported) */
-LIBTCCAPI int tcc_set_options(TCCState *s, const char *str);
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
 
 /*****************************/
@@ -59,9 +59,9 @@
 /* set output type. MUST BE CALLED before any compilation */
 LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
-#define TCC_OUTPUT_MEMORY   0 /* output will be run in memory (default) */
-#define TCC_OUTPUT_EXE      1 /* executable file */
-#define TCC_OUTPUT_DLL      2 /* dynamic library */
-#define TCC_OUTPUT_OBJ      3 /* object file */
-#define TCC_OUTPUT_PREPROCESS 4 /* only preprocess (used internally) */
+#define TCC_OUTPUT_MEMORY   1 /* output will be run in memory (default) */
+#define TCC_OUTPUT_EXE      2 /* executable file */
+#define TCC_OUTPUT_DLL      3 /* dynamic library */
+#define TCC_OUTPUT_OBJ      4 /* object file */
+#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
 
 /* equivalent to -Lpath option */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcc-doc.html	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html	(revision 331)
@@ -1,1266 +1,1310 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
-<html>
-<!-- Created on February 15, 2013 by texi2html 1.82
-texi2html was written by: 
-            Lionel Cons <Lionel.Cons@cern.ch> (original author)
-            Karl Berry  <karl@freefriends.org>
-            Olaf Bachmann <obachman@mathematik.uni-kl.de>
-            and many others.
-Maintained by: Many creative people.
-Send bugs and suggestions to <texi2html-bug@nongnu.org>
+<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Created on December, 17  2017 by texi2html 1.64 -->
+<!-- 
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+			Karl Berry  <karl@freefriends.org>
+			Olaf Bachmann <obachman@mathematik.uni-kl.de>
+			and many others.
+Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
+Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
+ 
 -->
-<head>
-<title>Tiny C Compiler Reference Documentation</title>
-
-<meta name="description" content="Tiny C Compiler Reference Documentation">
-<meta name="keywords" content="Tiny C Compiler Reference Documentation">
-<meta name="resource-type" content="document">
-<meta name="distribution" content="global">
-<meta name="Generator" content="texi2html 1.82">
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<style type="text/css">
-<!--
-a.summary-letter {text-decoration: none}
-blockquote.smallquotation {font-size: smaller}
-pre.display {font-family: serif}
-pre.format {font-family: serif}
-pre.menu-comment {font-family: serif}
-pre.menu-preformatted {font-family: serif}
-pre.smalldisplay {font-family: serif; font-size: smaller}
-pre.smallexample {font-size: smaller}
-pre.smallformat {font-family: serif; font-size: smaller}
-pre.smalllisp {font-size: smaller}
-span.roman {font-family:serif; font-weight:normal;}
-span.sansserif {font-family:sans-serif; font-weight:normal;}
-ul.toc {list-style: none}
--->
-</style>
-
-
-</head>
-
-<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
-
-<a name="Top"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="Tiny-C-Compiler-Reference-Documentation"></a>
-<h1 class="settitle">Tiny C Compiler Reference Documentation</h1>
-
-<p>This manual documents version 0.9.26 of the Tiny C Compiler.
-</p>
-<table class="menu" border="0" cellspacing="0">
-<tr><td align="left" valign="top"><a href="#Introduction">1. Introduction</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                Introduction to tcc.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#Invoke">2. Command line invocation</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Invocation of tcc (command line, options).
-</td></tr>
-<tr><td align="left" valign="top"><a href="#Clang">3. C language support</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       ANSI C and extensions.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#asm">4. TinyCC Assembler</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                         Assembler syntax.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#linker">5. TinyCC Linker</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Output file generation and supported targets.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Automatic bounds-checking of C code.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#Libtcc">7. The <code>libtcc</code> library</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      The libtcc library.
-</td></tr>
-<tr><td align="left" valign="top"><a href="#devel">8. Developer&rsquo;s guide</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       Guide for Developers.
-</td></tr>
-</table>
-
-
-<hr size="1">
-<a name="Introduction"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Top" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="Introduction-1"></a>
-<h1 class="chapter">1. Introduction</h1>
-
-<p>TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+<HEAD>
+<TITLE>Tiny C Compiler Reference Documentation: </TITLE>
+
+<META NAME="description" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="keywords" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+<META NAME="Generator" CONTENT="texi2html 1.64">
+
+</HEAD>
+
+<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
+
+<A NAME="SEC_Top"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Tiny C Compiler Reference Documentation</H1></P><P>
+
+This manual documents version 0.9.27
+ of the Tiny C Compiler.
+</P><P>
+
+<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> 
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC1">1. Introduction</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Introduction to tcc.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC2">2. Command line invocation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Invocation of tcc (command line, options).</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC5">3. C language support</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">ANSI C and extensions.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Assembler syntax.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Output file generation and supported targets.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Automatic bounds-checking of C code.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">The libtcc library.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC23">8. Developer's guide</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Guide for Developers.</TD></TR>
+</TABLE></BLOCKQUOTE>
+<P>
+
+<HR SIZE=1>
+<A NAME="SEC1"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<A NAME="Introduction"></A>
+<H1> 1. Introduction </H1>
+<!--docid::SEC1::-->
+<P>
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
 compilers, it is meant to be self-relying: you do not need an
 external assembler or linker because TCC does that for you.
-</p>
-<p>TCC compiles so <em>fast</em> that even for big projects <code>Makefile</code>s may
+</P><P>
+
+TCC compiles so <EM>fast</EM> that even for big projects <CODE>Makefile</CODE>s may
 not be necessary.
-</p>
-<p>TCC not only supports ANSI C, but also most of the new ISO C99
+</P><P>
+
+TCC not only supports ANSI C, but also most of the new ISO C99
 standard and many GNUC extensions including inline assembly.
-</p>
-<p>TCC can also be used to make <em>C scripts</em>, i.e. pieces of C source
+</P><P>
+
+TCC can also be used to make <EM>C scripts</EM>, i.e. pieces of C source
 that you run as a Perl or Python script. Compilation is so fast that
 your script will be as fast as if it was an executable.
-</p>
-<p>TCC can also automatically generate memory and bound checks
-(see section <a href="#Bounds">TinyCC Memory and Bound checks</a>) while allowing all C pointers operations. TCC can do
+</P><P>
+
+TCC can also automatically generate memory and bound checks
+(see section <A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>) while allowing all C pointers operations. TCC can do
 these checks even if non patched libraries are used.
-</p>
-<p>With <code>libtcc</code>, you can use TCC as a backend for dynamic code
-generation (see section <a href="#Libtcc">The <code>libtcc</code> library</a>).
-</p>
-<p>TCC mainly supports the i386 target on Linux and Windows. There are alpha
-ports for the ARM (<code>arm-tcc</code>) and the TMS320C67xx targets
-(<code>c67-tcc</code>). More information about the ARM port is available at
-<a href="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</a>.
-</p>
-<p>For usage on Windows, see also <a href="tcc-win32.txt">tcc-win32.txt</a>.
-</p>
-<hr size="6">
-<a name="Invoke"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Introduction" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Quick-start" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Introduction" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="Command-line-invocation"></a>
-<h1 class="chapter">2. Command line invocation</h1>
-
-<hr size="6">
-<a name="Quick-start"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Invoke" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Option-summary" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">2.1 Quick start</h2>
-
-<table><tr><td>&nbsp;</td><td><pre class="example">usage: tcc [options] [<var>infile1</var> <var>infile2</var>&hellip;] [&lsquo;<samp>-run</samp>&rsquo; <var>infile</var> <var>args</var>&hellip;]
-</pre></td></tr></table>
-
-<p>TCC options are a very much like gcc options. The main difference is that TCC
+</P><P>
+
+With <CODE>libtcc</CODE>, you can use TCC as a backend for dynamic code
+generation (see section <A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>).
+</P><P>
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (<CODE>arm-tcc</CODE>) and the TMS320C67xx targets
+(<CODE>c67-tcc</CODE>). More information about the ARM port is available at
+<A HREF="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</A>.
+</P><P>
+
+For usage on Windows, see also <A HREF="tcc-win32.txt">tcc-win32.txt</A>.
+</P><P>
+
+<A NAME="Invoke"></A>
+<HR SIZE="6">
+<A NAME="SEC2"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC1"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 2. Command line invocation </H1>
+<!--docid::SEC2::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC3"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.1 Quick start </H2>
+<!--docid::SEC3::-->
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>usage: tcc [options] [<VAR>infile1</VAR> <VAR>infile2</VAR><small>...</small>] [<SAMP>`-run'</SAMP> <VAR>infile</VAR> <VAR>args</VAR><small>...</small>]
+</pre></td></tr></table></P><P>
+
+TCC options are a very much like gcc options. The main difference is that TCC
 can also execute directly the resulting program and give it runtime
 arguments.
-</p>
-<p>Here are some examples to understand the logic:
-</p>
-<dl compact="compact">
-<dt> <code>&lsquo;<samp>tcc -run a.c</samp>&rsquo;</code></dt>
-<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and execute it directly
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -run a.c arg1</samp>&rsquo;</code></dt>
-<dd><p>Compile a.c and execute it directly. arg1 is given as first argument to
-the <code>main()</code> of a.c.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc a.c -run b.c arg1</samp>&rsquo;</code></dt>
-<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and execute them. arg1 is given
-as first argument to the <code>main()</code> of the resulting program. 
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -o myprog a.c b.c</samp>&rsquo;</code></dt>
-<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -o myprog a.o b.o</samp>&rsquo;</code></dt>
-<dd><p>link &lsquo;<tt>a.o</tt>&rsquo; and &lsquo;<tt>b.o</tt>&rsquo; together and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -c a.c</samp>&rsquo;</code></dt>
-<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and generate object file &lsquo;<tt>a.o</tt>&rsquo;.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -c asmfile.S</samp>&rsquo;</code></dt>
-<dd><p>Preprocess with C preprocess and assemble &lsquo;<tt>asmfile.S</tt>&rsquo; and generate
-object file &lsquo;<tt>asmfile.o</tt>&rsquo;.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -c asmfile.s</samp>&rsquo;</code></dt>
-<dd><p>Assemble (but not preprocess) &lsquo;<tt>asmfile.s</tt>&rsquo; and generate object file
-&lsquo;<tt>asmfile.o</tt>&rsquo;.
-</p>
-</dd>
-<dt> <code>&lsquo;<samp>tcc -r -o ab.o a.c b.c</samp>&rsquo;</code></dt>
-<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and generate the object file &lsquo;<tt>ab.o</tt>&rsquo;.
-</p>
-</dd>
-</dl>
-
-<p>Scripting:
-</p>
-<p>TCC can be invoked from <em>scripts</em>, just as shell scripts. You just
-need to add <code>#!/usr/local/bin/tcc -run</code> at the start of your C source:
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run
-#include &lt;stdio.h&gt;
+</P><P>
+
+Here are some examples to understand the logic:
+</P><P>
+
+<DL COMPACT>
+<DT><CODE><SAMP>`tcc -run a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and execute it directly
+<P>
+
+<DT><CODE><SAMP>`tcc -run a.c arg1'</SAMP></CODE>
+<DD>Compile a.c and execute it directly. arg1 is given as first argument to
+the <CODE>main()</CODE> of a.c.
+<P>
+
+<DT><CODE><SAMP>`tcc a.c -run b.c arg1'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and execute them. arg1 is given
+as first argument to the <CODE>main()</CODE> of the resulting program. 
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.o b.o'</SAMP></CODE>
+<DD>link <TT>`a.o'</TT> and <TT>`b.o'</TT> together and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and generate object file <TT>`a.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.S'</SAMP></CODE>
+<DD>Preprocess with C preprocess and assemble <TT>`asmfile.S'</TT> and generate
+object file <TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.s'</SAMP></CODE>
+<DD>Assemble (but not preprocess) <TT>`asmfile.s'</TT> and generate object file
+<TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -r -o ab.o a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and generate the object file <TT>`ab.o'</TT>.
+<P>
+
+</DL>
+<P>
+
+Scripting:
+</P><P>
+
+TCC can be invoked from <EM>scripts</EM>, just as shell scripts. You just
+need to add <CODE>#!/usr/local/bin/tcc -run</CODE> at the start of your C source:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run
+#include &#60;stdio.h&#62;
 
 int main() 
 {
-    printf(&quot;Hello World\n&quot;);
+    printf("Hello World\n");
     return 0;
 }
-</pre></td></tr></table>
-
-<p>TCC can read C source code from <em>standard input</em> when &lsquo;<samp>-</samp>&rsquo; is used in 
-place of &lsquo;<samp>infile</samp>&rsquo;. Example:
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">echo 'main(){puts(&quot;hello&quot;);}' | tcc -run -
-</pre></td></tr></table>
-
-<hr size="6">
-<a name="Option-summary"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Quick-start" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">2.2 Option summary</h2>
-
-<p>General Options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-c</samp>&rsquo;</dt>
-<dd><p>Generate an object file.
-</p>
-</dd>
-<dt> &lsquo;<samp>-o outfile</samp>&rsquo;</dt>
-<dd><p>Put object file, executable, or dll into output file &lsquo;<tt>outfile</tt>&rsquo;.
-</p>
-</dd>
-<dt> &lsquo;<samp>-run source [args...]</samp>&rsquo;</dt>
-<dd><p>Compile file <var>source</var> and run it with the command line arguments
-<var>args</var>. In order to be able to give more than one argument to a
-script, several TCC options can be given <em>after</em> the
-&lsquo;<samp>-run</samp>&rsquo; option, separated by spaces:
-</p><table><tr><td>&nbsp;</td><td><pre class="example">tcc &quot;-run -L/usr/X11R6/lib -lX11&quot; ex4.c
-</pre></td></tr></table>
-<p>In a script, it gives the following header:
-</p><table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
-</pre></td></tr></table>
-
-</dd>
-<dt> &lsquo;<samp>-dumpversion</samp>&rsquo;</dt>
-<dd><p>Print only the compiler version and nothing else.
-</p>
-</dd>
-<dt> &lsquo;<samp>-v</samp>&rsquo;</dt>
-<dd><p>Display TCC version.
-</p>
-</dd>
-<dt> &lsquo;<samp>-vv</samp>&rsquo;</dt>
-<dd><p>Show included files.  As sole argument, print search dirs (as below).
-</p>
-</dd>
-<dt> &lsquo;<samp>-bench</samp>&rsquo;</dt>
-<dd><p>Display compilation statistics.
-</p>
-</dd>
-<dt> &lsquo;<samp>-print-search-dirs</samp>&rsquo;</dt>
-<dd><p>Print the configured installation directory and a list of library
+</pre></td></tr></table></P><P>
+
+TCC can read C source code from <EM>standard input</EM> when <SAMP>`-'</SAMP> is used in 
+place of <SAMP>`infile'</SAMP>. Example:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>echo 'main(){puts("hello");}' | tcc -run -
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC4"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.2 Option summary </H2>
+<!--docid::SEC4::-->
+<P>
+
+General Options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-c'</SAMP>
+<DD>Generate an object file.
+<P>
+
+<DT><SAMP>`-o outfile'</SAMP>
+<DD>Put object file, executable, or dll into output file <TT>`outfile'</TT>.
+<P>
+
+<DT><SAMP>`-run source [args...]'</SAMP>
+<DD>Compile file <VAR>source</VAR> and run it with the command line arguments
+<VAR>args</VAR>. In order to be able to give more than one argument to a
+script, several TCC options can be given <EM>after</EM> the
+<SAMP>`-run'</SAMP> option, separated by spaces:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+</pre></td></tr></table>In a script, it gives the following header:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+</pre></td></tr></table><P>
+
+<DT><SAMP>`-v'</SAMP>
+<DD>Display TCC version.
+<P>
+
+<DT><SAMP>`-vv'</SAMP>
+<DD>Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
+<P>
+
+<DT><SAMP>`-bench'</SAMP>
+<DD>Display compilation statistics.
+<P>
+
+</DL>
+<P>
+
+Preprocessor options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Idir'</SAMP>
+<DD>Specify an additional include path. Include paths are searched in the
+order they are specified.
+<P>
+
+System include paths are always searched after. The default system
+include paths are: <TT>`/usr/local/include'</TT>, <TT>`/usr/include'</TT>
+and <TT>`PREFIX/lib/tcc/include'</TT>. (<TT>`PREFIX'</TT> is usually
+<TT>`/usr'</TT> or <TT>`/usr/local'</TT>).
+</P><P>
+
+<DT><SAMP>`-Dsym[=val]'</SAMP>
+<DD>Define preprocessor symbol <SAMP>`sym'</SAMP> to
+val. If val is not present, its value is <SAMP>`1'</SAMP>. Function-like macros can
+also be defined: <SAMP>`-DF(a)=a+1'</SAMP>
+<P>
+
+<DT><SAMP>`-Usym'</SAMP>
+<DD>Undefine preprocessor symbol <SAMP>`sym'</SAMP>.
+<P>
+
+<DT><SAMP>`-E'</SAMP>
+<DD>Preprocess only, to stdout or file (with -o).
+<P>
+
+</DL>
+<P>
+
+Compilation flags:
+</P><P>
+
+Note: each of the following options has a negative form beginning with
+<SAMP>`-fno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-funsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be unsigned.
+<P>
+
+<DT><SAMP>`-fsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be signed.
+<P>
+
+<DT><SAMP>`-fno-common'</SAMP>
+<DD>Do not generate common symbols for uninitialized data.
+<P>
+
+<DT><SAMP>`-fleading-underscore'</SAMP>
+<DD>Add a leading underscore at the beginning of each C symbol.
+<P>
+
+<DT><SAMP>`-fms-extensions'</SAMP>
+<DD>Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+<P>
+
+<DT><SAMP>`-fdollars-in-identifiers'</SAMP>
+<DD>Allow dollar signs in identifiers
+<P>
+
+</DL>
+<P>
+
+Warning options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-w'</SAMP>
+<DD>Disable all warnings.
+<P>
+
+</DL>
+<P>
+
+Note: each of the following warning options has a negative form beginning with
+<SAMP>`-Wno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Wimplicit-function-declaration'</SAMP>
+<DD>Warn about implicit function declaration.
+<P>
+
+<DT><SAMP>`-Wunsupported'</SAMP>
+<DD>Warn about unsupported GCC features that are ignored by TCC.
+<P>
+
+<DT><SAMP>`-Wwrite-strings'</SAMP>
+<DD>Make string constants be of type <CODE>const char *</CODE> instead of <CODE>char
+*</CODE>.
+<P>
+
+<DT><SAMP>`-Werror'</SAMP>
+<DD>Abort compilation if warnings are issued.
+<P>
+
+<DT><SAMP>`-Wall'</SAMP>
+<DD>Activate all warnings, except <SAMP>`-Werror'</SAMP>, <SAMP>`-Wunusupported'</SAMP> and
+<SAMP>`-Wwrite-strings'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Linker options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Ldir'</SAMP>
+<DD>Specify an additional static library path for the <SAMP>`-l'</SAMP> option. The
+default library paths are <TT>`/usr/local/lib'</TT>, <TT>`/usr/lib'</TT> and <TT>`/lib'</TT>.
+<P>
+
+<DT><SAMP>`-lxxx'</SAMP>
+<DD>Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+<SAMP>`-L'</SAMP> option and <CODE>LIBRARY_PATH</CODE> variable.
+<P>
+
+<DT><SAMP>`-Bdir'</SAMP>
+<DD>Set the path where the tcc internal libraries (and include files) can be
+found (default is <TT>`PREFIX/lib/tcc'</TT>).
+<P>
+
+<DT><SAMP>`-shared'</SAMP>
+<DD>Generate a shared library instead of an executable.
+<P>
+
+<DT><SAMP>`-soname name'</SAMP>
+<DD>set name for shared library to be used at runtime
+<P>
+
+<DT><SAMP>`-static'</SAMP>
+<DD>Generate a statically linked executable (default is a shared linked
+executable).
+<P>
+
+<DT><SAMP>`-rdynamic'</SAMP>
+<DD>Export global symbols to the dynamic linker. It is useful when a library
+opened with <CODE>dlopen()</CODE> needs to access executable symbols.
+<P>
+
+<DT><SAMP>`-r'</SAMP>
+<DD>Generate an object file combining all input files.
+<P>
+
+<DT><SAMP>`-Wl,-rpath=path'</SAMP>
+<DD>Put custom search path for dynamic libraries into executable.
+<P>
+
+<DT><SAMP>`-Wl,--enable-new-dtags'</SAMP>
+<DD>When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
+<P>
+
+<DT><SAMP>`-Wl,--oformat=fmt'</SAMP>
+<DD>Use <VAR>fmt</VAR> as output format. The supported output formats are:
+<DL COMPACT>
+<DT><CODE>elf32-i386</CODE>
+<DD>ELF output format (default)
+<DT><CODE>binary</CODE>
+<DD>Binary image (only for executable output)
+<DT><CODE>coff</CODE>
+<DD>COFF output format (only for executable output for TMS320C67xx target)
+</DL>
+<P>
+
+<DT><SAMP>`-Wl,-subsystem=console/gui/wince/...'</SAMP>
+<DD>Set type for PE (Windows) executables.
+<P>
+
+<DT><SAMP>`-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]'</SAMP>
+<DD>Modify executable layout.
+<P>
+
+<DT><SAMP>`-Wl,-Bsymbolic'</SAMP>
+<DD>Set DT_SYMBOLIC tag.
+<P>
+
+<DT><SAMP>`-Wl,-(no-)whole-archive'</SAMP>
+<DD>Turn on/off linking of all objects in archives.
+<P>
+
+</DL>
+<P>
+
+Debugger options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-g'</SAMP>
+<DD>Generate run time debug information so that you get clear run time
+error messages: <CODE> test.c:68: in function 'test5()': dereferencing
+invalid pointer</CODE> instead of the laconic <CODE>Segmentation
+fault</CODE>.
+<P>
+
+<DT><SAMP>`-b'</SAMP>
+<DD>Generate additional support code to check
+memory allocations and array/pointer bounds. <SAMP>`-g'</SAMP> is implied. Note
+that the generated code is slower and bigger in this case.
+<P>
+
+Note: <SAMP>`-b'</SAMP> is only available on i386 when using libtcc for the moment.
+</P><P>
+
+<DT><SAMP>`-bt N'</SAMP>
+<DD>Display N callers in stack traces. This is useful with <SAMP>`-g'</SAMP> or
+<SAMP>`-b'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Misc options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-MD'</SAMP>
+<DD>Generate makefile fragment with dependencies.
+<P>
+
+<DT><SAMP>`-MF depfile'</SAMP>
+<DD>Use <TT>`depfile'</TT> as output for -MD.
+<P>
+
+<DT><SAMP>`-print-search-dirs'</SAMP>
+<DD>Print the configured installation directory and a list of library
 and include directories tcc will search.
-</p>
-</dd>
-</dl>
-
-<p>Preprocessor options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-Idir</samp>&rsquo;</dt>
-<dd><p>Specify an additional include path. Include paths are searched in the
-order they are specified.
-</p>
-<p>System include paths are always searched after. The default system
-include paths are: &lsquo;<tt>/usr/local/include</tt>&rsquo;, &lsquo;<tt>/usr/include</tt>&rsquo;
-and &lsquo;<tt>PREFIX/lib/tcc/include</tt>&rsquo;. (&lsquo;<tt>PREFIX</tt>&rsquo; is usually
-&lsquo;<tt>/usr</tt>&rsquo; or &lsquo;<tt>/usr/local</tt>&rsquo;).
-</p>
-</dd>
-<dt> &lsquo;<samp>-Dsym[=val]</samp>&rsquo;</dt>
-<dd><p>Define preprocessor symbol &lsquo;<samp>sym</samp>&rsquo; to
-val. If val is not present, its value is &lsquo;<samp>1</samp>&rsquo;. Function-like macros can
-also be defined: &lsquo;<samp>-DF(a)=a+1</samp>&rsquo;
-</p>
-</dd>
-<dt> &lsquo;<samp>-Usym</samp>&rsquo;</dt>
-<dd><p>Undefine preprocessor symbol &lsquo;<samp>sym</samp>&rsquo;.
-</p></dd>
-</dl>
-
-<p>Compilation flags:
-</p>
-<p>Note: each of the following warning options has a negative form beginning with
-&lsquo;<samp>-fno-</samp>&rsquo;.
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-funsigned-char</samp>&rsquo;</dt>
-<dd><p>Let the <code>char</code> type be unsigned.
-</p>
-</dd>
-<dt> &lsquo;<samp>-fsigned-char</samp>&rsquo;</dt>
-<dd><p>Let the <code>char</code> type be signed.
-</p>
-</dd>
-<dt> &lsquo;<samp>-fno-common</samp>&rsquo;</dt>
-<dd><p>Do not generate common symbols for uninitialized data.
-</p>
-</dd>
-<dt> &lsquo;<samp>-fleading-underscore</samp>&rsquo;</dt>
-<dd><p>Add a leading underscore at the beginning of each C symbol.
-</p>
-</dd>
-</dl>
-
-<p>Warning options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-w</samp>&rsquo;</dt>
-<dd><p>Disable all warnings.
-</p>
-</dd>
-</dl>
-
-<p>Note: each of the following warning options has a negative form beginning with
-&lsquo;<samp>-Wno-</samp>&rsquo;.
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-Wimplicit-function-declaration</samp>&rsquo;</dt>
-<dd><p>Warn about implicit function declaration.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wunsupported</samp>&rsquo;</dt>
-<dd><p>Warn about unsupported GCC features that are ignored by TCC.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wwrite-strings</samp>&rsquo;</dt>
-<dd><p>Make string constants be of type <code>const char *</code> instead of <code>char
-*</code>.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Werror</samp>&rsquo;</dt>
-<dd><p>Abort compilation if warnings are issued.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wall</samp>&rsquo; </dt>
-<dd><p>Activate all warnings, except &lsquo;<samp>-Werror</samp>&rsquo;, &lsquo;<samp>-Wunusupported</samp>&rsquo; and
-&lsquo;<samp>-Wwrite-strings</samp>&rsquo;.
-</p>
-</dd>
-</dl>
-
-<p>Linker options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-Ldir</samp>&rsquo;</dt>
-<dd><p>Specify an additional static library path for the &lsquo;<samp>-l</samp>&rsquo; option. The
-default library paths are &lsquo;<tt>/usr/local/lib</tt>&rsquo;, &lsquo;<tt>/usr/lib</tt>&rsquo; and &lsquo;<tt>/lib</tt>&rsquo;.
-</p>
-</dd>
-<dt> &lsquo;<samp>-lxxx</samp>&rsquo;</dt>
-<dd><p>Link your program with dynamic library libxxx.so or static library
-libxxx.a. The library is searched in the paths specified by the
-&lsquo;<samp>-L</samp>&rsquo; option.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Bdir</samp>&rsquo;</dt>
-<dd><p>Set the path where the tcc internal libraries (and include files) can be
-found (default is &lsquo;<tt>PREFIX/lib/tcc</tt>&rsquo;).
-</p>
-</dd>
-<dt> &lsquo;<samp>-shared</samp>&rsquo;</dt>
-<dd><p>Generate a shared library instead of an executable.
-</p>
-</dd>
-<dt> &lsquo;<samp>-soname name</samp>&rsquo;</dt>
-<dd><p>set name for shared library to be used at runtime
-</p>
-</dd>
-<dt> &lsquo;<samp>-static</samp>&rsquo;</dt>
-<dd><p>Generate a statically linked executable (default is a shared linked
-executable).
-</p>
-</dd>
-<dt> &lsquo;<samp>-rdynamic</samp>&rsquo;</dt>
-<dd><p>Export global symbols to the dynamic linker. It is useful when a library
-opened with <code>dlopen()</code> needs to access executable symbols.
-</p>
-</dd>
-<dt> &lsquo;<samp>-r</samp>&rsquo;</dt>
-<dd><p>Generate an object file combining all input files.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wl,-rpath=path</samp>&rsquo;</dt>
-<dd><p>Put custom seatch path for dynamic libraries into executable.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wl,--oformat=fmt</samp>&rsquo;</dt>
-<dd><p>Use <var>fmt</var> as output format. The supported output formats are:
-</p><dl compact="compact">
-<dt> <code>elf32-i386</code></dt>
-<dd><p>ELF output format (default)
-</p></dd>
-<dt> <code>binary</code></dt>
-<dd><p>Binary image (only for executable output)
-</p></dd>
-<dt> <code>coff</code></dt>
-<dd><p>COFF output format (only for executable output for TMS320C67xx target)
-</p></dd>
-</dl>
-
-</dd>
-<dt> &lsquo;<samp>-Wl,-subsystem=console/gui/wince/...</samp>&rsquo;</dt>
-<dd><p>Set type for PE (Windows) executables.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]</samp>&rsquo;</dt>
-<dd><p>Modify executable layout.
-</p>
-</dd>
-<dt> &lsquo;<samp>-Wl,-Bsymbolic</samp>&rsquo;</dt>
-<dd><p>Set DT_SYMBOLIC tag.
-</p>
-</dd>
-</dl>
-
-<p>Debugger options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-g</samp>&rsquo;</dt>
-<dd><p>Generate run time debug information so that you get clear run time
-error messages: <code> test.c:68: in function 'test5()': dereferencing
-invalid pointer</code> instead of the laconic <code>Segmentation
-fault</code>.
-</p>
-</dd>
-<dt> &lsquo;<samp>-b</samp>&rsquo;</dt>
-<dd><p>Generate additional support code to check
-memory allocations and array/pointer bounds. &lsquo;<samp>-g</samp>&rsquo; is implied. Note
-that the generated code is slower and bigger in this case.
-</p>
-<p>Note: &lsquo;<samp>-b</samp>&rsquo; is only available on i386 for the moment.
-</p>
-</dd>
-<dt> &lsquo;<samp>-bt N</samp>&rsquo;</dt>
-<dd><p>Display N callers in stack traces. This is useful with &lsquo;<samp>-g</samp>&rsquo; or
-&lsquo;<samp>-b</samp>&rsquo;.
-</p>
-</dd>
-</dl>
-
-<p>Misc options:
-</p>
-<dl compact="compact">
-<dt> &lsquo;<samp>-MD</samp>&rsquo;</dt>
-<dd><p>Generate makefile fragment with dependencies.
-</p>
-</dd>
-<dt> &lsquo;<samp>-MF depfile</samp>&rsquo;</dt>
-<dd><p>Use &lsquo;<tt>depfile</tt>&rsquo; as output for -MD.
-</p>
-</dd>
-</dl>
-
-<p>Note: GCC options &lsquo;<samp>-Ox</samp>&rsquo;, &lsquo;<samp>-fx</samp>&rsquo; and &lsquo;<samp>-mx</samp>&rsquo; are
+<P>
+
+<DT><SAMP>`-dumpversion'</SAMP>
+<DD>Print version.
+<P>
+
+</DL>
+<P>
+
+Target specific options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-mms-bitfields'</SAMP>
+<DD>Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+<P>
+
+<DT><SAMP>`-mfloat-abi (ARM only)'</SAMP>
+<DD>Select the float ABI. Possible values: <CODE>softfp</CODE> and <CODE>hard</CODE>
+<P>
+
+<DT><SAMP>`-mno-sse'</SAMP>
+<DD>Do not use sse registers on x86_64
+<P>
+
+<DT><SAMP>`-m32, -m64'</SAMP>
+<DD>Pass command line to the i386/x86_64 cross compiler.
+<P>
+
+</DL>
+<P>
+
+Note: GCC options <SAMP>`-Ox'</SAMP>, <SAMP>`-fx'</SAMP> and <SAMP>`-mx'</SAMP> are
 ignored.
-</p>
-
-<hr size="6">
-<a name="Clang"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Option-summary" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#ANSI-C" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Invoke" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="C-language-support"></a>
-<h1 class="chapter">3. C language support</h1>
-
-<hr size="6">
-<a name="ANSI-C"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Clang" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#ISOC99-extensions" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">3.1 ANSI C</h2>
-
-<p>TCC implements all the ANSI C standard, including structure bit fields
-and floating point numbers (<code>long double</code>, <code>double</code>, and
-<code>float</code> fully supported).
-</p>
-<hr size="6">
-<a name="ISOC99-extensions"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#ANSI-C" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#GNU-C-extensions" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">3.2 ISOC99 extensions</h2>
-
-<p>TCC implements many features of the new C standard: ISO C99. Currently
-missing items are: complex and imaginary numbers and variable length
-arrays.
-</p>
-<p>Currently implemented ISOC99 features:
-</p>
-<ul>
-<li> 64 bit <code>long long</code> types are fully supported.
-
-</li><li> The boolean type <code>_Bool</code> is supported.
-
-</li><li> <code>__func__</code> is a string variable containing the current
+</P><P>
+
+Environment variables that affect how tcc operates.
+</P><P>
+
+<DL COMPACT>
+
+<DT><SAMP>`CPATH'</SAMP>
+<DD><DT><SAMP>`C_INCLUDE_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for include files,
+directories given with <SAMP>`-I'</SAMP> are searched first.
+<P>
+
+<DT><SAMP>`LIBRARY_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for libraries for the
+<SAMP>`-l'</SAMP> option, directories given with <SAMP>`-L'</SAMP> are searched first.
+<P>
+
+</DL>
+<P>
+
+<A NAME="Clang"></A>
+<HR SIZE="6">
+<A NAME="SEC5"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 3. C language support </H1>
+<!--docid::SEC5::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC6"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.1 ANSI C </H2>
+<!--docid::SEC6::-->
+<P>
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (<CODE>long double</CODE>, <CODE>double</CODE>, and
+<CODE>float</CODE> fully supported).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC7"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.2 ISOC99 extensions </H2>
+<!--docid::SEC7::-->
+<P>
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers.
+</P><P>
+
+Currently implemented ISOC99 features:
+</P><P>
+
+<UL>
+
+<LI>variable length arrays.
+<P>
+
+<LI>64 bit <CODE>long long</CODE> types are fully supported.
+<P>
+
+<LI>The boolean type <CODE>_Bool</CODE> is supported.
+<P>
+
+<LI><CODE>__func__</CODE> is a string variable containing the current
 function name.
-
-</li><li> Variadic macros: <code>__VA_ARGS__</code> can be used for
+<P>
+
+<LI>Variadic macros: <CODE>__VA_ARGS__</CODE> can be used for
    function-like macros:
-<table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
-</pre></td></tr></table>
-
-<p><code>dprintf</code> can then be used with a variable number of parameters.
-</p>
-</li><li> Declarations can appear anywhere in a block (as in C++).
-
-</li><li> Array and struct/union elements can be initialized in any order by
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+</pre></td></tr></table><P>
+
+<CODE>dprintf</CODE> can then be used with a variable number of parameters.
+</P><P>
+
+<LI>Declarations can appear anywhere in a block (as in C++).
+<P>
+
+<LI>Array and struct/union elements can be initialized in any order by
   using designators:
-<table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
 
     int tab[10] = { 1, 2, [5] = 5, [9] = 9};
-</pre></td></tr></table>
-    
-</li><li> Compound initializers are supported:
-<table><tr><td>&nbsp;</td><td><pre class="example">    int *p = (int []){ 1, 2, 3 };
-</pre></td></tr></table>
-<p>to initialize a pointer pointing to an initialized array. The same
+</pre></td></tr></table>    
+<LI>Compound initializers are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int *p = (int []){ 1, 2, 3 };
+</pre></td></tr></table>to initialize a pointer pointing to an initialized array. The same
 works for structures and strings.
-</p>
-</li><li> Hexadecimal floating point constants are supported:
-<table><tr><td>&nbsp;</td><td><pre class="example">          double d = 0x1234p10;
-</pre></td></tr></table>
-
-<p>is the same as writing 
-</p><table><tr><td>&nbsp;</td><td><pre class="example">          double d = 4771840.0;
-</pre></td></tr></table>
-
-</li><li> <code>inline</code> keyword is ignored.
-
-</li><li> <code>restrict</code> keyword is ignored.
-</li></ul>
-
-<hr size="6">
-<a name="GNU-C-extensions"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#ISOC99-extensions" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#TinyCC-extensions" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">3.3 GNU C extensions</h2>
-
-<p>TCC implements some GNU C extensions:
-</p>
-<ul>
-<li> array designators can be used without &rsquo;=&rsquo;: 
-<table><tr><td>&nbsp;</td><td><pre class="example">    int a[10] = { [0] 1, [5] 2, 3, 4 };
-</pre></td></tr></table>
-
-</li><li> Structure field designators can be a label: 
-<table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { x: 1, y: 1};
-</pre></td></tr></table>
-<p>instead of
-</p><table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { .x = 1, .y = 1};
-</pre></td></tr></table>
-
-</li><li> <code>\e</code> is ASCII character 27.
-
-</li><li> case ranges : ranges can be used in <code>case</code>s:
-<table><tr><td>&nbsp;</td><td><pre class="example">    switch(a) {
-    case 1 &hellip; 9:
-          printf(&quot;range 1 to 9\n&quot;);
+<P>
+
+<LI>Hexadecimal floating point constants are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 0x1234p10;
+</pre></td></tr></table><P>
+
+is the same as writing 
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 4771840.0;
+</pre></td></tr></table></P><P>
+
+<LI><CODE>inline</CODE> keyword is ignored.
+<P>
+
+<LI><CODE>restrict</CODE> keyword is ignored.
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC8"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.3 GNU C extensions </H2>
+<!--docid::SEC8::-->
+<P>
+
+TCC implements some GNU C extensions:
+</P><P>
+
+<UL>
+
+<LI>array designators can be used without '=':
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a[10] = { [0] 1, [5] 2, 3, 4 };
+</pre></td></tr></table><P>
+
+<LI>Structure field designators can be a label:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { x: 1, y: 1};
+</pre></td></tr></table>instead of
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { .x = 1, .y = 1};
+</pre></td></tr></table><P>
+
+<LI><CODE>\e</CODE> is ASCII character 27.
+<P>
+
+<LI>case ranges : ranges can be used in <CODE>case</CODE>s:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    switch(a) {
+    case 1 <small>...</small> 9:
+          printf("range 1 to 9\n");
           break;
     default:
-          printf(&quot;unexpected\n&quot;);
+          printf("unexpected\n");
           break;
     }
-</pre></td></tr></table>
-
-<a name="index-aligned-attribute"></a>
-<a name="index-packed-attribute"></a>
-<a name="index-section-attribute"></a>
-<a name="index-unused-attribute"></a>
-<a name="index-cdecl-attribute"></a>
-<a name="index-stdcall-attribute"></a>
-<a name="index-regparm-attribute"></a>
-<a name="index-dllexport-attribute"></a>
-
-</li><li> The keyword <code>__attribute__</code> is handled to specify variable or
+</pre></td></tr></table><P>
+
+<A NAME="IDX1"></A>
+<A NAME="IDX2"></A>
+<A NAME="IDX3"></A>
+<A NAME="IDX4"></A>
+<A NAME="IDX5"></A>
+<A NAME="IDX6"></A>
+<A NAME="IDX7"></A>
+<A NAME="IDX8"></A>
+</P><P>
+
+<LI>The keyword <CODE>__attribute__</CODE> is handled to specify variable or
 function attributes. The following attributes are supported:
-  <ul>
-<li> <code>aligned(n)</code>: align a variable or a structure field to n bytes
+<UL>
+
+<LI><CODE>aligned(n)</CODE>: align a variable or a structure field to n bytes
 (must be a power of two).
-
-  </li><li> <code>packed</code>: force alignment of a variable or a structure field to
+<P>
+
+<LI><CODE>packed</CODE>: force alignment of a variable or a structure field to
   1.
-
-  </li><li> <code>section(name)</code>: generate function or data in assembly section
+<P>
+
+<LI><CODE>section(name)</CODE>: generate function or data in assembly section
 name (name is a string containing the section name) instead of the default
 section.
-
-  </li><li> <code>unused</code>: specify that the variable or the function is unused.
-
-  </li><li> <code>cdecl</code>: use standard C calling convention (default).
-
-  </li><li> <code>stdcall</code>: use Pascal-like calling convention.
-
-  </li><li> <code>regparm(n)</code>: use fast i386 calling convention. <var>n</var> must be
-between 1 and 3. The first <var>n</var> function parameters are respectively put in
-registers <code>%eax</code>, <code>%edx</code> and <code>%ecx</code>.
-
-  </li><li> <code>dllexport</code>: export function from dll/executable (win32 only)
-
-</li></ul>
-
-<p>Here are some examples:
-</p><table><tr><td>&nbsp;</td><td><pre class="example">    int a __attribute__ ((aligned(8), section(&quot;.mysection&quot;)));
-</pre></td></tr></table>
-
-<p>align variable <code>a</code> to 8 bytes and put it in section <code>.mysection</code>.
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">    int my_add(int a, int b) __attribute__ ((section(&quot;.mycodesection&quot;))) 
+<P>
+
+<LI><CODE>unused</CODE>: specify that the variable or the function is unused.
+<P>
+
+<LI><CODE>cdecl</CODE>: use standard C calling convention (default).
+<P>
+
+<LI><CODE>stdcall</CODE>: use Pascal-like calling convention.
+<P>
+
+<LI><CODE>regparm(n)</CODE>: use fast i386 calling convention. <VAR>n</VAR> must be
+between 1 and 3. The first <VAR>n</VAR> function parameters are respectively put in
+registers <CODE>%eax</CODE>, <CODE>%edx</CODE> and <CODE>%ecx</CODE>.
+<P>
+
+<LI><CODE>dllexport</CODE>: export function from dll/executable (win32 only)
+<P>
+
+</UL>
+<P>
+
+Here are some examples:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a __attribute__ ((aligned(8), section(".mysection")));
+</pre></td></tr></table></P><P>
+
+align variable <CODE>a</CODE> to 8 bytes and put it in section <CODE>.mysection</CODE>.
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) 
     {
         return a + b;
     }
-</pre></td></tr></table>
-
-<p>generate function <code>my_add</code> in section <code>.mycodesection</code>.
-</p>
-</li><li> GNU style variadic macros:
-<table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(fmt, args&hellip;) printf(fmt, ## args)
-
-    dprintf(&quot;no arg\n&quot;);
-    dprintf(&quot;one arg %d\n&quot;, 1);
-</pre></td></tr></table>
-
-</li><li> <code>__FUNCTION__</code> is interpreted as C99 <code>__func__</code> 
+</pre></td></tr></table></P><P>
+
+generate function <CODE>my_add</CODE> in section <CODE>.mycodesection</CODE>.
+</P><P>
+
+<LI>GNU style variadic macros:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(fmt, args<small>...</small>) printf(fmt, ## args)
+
+    dprintf("no arg\n");
+    dprintf("one arg %d\n", 1);
+</pre></td></tr></table><P>
+
+<LI><CODE>__FUNCTION__</CODE> is interpreted as C99 <CODE>__func__</CODE>
 (so it has not exactly the same semantics as string literal GNUC
 where it is a string literal).
-
-</li><li> The <code>__alignof__</code> keyword can be used as <code>sizeof</code> 
+<P>
+
+<LI>The <CODE>__alignof__</CODE> keyword can be used as <CODE>sizeof</CODE>
 to get the alignment of a type or an expression.
-
-</li><li> The <code>typeof(x)</code> returns the type of <code>x</code>. 
-<code>x</code> is an expression or a type.
-
-</li><li> Computed gotos: <code>&amp;&amp;label</code> returns a pointer of type 
-<code>void *</code> on the goto label <code>label</code>. <code>goto *expr</code> can be
-used to jump on the pointer resulting from <code>expr</code>.
-
-</li><li> Inline assembly with asm instruction:
-<a name="index-inline-assembly"></a>
-<a name="index-assembly_002c-inline"></a>
-<a name="index-_005f_005fasm_005f_005f"></a>
-<table><tr><td>&nbsp;</td><td><pre class="example">static inline void * my_memcpy(void * to, const void * from, size_t n)
+<P>
+
+<LI>The <CODE>typeof(x)</CODE> returns the type of <CODE>x</CODE>.
+<CODE>x</CODE> is an expression or a type.
+<P>
+
+<LI>Computed gotos: <CODE>&#38;&#38;label</CODE> returns a pointer of type
+<CODE>void *</CODE> on the goto label <CODE>label</CODE>. <CODE>goto *expr</CODE> can be
+used to jump on the pointer resulting from <CODE>expr</CODE>.
+<P>
+
+<LI>Inline assembly with asm instruction:
+<A NAME="IDX9"></A>
+<A NAME="IDX10"></A>
+<A NAME="IDX11"></A>
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>static inline void * my_memcpy(void * to, const void * from, size_t n)
 {
 int d0, d1, d2;
 __asm__ __volatile__(
-        &quot;rep ; movsl\n\t&quot;
-        &quot;testb $2,%b4\n\t&quot;
-        &quot;je 1f\n\t&quot;
-        &quot;movsw\n&quot;
-        &quot;1:\ttestb $1,%b4\n\t&quot;
-        &quot;je 2f\n\t&quot;
-        &quot;movsb\n&quot;
-        &quot;2:&quot;
-        : &quot;=&amp;c&quot; (d0), &quot;=&amp;D&quot; (d1), &quot;=&amp;S&quot; (d2)
-        :&quot;0&quot; (n/4), &quot;q&quot; (n),&quot;1&quot; ((long) to),&quot;2&quot; ((long) from)
-        : &quot;memory&quot;);
+        "rep ; movsl\n\t"
+        "testb $2,%b4\n\t"
+        "je 1f\n\t"
+        "movsw\n"
+        "1:\ttestb $1,%b4\n\t"
+        "je 2f\n\t"
+        "movsb\n"
+        "2:"
+        : "=&c" (d0), "=&#38;D" (d1), "=&#38;S" (d2)
+        :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+        : "memory");
 return (to);
 }
-</pre></td></tr></table>
-
-<a name="index-gas"></a>
-<p>TCC includes its own x86 inline assembler with a <code>gas</code>-like (GNU
+</pre></td></tr></table><P>
+
+<A NAME="IDX12"></A>
+TCC includes its own x86 inline assembler with a <CODE>gas</CODE>-like (GNU
 assembler) syntax. No intermediate files are generated. GCC 3.x named
 operands are supported.
-</p>
-</li><li> <code>__builtin_types_compatible_p()</code> and <code>__builtin_constant_p()</code> 
+</P><P>
+
+<LI><CODE>__builtin_types_compatible_p()</CODE> and <CODE>__builtin_constant_p()</CODE>
 are supported.
-
-</li><li> <code>#pragma pack</code> is supported for win32 compatibility.
-
-</li></ul>
-
-<hr size="6">
-<a name="TinyCC-extensions"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#GNU-C-extensions" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Clang" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">3.4 TinyCC extensions</h2>
-
-<ul>
-<li> <code>__TINYC__</code> is a predefined macro to <code>1</code> to
-indicate that you use TCC.
-
-</li><li> <code>#!</code> at the start of a line is ignored to allow scripting.
-
-</li><li> Binary digits can be entered (<code>0b101</code> instead of
-<code>5</code>).
-
-</li><li> <code>__BOUNDS_CHECKING_ON</code> is defined if bound checking is activated.
-
-</li></ul>
-
-<hr size="6">
-<a name="asm"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#TinyCC-extensions" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Syntax" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Clang" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="TinyCC-Assembler"></a>
-<h1 class="chapter">4. TinyCC Assembler</h1>
-
-<p>Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+<P>
+
+<LI><CODE>#pragma pack</CODE> is supported for win32 compatibility.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC9"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.4 TinyCC extensions </H2>
+<!--docid::SEC9::-->
+<P>
+
+<UL>
+
+<LI><CODE>__TINYC__</CODE> is a predefined macro to indicate that you use TCC.
+<P>
+
+<LI><CODE>#!</CODE> at the start of a line is ignored to allow scripting.
+<P>
+
+<LI>Binary digits can be entered (<CODE>0b101</CODE> instead of
+<CODE>5</CODE>).
+<P>
+
+<LI><CODE>__BOUNDS_CHECKING_ON</CODE> is defined if bound checking is activated.
+<P>
+
+</UL>
+<P>
+
+<A NAME="asm"></A>
+<HR SIZE="6">
+<A NAME="SEC10"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 4. TinyCC Assembler </H1>
+<!--docid::SEC10::-->
+<P>
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
 assembler supports a gas-like syntax (GNU assembler). You can
-desactivate assembler support if you want a smaller TinyCC executable
+deactivate assembler support if you want a smaller TinyCC executable
 (the C compiler does not rely on the assembler).
-</p>
-<p>TinyCC Assembler is used to handle files with &lsquo;<tt>.S</tt>&rsquo; (C
-preprocessed assembler) and &lsquo;<tt>.s</tt>&rsquo; extensions. It is also used to
-handle the GNU inline assembler with the <code>asm</code> keyword.
-</p>
-<hr size="6">
-<a name="Syntax"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#asm" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Expressions" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">4.1 Syntax</h2>
-
-<p>TinyCC Assembler supports most of the gas syntax. The tokens are the
+</P><P>
+
+TinyCC Assembler is used to handle files with <TT>`.S'</TT> (C
+preprocessed assembler) and <TT>`.s'</TT> extensions. It is also used to
+handle the GNU inline assembler with the <CODE>asm</CODE> keyword.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC11"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.1 Syntax </H2>
+<!--docid::SEC11::-->
+<P>
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
 same as C.
-</p>
-<ul>
-<li> C and C++ comments are supported.
-
-</li><li> Identifiers are the same as C, so you cannot use &rsquo;.&rsquo; or &rsquo;$&rsquo;.
-
-</li><li> Only 32 bit integer numbers are supported.
-
-</li></ul>
-
-<hr size="6">
-<a name="Expressions"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Syntax" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Labels" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">4.2 Expressions</h2>
-
-<ul>
-<li> Integers in decimal, octal and hexa are supported.
-
-</li><li> Unary operators: +, -, ~.
-
-</li><li> Binary operators in decreasing priority order:
-
-<ol>
-<li> *, /, %
-</li><li> &amp;, |, ^
-</li><li> +, -
-</li></ol>
-
-</li><li> A value is either an absolute number or a label plus an offset. 
-All operators accept absolute values except &rsquo;+&rsquo; and &rsquo;-&rsquo;. &rsquo;+&rsquo; or &rsquo;-&rsquo; can be
-used to add an offset to a label. &rsquo;-&rsquo; supports two labels only if they
+</P><P>
+
+<UL>
+
+<LI>C and C++ comments are supported.
+<P>
+
+<LI>Identifiers are the same as C, so you cannot use '.' or '$'.
+<P>
+
+<LI>Only 32 bit integer numbers are supported.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC12"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.2 Expressions </H2>
+<!--docid::SEC12::-->
+<P>
+
+<UL>
+
+<LI>Integers in decimal, octal and hexa are supported.
+<P>
+
+<LI>Unary operators: +, -, ~.
+<P>
+
+<LI>Binary operators in decreasing priority order:
+<P>
+
+<OL>
+<LI>*, /, %
+<LI>&#38;, |, ^
+<LI>+, -
+</OL>
+<P>
+
+<LI>A value is either an absolute number or a label plus an offset.
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
 are the same or if they are both defined and in the same section.
-
-</li></ul>
-
-<hr size="6">
-<a name="Labels"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Expressions" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Directives" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">4.3 Labels</h2>
-
-<ul>
-<li> All labels are considered as local, except undefined ones.
-
-</li><li> Numeric labels can be used as local <code>gas</code>-like labels. 
-They can be defined several times in the same source. Use &rsquo;b&rsquo;
-(backward) or &rsquo;f&rsquo; (forward) as suffix to reference them:
-
-<table><tr><td>&nbsp;</td><td><pre class="example"> 1:
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC13"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.3 Labels </H2>
+<!--docid::SEC13::-->
+<P>
+
+<UL>
+
+<LI>All labels are considered as local, except undefined ones.
+<P>
+
+<LI>Numeric labels can be used as local <CODE>gas</CODE>-like labels.
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> 1:
       jmp 1b /* jump to '1' label before */
       jmp 1f /* jump to '1' label after */
  1:
-</pre></td></tr></table>
-
-</li></ul>
-
-<hr size="6">
-<a name="Directives"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Labels" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#X86-Assembler" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">4.4 Directives</h2>
-<a name="index-assembler-directives"></a>
-<a name="index-directives_002c-assembler"></a>
-<a name="index-align-directive"></a>
-<a name="index-skip-directive"></a>
-<a name="index-space-directive"></a>
-<a name="index-byte-directive"></a>
-<a name="index-word-directive"></a>
-<a name="index-short-directive"></a>
-<a name="index-int-directive"></a>
-<a name="index-long-directive"></a>
-<a name="index-quad-directive"></a>
-<a name="index-globl-directive"></a>
-<a name="index-global-directive"></a>
-<a name="index-section-directive"></a>
-<a name="index-text-directive"></a>
-<a name="index-data-directive"></a>
-<a name="index-bss-directive"></a>
-<a name="index-fill-directive"></a>
-<a name="index-org-directive"></a>
-<a name="index-previous-directive"></a>
-<a name="index-string-directive"></a>
-<a name="index-asciz-directive"></a>
-<a name="index-ascii-directive"></a>
-
-<p>All directives are preceeded by a &rsquo;.&rsquo;. The following directives are
+</pre></td></tr></table></P><P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC14"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.4 Directives </H2>
+<!--docid::SEC14::-->
+<P>
+
+All directives are preceded by a '.'. The following directives are
 supported:
-</p>
-<ul>
-<li> .align n[,value]
-</li><li> .skip n[,value]
-</li><li> .space n[,value]
-</li><li> .byte value1[,...]
-</li><li> .word value1[,...]
-</li><li> .short value1[,...]
-</li><li> .int value1[,...]
-</li><li> .long value1[,...]
-</li><li> .quad immediate_value1[,...]
-</li><li> .globl symbol
-</li><li> .global symbol
-</li><li> .section section
-</li><li> .text
-</li><li> .data
-</li><li> .bss
-</li><li> .fill repeat[,size[,value]]
-</li><li> .org n
-</li><li> .previous
-</li><li> .string string[,...]
-</li><li> .asciz string[,...]
-</li><li> .ascii string[,...]
-</li></ul>
-
-<hr size="6">
-<a name="X86-Assembler"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Directives" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#asm" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">4.5 X86 Assembler</h2>
-<a name="index-assembler"></a>
-
-<p>All X86 opcodes are supported. Only ATT syntax is supported (source
+</P><P>
+
+<UL>
+<LI>.align n[,value]
+<LI>.skip n[,value]
+<LI>.space n[,value]
+<LI>.byte value1[,...]
+<LI>.word value1[,...]
+<LI>.short value1[,...]
+<LI>.int value1[,...]
+<LI>.long value1[,...]
+<LI>.quad immediate_value1[,...]
+<LI>.globl symbol
+<LI>.global symbol
+<LI>.section section
+<LI>.text
+<LI>.data
+<LI>.bss
+<LI>.fill repeat[,size[,value]]
+<LI>.org n
+<LI>.previous
+<LI>.string string[,...]
+<LI>.asciz string[,...]
+<LI>.ascii string[,...]
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC15"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.5 X86 Assembler </H2>
+<!--docid::SEC15::-->
+<P>
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
 then destination operand order). If no size suffix is given, TinyCC
 tries to guess it from the operand sizes.
-</p>
-<p>Currently, MMX opcodes are supported but not SSE ones.
-</p>
-<hr size="6">
-<a name="linker"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#X86-Assembler" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#ELF-file-generation" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#asm" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="TinyCC-Linker"></a>
-<h1 class="chapter">5. TinyCC Linker</h1>
-<a name="index-linker"></a>
-
-<hr size="6">
-<a name="ELF-file-generation"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#linker" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#ELF-file-loader" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">5.1 ELF file generation</h2>
-<a name="index-ELF"></a>
-
-<p>TCC can directly output relocatable ELF files (object files),
+</P><P>
+
+Currently, MMX opcodes are supported but not SSE ones.
+</P><P>
+
+<A NAME="linker"></A>
+<HR SIZE="6">
+<A NAME="SEC16"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 5. TinyCC Linker </H1>
+<!--docid::SEC16::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC17"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.1 ELF file generation </H2>
+<!--docid::SEC17::-->
+<P>
+
+TCC can directly output relocatable ELF files (object files),
 executable ELF files and dynamic ELF libraries without relying on an
 external linker.
-</p>
-<p>Dynamic ELF libraries can be output but the C compiler does not generate
+</P><P>
+
+Dynamic ELF libraries can be output but the C compiler does not generate
 position independent code (PIC). It means that the dynamic library
 code generated by TCC cannot be factorized among processes yet.
-</p>
-<p>TCC linker eliminates unreferenced object code in libraries. A single pass is
+</P><P>
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
 done on the object and library list, so the order in which object files and
 libraries are specified is important (same constraint as GNU ld). No grouping
-options (&lsquo;<samp>--start-group</samp>&rsquo; and &lsquo;<samp>--end-group</samp>&rsquo;) are supported.
-</p>
-<hr size="6">
-<a name="ELF-file-loader"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#ELF-file-generation" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#PE_002di386-file-generation" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">5.2 ELF file loader</h2>
-
-<p>TCC can load ELF object files, archives (.a files) and dynamic
+options (<SAMP>`--start-group'</SAMP> and <SAMP>`--end-group'</SAMP>) are supported.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC18"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.2 ELF file loader </H2>
+<!--docid::SEC18::-->
+<P>
+
+TCC can load ELF object files, archives (.a files) and dynamic
 libraries (.so).
-</p>
-<hr size="6">
-<a name="PE_002di386-file-generation"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#ELF-file-loader" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#GNU-Linker-Scripts" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">5.3 PE-i386 file generation</h2>
-<a name="index-PE_002di386"></a>
-
-<p>TCC for Windows supports the native Win32 executable file format (PE-i386).  It
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC19"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.3 PE-i386 file generation </H2>
+<!--docid::SEC19::-->
+<P>
+
+TCC for Windows supports the native Win32 executable file format (PE-i386).  It
 generates EXE files (console and gui) and DLL files.
-</p>
-<p>For usage on Windows, see also tcc-win32.txt.
-</p>
-<hr size="6">
-<a name="GNU-Linker-Scripts"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#PE_002di386-file-generation" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#linker" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">5.4 GNU Linker Scripts</h2>
-<a name="index-scripts_002c-linker"></a>
-<a name="index-linker-scripts"></a>
-<a name="index-GROUP_002c-linker-command"></a>
-<a name="index-FILE_002c-linker-command"></a>
-<a name="index-OUTPUT_005fFORMAT_002c-linker-command"></a>
-<a name="index-TARGET_002c-linker-command"></a>
-
-<p>Because on many Linux systems some dynamic libraries (such as
-&lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;) are in fact GNU ld link scripts (horrible!),
+</P><P>
+
+For usage on Windows, see also tcc-win32.txt.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC20"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.4 GNU Linker Scripts </H2>
+<!--docid::SEC20::-->
+<P>
+
+Because on many Linux systems some dynamic libraries (such as
+<TT>`/usr/lib/libc.so'</TT>) are in fact GNU ld link scripts (horrible!),
 the TCC linker also supports a subset of GNU ld scripts.
-</p>
-<p>The <code>GROUP</code> and <code>FILE</code> commands are supported. <code>OUTPUT_FORMAT</code>
-and <code>TARGET</code> are ignored.
-</p>
-<p>Example from &lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;:
-</p><table><tr><td>&nbsp;</td><td><pre class="example">/* GNU ld script
+</P><P>
+
+The <CODE>GROUP</CODE> and <CODE>FILE</CODE> commands are supported. <CODE>OUTPUT_FORMAT</CODE>
+and <CODE>TARGET</CODE> are ignored.
+</P><P>
+
+Example from <TT>`/usr/lib/libc.so'</TT>:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>/* GNU ld script
    Use the shared library, but some functions are only in
    the static library, so try that secondarily.  */
 GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
-</pre></td></tr></table>
-
-<hr size="6">
-<a name="Bounds"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#GNU-Linker-Scripts" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Libtcc" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#linker" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Libtcc" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="TinyCC-Memory-and-Bound-checks"></a>
-<h1 class="chapter">6. TinyCC Memory and Bound checks</h1>
-<a name="index-bound-checks"></a>
-<a name="index-memory-checks"></a>
-
-<p>This feature is activated with the &lsquo;<samp>-b</samp>&rsquo; (see section <a href="#Invoke">Command line invocation</a>).
-</p>
-<p>Note that pointer size is <em>unchanged</em> and that code generated
-with bound checks is <em>fully compatible</em> with unchecked
+</pre></td></tr></table></P><P>
+
+<A NAME="Bounds"></A>
+<HR SIZE="6">
+<A NAME="SEC21"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 6. TinyCC Memory and Bound checks </H1>
+<!--docid::SEC21::-->
+<P>
+
+This feature is activated with the <SAMP>`-b'</SAMP> (see section <A HREF="tcc-doc.html#SEC2">2. Command line invocation</A>).
+</P><P>
+
+Note that pointer size is <EM>unchanged</EM> and that code generated
+with bound checks is <EM>fully compatible</EM> with unchecked
 code. When a pointer comes from unchecked code, it is assumed to be
 valid. Even very obscure C code with casts should work correctly.
-</p>
-<p>For more information about the ideas behind this method, see
-<a href="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</a>.
-</p>
-<p>Here are some examples of caught errors:
-</p>
-<dl compact="compact">
-<dt> Invalid range with standard string function:</dt>
-<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+</P><P>
+
+For more information about the ideas behind this method, see
+<A HREF="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</A>.
+</P><P>
+
+Here are some examples of caught errors:
+</P><P>
+
+<DL COMPACT>
+
+<DT>Invalid range with standard string function:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
     char tab[10];
     memset(tab, 0, 11);
 }
-</pre></td></tr></table>
-
-</dd>
-<dt> Out of bounds-error in global or local arrays:</dt>
-<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in global or local arrays:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
     int tab[10];
-    for(i=0;i&lt;11;i++) {
+    for(i=0;i&#60;11;i++) {
         sum += tab[i];
     }
 }
-</pre></td></tr></table>
-
-</dd>
-<dt> Out of bounds-error in malloc&rsquo;ed data:</dt>
-<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in malloc'ed data:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
     int *tab;
     tab = malloc(20 * sizeof(int));
-    for(i=0;i&lt;21;i++) {
+    for(i=0;i&#60;21;i++) {
         sum += tab4[i];
     }
     free(tab);
 }
-</pre></td></tr></table>
-
-</dd>
-<dt> Access of freed memory:</dt>
-<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+</pre></td></tr></table><P>
+
+<DT>Access of freed memory:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
     int *tab;
     tab = malloc(20 * sizeof(int));
     free(tab);
-    for(i=0;i&lt;20;i++) {
+    for(i=0;i&#60;20;i++) {
         sum += tab4[i];
     }
 }
-</pre></td></tr></table>
-
-</dd>
-<dt> Double free:</dt>
-<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+</pre></td></tr></table><P>
+
+<DT>Double free:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
     int *tab;
     tab = malloc(20 * sizeof(int));
@@ -1268,175 +1312,170 @@
     free(tab);
 }
-</pre></td></tr></table>
-
-</dd>
-</dl>
-
-<hr size="6">
-<a name="Libtcc"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Bounds" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Bounds" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="The-libtcc-library"></a>
-<h1 class="chapter">7. The <code>libtcc</code> library</h1>
-
-<p>The <code>libtcc</code> library enables you to use TCC as a backend for
+</pre></td></tr></table><P>
+
+</DL>
+<P>
+
+<A NAME="Libtcc"></A>
+<HR SIZE="6">
+<A NAME="SEC22"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 7. The <CODE>libtcc</CODE> library </H1>
+<!--docid::SEC22::-->
+<P>
+
+The <CODE>libtcc</CODE> library enables you to use TCC as a backend for
 dynamic code generation. 
-</p>
-<p>Read the &lsquo;<tt>libtcc.h</tt>&rsquo; to have an overview of the API. Read
-&lsquo;<tt>libtcc_test.c</tt>&rsquo; to have a very simple example.
-</p>
-<p>The idea consists in giving a C string containing the program you want
-to compile directly to <code>libtcc</code>. Then you can access to any global
+</P><P>
+
+Read the <TT>`libtcc.h'</TT> to have an overview of the API. Read
+<TT>`libtcc_test.c'</TT> to have a very simple example.
+</P><P>
+
+The idea consists in giving a C string containing the program you want
+to compile directly to <CODE>libtcc</CODE>. Then you can access to any global
 symbol (function or variable) defined.
-</p>
-<hr size="6">
-<a name="devel"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Libtcc" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#File-reading" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Libtcc" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<a name="Developer_0027s-guide"></a>
-<h1 class="chapter">8. Developer&rsquo;s guide</h1>
-
-<p>This chapter gives some hints to understand how TCC works. You can skip
+</P><P>
+
+<A NAME="devel"></A>
+<HR SIZE="6">
+<A NAME="SEC23"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 8. Developer's guide </H1>
+<!--docid::SEC23::-->
+<P>
+
+This chapter gives some hints to understand how TCC works. You can skip
 it if you do not intend to modify the TCC code.
-</p>
-<hr size="6">
-<a name="File-reading"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#devel" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Lexer" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.1 File reading</h2>
-
-<p>The <code>BufferedFile</code> structure contains the context needed to read a
-file, including the current line number. <code>tcc_open()</code> opens a new
-file and <code>tcc_close()</code> closes it. <code>inp()</code> returns the next
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC24"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.1 File reading </H2>
+<!--docid::SEC24::-->
+<P>
+
+The <CODE>BufferedFile</CODE> structure contains the context needed to read a
+file, including the current line number. <CODE>tcc_open()</CODE> opens a new
+file and <CODE>tcc_close()</CODE> closes it. <CODE>inp()</CODE> returns the next
 character.
-</p>
-<hr size="6">
-<a name="Lexer"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#File-reading" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Parser" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.2 Lexer</h2>
-
-<p><code>next()</code> reads the next token in the current
-file. <code>next_nomacro()</code> reads the next token without macro
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC25"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.2 Lexer </H2>
+<!--docid::SEC25::-->
+<P>
+
+<CODE>next()</CODE> reads the next token in the current
+file. <CODE>next_nomacro()</CODE> reads the next token without macro
 expansion.
-</p>
-<p><code>tok</code> contains the current token (see <code>TOK_xxx</code>)
-constants. Identifiers and keywords are also keywords. <code>tokc</code>
+</P><P>
+
+<CODE>tok</CODE> contains the current token (see <CODE>TOK_xxx</CODE>)
+constants. Identifiers and keywords are also keywords. <CODE>tokc</CODE>
 contains additional infos about the token (for example a constant value
 if number or string token).
-</p>
-<hr size="6">
-<a name="Parser"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Lexer" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Types" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.3 Parser</h2>
-
-<p>The parser is hardcoded (yacc is not necessary). It does only one pass,
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC26"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.3 Parser </H2>
+<!--docid::SEC26::-->
+<P>
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
 except:
-</p>
-<ul>
-<li> For initialized arrays with unknown size, a first pass 
+</P><P>
+
+<UL>
+
+<LI>For initialized arrays with unknown size, a first pass
 is done to count the number of elements.
-
-</li><li> For architectures where arguments are evaluated in 
+<P>
+
+<LI>For architectures where arguments are evaluated in
 reverse order, a first pass is done to reverse the argument order.
-
-</li></ul>
-
-<hr size="6">
-<a name="Types"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Parser" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Symbols" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.4 Types</h2>
-
-<p>The types are stored in a single &rsquo;int&rsquo; variable. It was choosen in the
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC27"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.4 Types </H2>
+<!--docid::SEC27::-->
+<P>
+
+The types are stored in a single 'int' variable. It was chosen in the
 first stages of development when tcc was much simpler. Now, it may not
 be the best solution.
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_INT        0  /* integer type */
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_INT        0  /* integer type */
 #define VT_BYTE       1  /* signed byte type */
 #define VT_SHORT      2  /* short type */
@@ -1460,31 +1499,37 @@
 #define VT_CONSTANT   0x0800  /* const modifier */
 #define VT_VOLATILE   0x1000  /* volatile modifier */
-#define VT_SIGNED     0x2000  /* signed type */
+#define VT_DEFSIGN    0x2000  /* signed type */
 
 #define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
-</pre></td></tr></table>
-
-<p>When a reference to another type is needed (for pointers, functions and
-structures), the <code>32 - VT_STRUCT_SHIFT</code> high order bits are used to
+</pre></td></tr></table></P><P>
+
+When a reference to another type is needed (for pointers, functions and
+structures), the <CODE>32 - VT_STRUCT_SHIFT</CODE> high order bits are used to
 store an identifier reference.
-</p>
-<p>The <code>VT_UNSIGNED</code> flag can be set for chars, shorts, ints and long
+</P><P>
+
+The <CODE>VT_UNSIGNED</CODE> flag can be set for chars, shorts, ints and long
 longs.
-</p>
-<p>Arrays are considered as pointers <code>VT_PTR</code> with the flag
-<code>VT_ARRAY</code> set. Variable length arrays are considered as special
-arrays and have flag <code>VT_VLA</code> set instead of <code>VT_ARRAY</code>.
-</p>
-<p>The <code>VT_BITFIELD</code> flag can be set for chars, shorts, ints and long
+</P><P>
+
+Arrays are considered as pointers <CODE>VT_PTR</CODE> with the flag
+<CODE>VT_ARRAY</CODE> set. Variable length arrays are considered as special
+arrays and have flag <CODE>VT_VLA</CODE> set instead of <CODE>VT_ARRAY</CODE>.
+</P><P>
+
+The <CODE>VT_BITFIELD</CODE> flag can be set for chars, shorts, ints and long
 longs. If it is set, then the bitfield position is stored from bits
 VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
 from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
-</p>
-<p><code>VT_LONG</code> is never used except during parsing.
-</p>
-<p>During parsing, the storage of an object is also stored in the type
+</P><P>
+
+<CODE>VT_LONG</CODE> is never used except during parsing.
+</P><P>
+
+During parsing, the storage of an object is also stored in the type
 integer:
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_EXTERN  0x00000080  /* extern definition */
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_EXTERN  0x00000080  /* extern definition */
 #define VT_STATIC  0x00000100  /* static variable */
 #define VT_TYPEDEF 0x00000200  /* typedef definition */
@@ -1493,217 +1538,217 @@
 #define VT_EXPORT  0x00008000  /* win32: data exported from dll */
 #define VT_WEAK    0x00010000  /* win32: data exported from dll */
-</pre></td></tr></table>
-
-<hr size="6">
-<a name="Symbols"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Types" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Sections" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.5 Symbols</h2>
-
-<p>All symbols are stored in hashed symbol stacks. Each symbol stack
-contains <code>Sym</code> structures.
-</p>
-<p><code>Sym.v</code> contains the symbol name (remember
-an idenfier is also a token, so a string is never necessary to store
-it). <code>Sym.t</code> gives the type of the symbol. <code>Sym.r</code> is usually
-the register in which the corresponding variable is stored. <code>Sym.c</code> is
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC28"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.5 Symbols </H2>
+<!--docid::SEC28::-->
+<P>
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains <CODE>Sym</CODE> structures.
+</P><P>
+
+<CODE>Sym.v</CODE> contains the symbol name (remember
+an identifier is also a token, so a string is never necessary to store
+it). <CODE>Sym.t</CODE> gives the type of the symbol. <CODE>Sym.r</CODE> is usually
+the register in which the corresponding variable is stored. <CODE>Sym.c</CODE> is
 usually a constant associated to the symbol like its address for normal
 symbols, and the number of entries for symbols representing arrays.
-Variable length array types use <code>Sym.c</code> as a location on the stack
+Variable length array types use <CODE>Sym.c</CODE> as a location on the stack
 which holds the runtime sizeof for the type.
-</p>
-<p>Four main symbol stacks are defined:
-</p>
-<dl compact="compact">
-<dt> <code>define_stack</code></dt>
-<dd><p>for the macros (<code>#define</code>s).
-</p>
-</dd>
-<dt> <code>global_stack</code></dt>
-<dd><p>for the global variables, functions and types.
-</p>
-</dd>
-<dt> <code>local_stack</code></dt>
-<dd><p>for the local variables, functions and types.
-</p>
-</dd>
-<dt> <code>global_label_stack</code></dt>
-<dd><p>for the local labels (for <code>goto</code>).
-</p>
-</dd>
-<dt> <code>label_stack</code></dt>
-<dd><p>for GCC block local labels (see the <code>__label__</code> keyword).
-</p>
-</dd>
-</dl>
-
-<p><code>sym_push()</code> is used to add a new symbol in the local symbol
+</P><P>
+
+Four main symbol stacks are defined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>define_stack</CODE>
+<DD>for the macros (<CODE>#define</CODE>s).
+<P>
+
+<DT><CODE>global_stack</CODE>
+<DD>for the global variables, functions and types.
+<P>
+
+<DT><CODE>local_stack</CODE>
+<DD>for the local variables, functions and types.
+<P>
+
+<DT><CODE>global_label_stack</CODE>
+<DD>for the local labels (for <CODE>goto</CODE>).
+<P>
+
+<DT><CODE>label_stack</CODE>
+<DD>for GCC block local labels (see the <CODE>__label__</CODE> keyword).
+<P>
+
+</DL>
+<P>
+
+<CODE>sym_push()</CODE> is used to add a new symbol in the local symbol
 stack. If no local symbol stack is active, it is added in the global
 symbol stack.
-</p>
-<p><code>sym_pop(st,b)</code> pops symbols from the symbol stack <var>st</var> until
-the symbol <var>b</var> is on the top of stack. If <var>b</var> is NULL, the stack
+</P><P>
+
+<CODE>sym_pop(st,b)</CODE> pops symbols from the symbol stack <VAR>st</VAR> until
+the symbol <VAR>b</VAR> is on the top of stack. If <VAR>b</VAR> is NULL, the stack
 is emptied.
-</p>
-<p><code>sym_find(v)</code> return the symbol associated to the identifier
-<var>v</var>. The local stack is searched first from top to bottom, then the
+</P><P>
+
+<CODE>sym_find(v)</CODE> return the symbol associated to the identifier
+<VAR>v</VAR>. The local stack is searched first from top to bottom, then the
 global stack.
-</p>
-<hr size="6">
-<a name="Sections"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Symbols" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Code-generation" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.6 Sections</h2>
-
-<p>The generated code and datas are written in sections. The structure
-<code>Section</code> contains all the necessary information for a given
-section. <code>new_section()</code> creates a new section. ELF file semantics
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC29"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.6 Sections </H2>
+<!--docid::SEC29::-->
+<P>
+
+The generated code and data are written in sections. The structure
+<CODE>Section</CODE> contains all the necessary information for a given
+section. <CODE>new_section()</CODE> creates a new section. ELF file semantics
 is assumed for each section.
-</p>
-<p>The following sections are predefined:
-</p>
-<dl compact="compact">
-<dt> <code>text_section</code></dt>
-<dd><p>is the section containing the generated code. <var>ind</var> contains the
+</P><P>
+
+The following sections are predefined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>text_section</CODE>
+<DD>is the section containing the generated code. <VAR>ind</VAR> contains the
 current position in the code section.
-</p>
-</dd>
-<dt> <code>data_section</code></dt>
-<dd><p>contains initialized data
-</p>
-</dd>
-<dt> <code>bss_section</code></dt>
-<dd><p>contains uninitialized data
-</p>
-</dd>
-<dt> <code>bounds_section</code></dt>
-<dt> <code>lbounds_section</code></dt>
-<dd><p>are used when bound checking is activated
-</p>
-</dd>
-<dt> <code>stab_section</code></dt>
-<dt> <code>stabstr_section</code></dt>
-<dd><p>are used when debugging is actived to store debug information
-</p>
-</dd>
-<dt> <code>symtab_section</code></dt>
-<dt> <code>strtab_section</code></dt>
-<dd><p>contain the exported symbols (currently only used for debugging).
-</p>
-</dd>
-</dl>
-
-<hr size="6">
-<a name="Code-generation"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Sections" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Introduction-2" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.7 Code generation</h2>
-<a name="index-code-generation"></a>
-
-<hr size="6">
-<a name="Introduction-2"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Code-generation" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#The-value-stack" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h3 class="subsection">8.7.1 Introduction</h3>
-
-<p>The TCC code generator directly generates linked binary code in one
+<P>
+
+<DT><CODE>data_section</CODE>
+<DD>contains initialized data
+<P>
+
+<DT><CODE>bss_section</CODE>
+<DD>contains uninitialized data
+<P>
+
+<DT><CODE>bounds_section</CODE>
+<DD><DT><CODE>lbounds_section</CODE>
+<DD>are used when bound checking is activated
+<P>
+
+<DT><CODE>stab_section</CODE>
+<DD><DT><CODE>stabstr_section</CODE>
+<DD>are used when debugging is active to store debug information
+<P>
+
+<DT><CODE>symtab_section</CODE>
+<DD><DT><CODE>strtab_section</CODE>
+<DD>contain the exported symbols (currently only used for debugging).
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC30"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.7 Code generation </H2>
+<!--docid::SEC30::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC31"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.1 Introduction </H3>
+<!--docid::SEC31::-->
+<P>
+
+The TCC code generator directly generates linked binary code in one
 pass. It is rather unusual these days (see gcc for example which
 generates text assembly), but it can be very fast and surprisingly
 little complicated.
-</p>
-<p>The TCC code generator is register based. Optimization is only done at
+</P><P>
+
+The TCC code generator is register based. Optimization is only done at
 the expression level. No intermediate representation of expression is
-kept except the current values stored in the <em>value stack</em>.
-</p>
-<p>On x86, three temporary registers are used. When more registers are
+kept except the current values stored in the <EM>value stack</EM>.
+</P><P>
+
+On x86, three temporary registers are used. When more registers are
 needed, one register is spilled into a new temporary variable on the stack.
-</p>
-<hr size="6">
-<a name="The-value-stack"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Introduction-2" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Manipulating-the-value-stack" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h3 class="subsection">8.7.2 The value stack</h3>
-<a name="index-value-stack_002c-introduction"></a>
-
-<p>When an expression is parsed, its value is pushed on the value stack
-(<var>vstack</var>). The top of the value stack is <var>vtop</var>. Each value
-stack entry is the structure <code>SValue</code>.
-</p>
-<p><code>SValue.t</code> is the type. <code>SValue.r</code> indicates how the value is
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC32"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.2 The value stack </H3>
+<!--docid::SEC32::-->
+<P>
+
+When an expression is parsed, its value is pushed on the value stack
+(<VAR>vstack</VAR>). The top of the value stack is <VAR>vtop</VAR>. Each value
+stack entry is the structure <CODE>SValue</CODE>.
+</P><P>
+
+<CODE>SValue.t</CODE> is the type. <CODE>SValue.r</CODE> indicates how the value is
 currently stored in the generated code. It is usually a CPU register
-index (<code>REG_xxx</code> constants), but additional values and flags are
+index (<CODE>REG_xxx</CODE> constants), but additional values and flags are
 defined:
-</p>
-<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_CONST     0x00f0
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_CONST     0x00f0
 #define VT_LLOCAL    0x00f1
 #define VT_LOCAL     0x00f2
@@ -1720,613 +1765,726 @@
 #define VT_LVAL_UNSIGNED 0x4000
 #define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
-</pre></td></tr></table>
-
-<dl compact="compact">
-<dt> <code>VT_CONST</code></dt>
-<dd><p>indicates that the value is a constant. It is stored in the union
-<code>SValue.c</code>, depending on its type.
-</p>
-</dd>
-<dt> <code>VT_LOCAL</code></dt>
-<dd><p>indicates a local variable pointer at offset <code>SValue.c.i</code> in the
+</pre></td></tr></table></P><P>
+
+<DL COMPACT>
+
+<DT><CODE>VT_CONST</CODE>
+<DD>indicates that the value is a constant. It is stored in the union
+<CODE>SValue.c</CODE>, depending on its type.
+<P>
+
+<DT><CODE>VT_LOCAL</CODE>
+<DD>indicates a local variable pointer at offset <CODE>SValue.c.i</CODE> in the
 stack.
-</p>
-</dd>
-<dt> <code>VT_CMP</code></dt>
-<dd><p>indicates that the value is actually stored in the CPU flags (i.e. the
+<P>
+
+<DT><CODE>VT_CMP</CODE>
+<DD>indicates that the value is actually stored in the CPU flags (i.e. the
 value is the consequence of a test). The value is either 0 or 1. The
-actual CPU flags used is indicated in <code>SValue.c.i</code>. 
-</p>
-<p>If any code is generated which destroys the CPU flags, this value MUST be
+actual CPU flags used is indicated in <CODE>SValue.c.i</CODE>. 
+<P>
+
+If any code is generated which destroys the CPU flags, this value MUST be
 put in a normal register.
-</p>
-</dd>
-<dt> <code>VT_JMP</code></dt>
-<dt> <code>VT_JMPI</code></dt>
-<dd><p>indicates that the value is the consequence of a conditional jump. For VT_JMP,
+</P><P>
+
+<DT><CODE>VT_JMP</CODE>
+<DD><DT><CODE>VT_JMPI</CODE>
+<DD>indicates that the value is the consequence of a conditional jump. For VT_JMP,
 it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
-</p>
-<p>These values are used to compile the <code>||</code> and <code>&amp;&amp;</code> logical
+<P>
+
+These values are used to compile the <CODE>||</CODE> and <CODE>&#38;&#38;</CODE> logical
 operators.
-</p>
-<p>If any code is generated, this value MUST be put in a normal
-register. Otherwise, the generated code won&rsquo;t be executed if the jump is
+</P><P>
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
 taken.
-</p>
-</dd>
-<dt> <code>VT_LVAL</code></dt>
-<dd><p>is a flag indicating that the value is actually an lvalue (left value of
+</P><P>
+
+<DT><CODE>VT_LVAL</CODE>
+<DD>is a flag indicating that the value is actually an lvalue (left value of
 an assignment). It means that the value stored is actually a pointer to
 the wanted value. 
-</p>
-<p>Understanding the use <code>VT_LVAL</code> is very important if you want to
+<P>
+
+Understanding the use <CODE>VT_LVAL</CODE> is very important if you want to
 understand how TCC works.
-</p>
-</dd>
-<dt> <code>VT_LVAL_BYTE</code></dt>
-<dt> <code>VT_LVAL_SHORT</code></dt>
-<dt> <code>VT_LVAL_UNSIGNED</code></dt>
-<dd><p>if the lvalue has an integer type, then these flags give its real
+</P><P>
+
+<DT><CODE>VT_LVAL_BYTE</CODE>
+<DD><DT><CODE>VT_LVAL_SHORT</CODE>
+<DD><DT><CODE>VT_LVAL_UNSIGNED</CODE>
+<DD>if the lvalue has an integer type, then these flags give its real
 type. The type alone is not enough in case of cast optimisations.
-</p>
-</dd>
-<dt> <code>VT_LLOCAL</code></dt>
-<dd><p>is a saved lvalue on the stack. <code>VT_LLOCAL</code> should be eliminated
-ASAP because its semantics are rather complicated.
-</p>
-</dd>
-<dt> <code>VT_MUSTCAST</code></dt>
-<dd><p>indicates that a cast to the value type must be performed if the value
+<P>
+
+<DT><CODE>VT_LLOCAL</CODE>
+<DD>is a saved lvalue on the stack. <CODE>VT_LVAL</CODE> must also be set with
+<CODE>VT_LLOCAL</CODE>. <CODE>VT_LLOCAL</CODE> can arise when a <CODE>VT_LVAL</CODE> in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
+<P>
+
+<DT><CODE>VT_MUSTCAST</CODE>
+<DD>indicates that a cast to the value type must be performed if the value
 is used (lazy casting).
-</p>
-</dd>
-<dt> <code>VT_SYM</code></dt>
-<dd><p>indicates that the symbol <code>SValue.sym</code> must be added to the constant.
-</p>
-</dd>
-<dt> <code>VT_MUSTBOUND</code></dt>
-<dt> <code>VT_BOUNDED</code></dt>
-<dd><p>are only used for optional bound checking.
-</p>
-</dd>
-</dl>
-
-<hr size="6">
-<a name="Manipulating-the-value-stack"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#The-value-stack" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#CPU-dependent-code-generation" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h3 class="subsection">8.7.3 Manipulating the value stack</h3>
-<a name="index-value-stack"></a>
-
-<p><code>vsetc()</code> and <code>vset()</code> pushes a new value on the value
-stack. If the previous <var>vtop</var> was stored in a very unsafe place(for
+<P>
+
+<DT><CODE>VT_SYM</CODE>
+<DD>indicates that the symbol <CODE>SValue.sym</CODE> must be added to the constant.
+<P>
+
+<DT><CODE>VT_MUSTBOUND</CODE>
+<DD><DT><CODE>VT_BOUNDED</CODE>
+<DD>are only used for optional bound checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC33"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.3 Manipulating the value stack </H3>
+<!--docid::SEC33::-->
+<P>
+
+<CODE>vsetc()</CODE> and <CODE>vset()</CODE> pushes a new value on the value
+stack. If the previous <VAR>vtop</VAR> was stored in a very unsafe place(for
 example in the CPU flags), then some code is generated to put the
-previous <var>vtop</var> in a safe storage.
-</p>
-<p><code>vpop()</code> pops <var>vtop</var>. In some cases, it also generates cleanup
+previous <VAR>vtop</VAR> in a safe storage.
+</P><P>
+
+<CODE>vpop()</CODE> pops <VAR>vtop</VAR>. In some cases, it also generates cleanup
 code (for example if stacked floating point registers are used as on
 x86).
-</p>
-<p>The <code>gv(rc)</code> function generates code to evaluate <var>vtop</var> (the
-top value of the stack) into registers. <var>rc</var> selects in which
-register class the value should be put. <code>gv()</code> is the <em>most
-important function</em> of the code generator.
-</p>
-<p><code>gv2()</code> is the same as <code>gv()</code> but for the top two stack
+</P><P>
+
+The <CODE>gv(rc)</CODE> function generates code to evaluate <VAR>vtop</VAR> (the
+top value of the stack) into registers. <VAR>rc</VAR> selects in which
+register class the value should be put. <CODE>gv()</CODE> is the <EM>most
+important function</EM> of the code generator.
+</P><P>
+
+<CODE>gv2()</CODE> is the same as <CODE>gv()</CODE> but for the top two stack
 entries.
-</p>
-<hr size="6">
-<a name="CPU-dependent-code-generation"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Manipulating-the-value-stack" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Optimizations-done" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Code-generation" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h3 class="subsection">8.7.4 CPU dependent code generation</h3>
-<a name="index-CPU-dependent"></a>
-<p>See the &lsquo;<tt>i386-gen.c</tt>&rsquo; file to have an example.
-</p>
-<dl compact="compact">
-<dt> <code>load()</code></dt>
-<dd><p>must generate the code needed to load a stack value into a register.
-</p>
-</dd>
-<dt> <code>store()</code></dt>
-<dd><p>must generate the code needed to store a register into a stack value
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC34"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.4 CPU dependent code generation </H3>
+<!--docid::SEC34::-->
+See the <TT>`i386-gen.c'</TT> file to have an example.
+<P>
+
+<DL COMPACT>
+
+<DT><CODE>load()</CODE>
+<DD>must generate the code needed to load a stack value into a register.
+<P>
+
+<DT><CODE>store()</CODE>
+<DD>must generate the code needed to store a register into a stack value
 lvalue.
-</p>
-</dd>
-<dt> <code>gfunc_start()</code></dt>
-<dt> <code>gfunc_param()</code></dt>
-<dt> <code>gfunc_call()</code></dt>
-<dd><p>should generate a function call
-</p>
-</dd>
-<dt> <code>gfunc_prolog()</code></dt>
-<dt> <code>gfunc_epilog()</code></dt>
-<dd><p>should generate a function prolog/epilog.
-</p>
-</dd>
-<dt> <code>gen_opi(op)</code></dt>
-<dd><p>must generate the binary integer operation <var>op</var> on the two top
-entries of the stack which are guaranted to contain integer types.
-</p>
-<p>The result value should be put on the stack.
-</p>
-</dd>
-<dt> <code>gen_opf(op)</code></dt>
-<dd><p>same as <code>gen_opi()</code> for floating point operations. The two top
-entries of the stack are guaranted to contain floating point values of
+<P>
+
+<DT><CODE>gfunc_start()</CODE>
+<DD><DT><CODE>gfunc_param()</CODE>
+<DD><DT><CODE>gfunc_call()</CODE>
+<DD>should generate a function call
+<P>
+
+<DT><CODE>gfunc_prolog()</CODE>
+<DD><DT><CODE>gfunc_epilog()</CODE>
+<DD>should generate a function prolog/epilog.
+<P>
+
+<DT><CODE>gen_opi(op)</CODE>
+<DD>must generate the binary integer operation <VAR>op</VAR> on the two top
+entries of the stack which are guaranteed to contain integer types.
+<P>
+
+The result value should be put on the stack.
+</P><P>
+
+<DT><CODE>gen_opf(op)</CODE>
+<DD>same as <CODE>gen_opi()</CODE> for floating point operations. The two top
+entries of the stack are guaranteed to contain floating point values of
 same types.
-</p>
-</dd>
-<dt> <code>gen_cvt_itof()</code></dt>
-<dd><p>integer to floating point conversion.
-</p>
-</dd>
-<dt> <code>gen_cvt_ftoi()</code></dt>
-<dd><p>floating point to integer conversion.
-</p>
-</dd>
-<dt> <code>gen_cvt_ftof()</code></dt>
-<dd><p>floating point to floating point of different size conversion.
-</p>
-</dd>
-<dt> <code>gen_bounded_ptr_add()</code></dt>
-<dt> <code>gen_bounded_ptr_deref()</code></dt>
-<dd><p>are only used for bounds checking.
-</p>
-</dd>
-</dl>
-
-<hr size="6">
-<a name="Optimizations-done"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#CPU-dependent-code-generation" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next section in reading order"> &gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#devel" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Next chapter"> &gt;&gt; </a>]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h2 class="section">8.8 Optimizations done</h2>
-<a name="index-optimizations"></a>
-<a name="index-constant-propagation"></a>
-<a name="index-strength-reduction"></a>
-<a name="index-comparison-operators"></a>
-<a name="index-caching-processor-flags"></a>
-<a name="index-flags_002c-caching"></a>
-<a name="index-jump-optimization"></a>
-<p>Constant propagation is done for all operations. Multiplications and
+<P>
+
+<DT><CODE>gen_cvt_itof()</CODE>
+<DD>integer to floating point conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftoi()</CODE>
+<DD>floating point to integer conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftof()</CODE>
+<DD>floating point to floating point of different size conversion.
+<P>
+
+<DT><CODE>gen_bounded_ptr_add()</CODE>
+<DD><DT><CODE>gen_bounded_ptr_deref()</CODE>
+<DD>are only used for bounds checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC35"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.8 Optimizations done </H2>
+<!--docid::SEC35::-->
+Constant propagation is done for all operations. Multiplications and
 divisions are optimized to shifts when appropriate. Comparison
 operators are optimized by maintaining a special cache for the
-processor flags. &amp;&amp;, || and ! are optimized by maintaining a special
-&rsquo;jump target&rsquo; value. No other jump optimization is currently performed
+processor flags. &#38;&#38;, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
 because it would require to store the code in a more abstract fashion.
-</p>
-<hr size="6">
-<a name="Concept-Index"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Optimizations-done" title="Previous section in reading order"> &lt; </a>]</td>
-<td valign="middle" align="left">[ &gt; ]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#devel" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
-<td valign="middle" align="left">[<a href="#Top" title="Up section"> Up </a>]</td>
-<td valign="middle" align="left">[ &gt;&gt; ]</td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left"> &nbsp; </td>
-<td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h1 class="unnumbered">Concept Index</h1>
-<table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#Concept-Index_cp_symbol-1" class="summary-letter"><b>_</b></a>
- &nbsp; 
-<br>
-<a href="#Concept-Index_cp_letter-A" class="summary-letter"><b>A</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-B" class="summary-letter"><b>B</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-C" class="summary-letter"><b>C</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-D" class="summary-letter"><b>D</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-E" class="summary-letter"><b>E</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-F" class="summary-letter"><b>F</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-G" class="summary-letter"><b>G</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-I" class="summary-letter"><b>I</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-J" class="summary-letter"><b>J</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-L" class="summary-letter"><b>L</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-M" class="summary-letter"><b>M</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-O" class="summary-letter"><b>O</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-P" class="summary-letter"><b>P</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-Q" class="summary-letter"><b>Q</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-R" class="summary-letter"><b>R</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-S" class="summary-letter"><b>S</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-T" class="summary-letter"><b>T</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-U" class="summary-letter"><b>U</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-V" class="summary-letter"><b>V</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-W" class="summary-letter"><b>W</b></a>
- &nbsp; 
-</td></tr></table>
-<table border="0" class="index-cp">
-<tr><td></td><th align="left">Index Entry</th><th align="left"> Section</th></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_symbol-1">_</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-_005f_005fasm_005f_005f">__asm__</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-A">A</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-align-directive">align directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-aligned-attribute">aligned attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-ascii-directive">ascii directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-asciz-directive">asciz directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-assembler">assembler</a></td><td valign="top"><a href="#X86-Assembler">4.5 X86 Assembler</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-assembler-directives">assembler directives</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-assembly_002c-inline">assembly, inline</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-B">B</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-bound-checks">bound checks</a></td><td valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-bss-directive">bss directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-byte-directive">byte directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-C">C</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-caching-processor-flags">caching processor flags</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-cdecl-attribute">cdecl attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-code-generation">code generation</a></td><td valign="top"><a href="#Code-generation">8.7 Code generation</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-comparison-operators">comparison operators</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-constant-propagation">constant propagation</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-CPU-dependent">CPU dependent</a></td><td valign="top"><a href="#CPU-dependent-code-generation">8.7.4 CPU dependent code generation</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-D">D</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-data-directive">data directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-directives_002c-assembler">directives, assembler</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-dllexport-attribute">dllexport attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-E">E</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-ELF">ELF</a></td><td valign="top"><a href="#ELF-file-generation">5.1 ELF file generation</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-F">F</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-FILE_002c-linker-command">FILE, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-fill-directive">fill directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-flags_002c-caching">flags, caching</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-G">G</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-gas">gas</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-global-directive">global directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-globl-directive">globl directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-GROUP_002c-linker-command">GROUP, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-I">I</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-inline-assembly">inline assembly</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-int-directive">int directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-J">J</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-jump-optimization">jump optimization</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-L">L</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-linker">linker</a></td><td valign="top"><a href="#linker">5. TinyCC Linker</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-linker-scripts">linker scripts</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-long-directive">long directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-M">M</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-memory-checks">memory checks</a></td><td valign="top"><a href="#Bounds">6. TinyCC Memory and Bound checks</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-O">O</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-optimizations">optimizations</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-org-directive">org directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-OUTPUT_005fFORMAT_002c-linker-command">OUTPUT_FORMAT, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-P">P</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-packed-attribute">packed attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-PE_002di386">PE-i386</a></td><td valign="top"><a href="#PE_002di386-file-generation">5.3 PE-i386 file generation</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-previous-directive">previous directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-Q">Q</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-quad-directive">quad directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-R">R</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-regparm-attribute">regparm attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-S">S</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-scripts_002c-linker">scripts, linker</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-section-attribute">section attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-section-directive">section directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-short-directive">short directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-skip-directive">skip directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-space-directive">space directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-stdcall-attribute">stdcall attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-strength-reduction">strength reduction</a></td><td valign="top"><a href="#Optimizations-done">8.8 Optimizations done</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-string-directive">string directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-T">T</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-TARGET_002c-linker-command">TARGET, linker command</a></td><td valign="top"><a href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-text-directive">text directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-U">U</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-unused-attribute">unused attribute</a></td><td valign="top"><a href="#GNU-C-extensions">3.3 GNU C extensions</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-V">V</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-value-stack">value stack</a></td><td valign="top"><a href="#Manipulating-the-value-stack">8.7.3 Manipulating the value stack</a></td></tr>
-<tr><td></td><td valign="top"><a href="#index-value-stack_002c-introduction">value stack, introduction</a></td><td valign="top"><a href="#The-value-stack">8.7.2 The value stack</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-<tr><th><a name="Concept-Index_cp_letter-W">W</a></th><td></td><td></td></tr>
-<tr><td></td><td valign="top"><a href="#index-word-directive">word directive</a></td><td valign="top"><a href="#Directives">4.4 Directives</a></td></tr>
-<tr><td colspan="3"> <hr></td></tr>
-</table>
-<table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#Concept-Index_cp_symbol-1" class="summary-letter"><b>_</b></a>
- &nbsp; 
-<br>
-<a href="#Concept-Index_cp_letter-A" class="summary-letter"><b>A</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-B" class="summary-letter"><b>B</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-C" class="summary-letter"><b>C</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-D" class="summary-letter"><b>D</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-E" class="summary-letter"><b>E</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-F" class="summary-letter"><b>F</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-G" class="summary-letter"><b>G</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-I" class="summary-letter"><b>I</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-J" class="summary-letter"><b>J</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-L" class="summary-letter"><b>L</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-M" class="summary-letter"><b>M</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-O" class="summary-letter"><b>O</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-P" class="summary-letter"><b>P</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-Q" class="summary-letter"><b>Q</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-R" class="summary-letter"><b>R</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-S" class="summary-letter"><b>S</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-T" class="summary-letter"><b>T</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-U" class="summary-letter"><b>U</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-V" class="summary-letter"><b>V</b></a>
- &nbsp; 
-<a href="#Concept-Index_cp_letter-W" class="summary-letter"><b>W</b></a>
- &nbsp; 
-</td></tr></table>
-
-<hr size="6">
-<a name="SEC_Contents"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h1>Table of Contents</h1>
-<div class="contents">
-
-<ul class="toc">
-  <li><a name="toc-Introduction-1" href="#Introduction">1. Introduction</a></li>
-  <li><a name="toc-Command-line-invocation" href="#Invoke">2. Command line invocation</a>
-  <ul class="toc">
-    <li><a name="toc-Quick-start" href="#Quick-start">2.1 Quick start</a></li>
-    <li><a name="toc-Option-summary" href="#Option-summary">2.2 Option summary</a></li>
-  </ul></li>
-  <li><a name="toc-C-language-support" href="#Clang">3. C language support</a>
-  <ul class="toc">
-    <li><a name="toc-ANSI-C" href="#ANSI-C">3.1 ANSI C</a></li>
-    <li><a name="toc-ISOC99-extensions" href="#ISOC99-extensions">3.2 ISOC99 extensions</a></li>
-    <li><a name="toc-GNU-C-extensions" href="#GNU-C-extensions">3.3 GNU C extensions</a></li>
-    <li><a name="toc-TinyCC-extensions" href="#TinyCC-extensions">3.4 TinyCC extensions</a></li>
-  </ul></li>
-  <li><a name="toc-TinyCC-Assembler" href="#asm">4. TinyCC Assembler</a>
-  <ul class="toc">
-    <li><a name="toc-Syntax" href="#Syntax">4.1 Syntax</a></li>
-    <li><a name="toc-Expressions" href="#Expressions">4.2 Expressions</a></li>
-    <li><a name="toc-Labels" href="#Labels">4.3 Labels</a></li>
-    <li><a name="toc-Directives" href="#Directives">4.4 Directives</a></li>
-    <li><a name="toc-X86-Assembler" href="#X86-Assembler">4.5 X86 Assembler</a></li>
-  </ul></li>
-  <li><a name="toc-TinyCC-Linker" href="#linker">5. TinyCC Linker</a>
-  <ul class="toc">
-    <li><a name="toc-ELF-file-generation" href="#ELF-file-generation">5.1 ELF file generation</a></li>
-    <li><a name="toc-ELF-file-loader" href="#ELF-file-loader">5.2 ELF file loader</a></li>
-    <li><a name="toc-PE_002di386-file-generation" href="#PE_002di386-file-generation">5.3 PE-i386 file generation</a></li>
-    <li><a name="toc-GNU-Linker-Scripts" href="#GNU-Linker-Scripts">5.4 GNU Linker Scripts</a></li>
-  </ul></li>
-  <li><a name="toc-TinyCC-Memory-and-Bound-checks" href="#Bounds">6. TinyCC Memory and Bound checks</a></li>
-  <li><a name="toc-The-libtcc-library" href="#Libtcc">7. The <code>libtcc</code> library</a></li>
-  <li><a name="toc-Developer_0027s-guide" href="#devel">8. Developer&rsquo;s guide</a>
-  <ul class="toc">
-    <li><a name="toc-File-reading" href="#File-reading">8.1 File reading</a></li>
-    <li><a name="toc-Lexer" href="#Lexer">8.2 Lexer</a></li>
-    <li><a name="toc-Parser" href="#Parser">8.3 Parser</a></li>
-    <li><a name="toc-Types" href="#Types">8.4 Types</a></li>
-    <li><a name="toc-Symbols" href="#Symbols">8.5 Symbols</a></li>
-    <li><a name="toc-Sections" href="#Sections">8.6 Sections</a></li>
-    <li><a name="toc-Code-generation" href="#Code-generation">8.7 Code generation</a>
-    <ul class="toc">
-      <li><a name="toc-Introduction-2" href="#Introduction-2">8.7.1 Introduction</a></li>
-      <li><a name="toc-The-value-stack" href="#The-value-stack">8.7.2 The value stack</a></li>
-      <li><a name="toc-Manipulating-the-value-stack" href="#Manipulating-the-value-stack">8.7.3 Manipulating the value stack</a></li>
-      <li><a name="toc-CPU-dependent-code-generation" href="#CPU-dependent-code-generation">8.7.4 CPU dependent code generation</a></li>
-    </ul></li>
-    <li><a name="toc-Optimizations-done" href="#Optimizations-done">8.8 Optimizations done</a></li>
-  </ul></li>
-  <li><a name="toc-Concept-Index" href="#Concept-Index">Concept Index</a></li>
-</ul>
-</div>
-<hr size="1">
-<a name="SEC_About"></a>
-<table cellpadding="1" cellspacing="1" border="0">
-<tr><td valign="middle" align="left">[<a href="#Top" title="Cover (top) of document">Top</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
-<td valign="middle" align="left">[<a href="#Concept-Index" title="Index">Index</a>]</td>
-<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
-</tr></table>
-<h1>About This Document</h1>
-<p>
-  This document was generated by <em>Thomas Preud'homme</em> on <em>February 15, 2013</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.
-</p>
-<p>
-  The buttons in the navigation panels have the following meaning:
-</p>
-<table border="1">
-  <tr>
-    <th> Button </th>
-    <th> Name </th>
-    <th> Go to </th>
-    <th> From 1.2.3 go to</th>
-  </tr>
-  <tr>
-    <td align="center"> [ &lt; ] </td>
-    <td align="center">Back</td>
-    <td>Previous section in reading order</td>
-    <td>1.2.2</td>
-  </tr>
-  <tr>
-    <td align="center"> [ &gt; ] </td>
-    <td align="center">Forward</td>
-    <td>Next section in reading order</td>
-    <td>1.2.4</td>
-  </tr>
-  <tr>
-    <td align="center"> [ &lt;&lt; ] </td>
-    <td align="center">FastBack</td>
-    <td>Beginning of this chapter or previous chapter</td>
-    <td>1</td>
-  </tr>
-  <tr>
-    <td align="center"> [ Up ] </td>
-    <td align="center">Up</td>
-    <td>Up section</td>
-    <td>1.2</td>
-  </tr>
-  <tr>
-    <td align="center"> [ &gt;&gt; ] </td>
-    <td align="center">FastForward</td>
-    <td>Next chapter</td>
-    <td>2</td>
-  </tr>
-  <tr>
-    <td align="center"> [Top] </td>
-    <td align="center">Top</td>
-    <td>Cover (top) of document</td>
-    <td> &nbsp; </td>
-  </tr>
-  <tr>
-    <td align="center"> [Contents] </td>
-    <td align="center">Contents</td>
-    <td>Table of contents</td>
-    <td> &nbsp; </td>
-  </tr>
-  <tr>
-    <td align="center"> [Index] </td>
-    <td align="center">Index</td>
-    <td>Index</td>
-    <td> &nbsp; </td>
-  </tr>
-  <tr>
-    <td align="center"> [ ? ] </td>
-    <td align="center">About</td>
-    <td>About (help)</td>
-    <td> &nbsp; </td>
-  </tr>
-</table>
-
-<p>
-  where the <strong> Example </strong> assumes that the current position is at <strong> Subsubsection One-Two-Three </strong> of a document of the following structure:
-</p>
-
-<ul>
-  <li> 1. Section One
-    <ul>
-      <li>1.1 Subsection One-One
-        <ul>
-          <li>...</li>
-        </ul>
-      </li>
-      <li>1.2 Subsection One-Two
-        <ul>
-          <li>1.2.1 Subsubsection One-Two-One</li>
-          <li>1.2.2 Subsubsection One-Two-Two</li>
-          <li>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp;
-            <strong>&lt;== Current Position </strong></li>
-          <li>1.2.4 Subsubsection One-Two-Four</li>
-        </ul>
-      </li>
-      <li>1.3 Subsection One-Three
-        <ul>
-          <li>...</li>
-        </ul>
-      </li>
-      <li>1.4 Subsection One-Four</li>
-    </ul>
-  </li>
-</ul>
-
-<hr size="1">
-<p>
- <font size="-1">
-  This document was generated by <em>Thomas Preud'homme</em> on <em>February 15, 2013</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.82</em></a>.
- </font>
- <br>
-
-</p>
-</body>
-</html>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC36"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> Concept Index </H1>
+<!--docid::SEC36::-->
+<table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp; 
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp; 
+</td></tr></table><br><P></P>
+<TABLE border=0>
+<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp__"></A>_</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX11">__asm__</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_A"></A>A</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">align directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX1">aligned attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">ascii directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">asciz directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">assembler directives</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX10">assembly, inline</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_B"></A>B</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">bound checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">bss directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">byte directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_C"></A>C</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">caching processor flags</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX5">cdecl attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">code generation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">8.7 Code generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">comparison operators</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">constant propagation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">CPU dependent</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_D"></A>D</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">data directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">directives, assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX8">dllexport attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_E"></A>E</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">ELF</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_F"></A>F</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">FILE, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">fill directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">flags, caching</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_G"></A>G</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX12">gas</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">global directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">globl directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">GROUP, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_I"></A>I</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX9">inline assembly</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">int directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_J"></A>J</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">jump optimization</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_L"></A>L</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">linker scripts</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">long directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_M"></A>M</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">memory checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_O"></A>O</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">optimizations</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">org directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">OUTPUT_FORMAT, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_P"></A>P</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX2">packed attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">PE-i386</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">previous directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_Q"></A>Q</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">quad directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_R"></A>R</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX7">regparm attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_S"></A>S</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">scripts, linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX3">section attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">section directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">short directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">skip directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">space directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX6">stdcall attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">strength reduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">string directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_T"></A>T</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">TARGET, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">text directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_U"></A>U</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX4">unused attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_V"></A>V</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">value stack</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">value stack, introduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_W"></A>W</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">word directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+</TABLE><P></P><table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp; 
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp; 
+</td></tr></table><br><P>
+
+<HR SIZE="6">
+<A NAME="SEC_Contents"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Table of Contents</H1>
+<UL>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<UL>
+<A NAME="TOC3" HREF="tcc-doc.html#SEC3">2.1 Quick start</A>
+<BR>
+<A NAME="TOC4" HREF="tcc-doc.html#SEC4">2.2 Option summary</A>
+<BR>
+</UL>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<UL>
+<A NAME="TOC6" HREF="tcc-doc.html#SEC6">3.1 ANSI C</A>
+<BR>
+<A NAME="TOC7" HREF="tcc-doc.html#SEC7">3.2 ISOC99 extensions</A>
+<BR>
+<A NAME="TOC8" HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A>
+<BR>
+<A NAME="TOC9" HREF="tcc-doc.html#SEC9">3.4 TinyCC extensions</A>
+<BR>
+</UL>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<UL>
+<A NAME="TOC11" HREF="tcc-doc.html#SEC11">4.1 Syntax</A>
+<BR>
+<A NAME="TOC12" HREF="tcc-doc.html#SEC12">4.2 Expressions</A>
+<BR>
+<A NAME="TOC13" HREF="tcc-doc.html#SEC13">4.3 Labels</A>
+<BR>
+<A NAME="TOC14" HREF="tcc-doc.html#SEC14">4.4 Directives</A>
+<BR>
+<A NAME="TOC15" HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A>
+<BR>
+</UL>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<UL>
+<A NAME="TOC17" HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A>
+<BR>
+<A NAME="TOC18" HREF="tcc-doc.html#SEC18">5.2 ELF file loader</A>
+<BR>
+<A NAME="TOC19" HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A>
+<BR>
+<A NAME="TOC20" HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A>
+<BR>
+</UL>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<UL>
+<A NAME="TOC24" HREF="tcc-doc.html#SEC24">8.1 File reading</A>
+<BR>
+<A NAME="TOC25" HREF="tcc-doc.html#SEC25">8.2 Lexer</A>
+<BR>
+<A NAME="TOC26" HREF="tcc-doc.html#SEC26">8.3 Parser</A>
+<BR>
+<A NAME="TOC27" HREF="tcc-doc.html#SEC27">8.4 Types</A>
+<BR>
+<A NAME="TOC28" HREF="tcc-doc.html#SEC28">8.5 Symbols</A>
+<BR>
+<A NAME="TOC29" HREF="tcc-doc.html#SEC29">8.6 Sections</A>
+<BR>
+<A NAME="TOC30" HREF="tcc-doc.html#SEC30">8.7 Code generation</A>
+<BR>
+<UL>
+<A NAME="TOC31" HREF="tcc-doc.html#SEC31">8.7.1 Introduction</A>
+<BR>
+<A NAME="TOC32" HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A>
+<BR>
+<A NAME="TOC33" HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A>
+<BR>
+<A NAME="TOC34" HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A>
+<BR>
+</UL>
+<A NAME="TOC35" HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A>
+<BR>
+</UL>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+</UL>
+<HR SIZE=1>
+<A NAME="SEC_OVERVIEW"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Short Table of Contents</H1>
+<BLOCKQUOTE>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+
+</BLOCKQUOTE>
+<HR SIZE=1>
+<A NAME="SEC_About"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>About this document</H1>
+This document was generated on <I>December, 17  2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+<P></P>  
+The buttons in the navigation panels have the following meaning:
+<P></P>
+<table border = "1">
+<TR>
+<TH> Button </TH>
+<TH> Name </TH>
+<TH> Go to </TH>
+<TH> From 1.2.3 go to</TH>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt; ] </TD>
+<TD ALIGN="CENTER">
+Back
+</TD>
+<TD>
+previous section in reading order
+</TD>
+<TD>
+1.2.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt; ] </TD>
+<TD ALIGN="CENTER">
+Forward
+</TD>
+<TD>
+next section in reading order
+</TD>
+<TD>
+1.2.4
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt;&lt; ] </TD>
+<TD ALIGN="CENTER">
+FastBack
+</TD>
+<TD>
+previous or up-and-previous section 
+</TD>
+<TD>
+1.1
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ Up ] </TD>
+<TD ALIGN="CENTER">
+Up
+</TD>
+<TD>
+up section
+</TD>
+<TD>
+1.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt;&gt; ] </TD>
+<TD ALIGN="CENTER">
+FastForward
+</TD>
+<TD>
+next or up-and-next section
+</TD>
+<TD>
+1.3
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Top] </TD>
+<TD ALIGN="CENTER">
+Top
+</TD>
+<TD>
+cover (top) of document
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Contents] </TD>
+<TD ALIGN="CENTER">
+Contents
+</TD>
+<TD>
+table of contents
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Index] </TD>
+<TD ALIGN="CENTER">
+Index
+</TD>
+<TD>
+concept index
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ ? ] </TD>
+<TD ALIGN="CENTER">
+About
+</TD>
+<TD>
+this page
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+</TABLE>
+<P></P>
+where the <STRONG> Example </STRONG> assumes that the current position 
+is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
+the following structure:
+<UL>
+<LI> 1. Section One  </LI>
+<UL>
+<LI>1.1 Subsection One-One</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.2 Subsection One-Two</LI>
+<UL>
+<LI>1.2.1 Subsubsection One-Two-One
+</LI><LI>1.2.2 Subsubsection One-Two-Two
+</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
+&lt;== Current Position </STRONG>
+</LI><LI>1.2.4 Subsubsection One-Two-Four
+</LI></UL>
+<LI>1.3 Subsection One-Three</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.4 Subsection One-Four</LI>
+</UL>
+</UL>
+
+<HR SIZE=1>
+<BR>  
+<FONT SIZE="-1">
+This document was generated
+on <I>December, 17  2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+
+</BODY>
+</HTML>
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcc-doc.texi	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi	(revision 331)
@@ -177,19 +177,12 @@
 @end example
 
-@item -dumpversion
-Print only the compiler version and nothing else.
-
 @item -v
 Display TCC version.
 
 @item -vv
-Show included files.  As sole argument, print search dirs (as below).
+Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
 
 @item -bench
 Display compilation statistics.
-
-@item -print-search-dirs
-Print the configured installation directory and a list of library
-and include directories tcc will search.
 
 @end table
@@ -214,9 +207,13 @@
 @item -Usym
 Undefine preprocessor symbol @samp{sym}.
+
+@item -E
+Preprocess only, to stdout or file (with -o).
+
 @end table
 
 Compilation flags:
 
-Note: each of the following warning options has a negative form beginning with
+Note: each of the following options has a negative form beginning with
 @option{-fno-}.
 
@@ -233,4 +230,12 @@
 @item -fleading-underscore
 Add a leading underscore at the beginning of each C symbol.
+
+@item -fms-extensions
+Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+
+@item -fdollars-in-identifiers
+Allow dollar signs in identifiers
 
 @end table
@@ -277,5 +282,5 @@
 Link your program with dynamic library libxxx.so or static library
 libxxx.a. The library is searched in the paths specified by the
-@option{-L} option.
+@option{-L} option and @env{LIBRARY_PATH} variable.
 
 @item -Bdir
@@ -301,5 +306,9 @@
 
 @item -Wl,-rpath=path
-Put custom seatch path for dynamic libraries into executable.
+Put custom search path for dynamic libraries into executable.
+
+@item -Wl,--enable-new-dtags
+When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
 
 @item -Wl,--oformat=fmt
@@ -323,4 +332,7 @@
 Set DT_SYMBOLIC tag.
 
+@item -Wl,-(no-)whole-archive
+Turn on/off linking of all objects in archives.
+
 @end table
 
@@ -339,5 +351,5 @@
 that the generated code is slower and bigger in this case.
 
-Note: @option{-b} is only available on i386 for the moment.
+Note: @option{-b} is only available on i386 when using libtcc for the moment.
 
 @item -bt N
@@ -356,4 +368,29 @@
 Use @file{depfile} as output for -MD.
 
+@item -print-search-dirs
+Print the configured installation directory and a list of library
+and include directories tcc will search.
+
+@item -dumpversion
+Print version.
+
+@end table
+
+Target specific options:
+
+@table @option
+@item -mms-bitfields
+Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+
+@item -mfloat-abi (ARM only)
+Select the float ABI. Possible values: @code{softfp} and @code{hard}
+
+@item -mno-sse
+Do not use sse registers on x86_64
+
+@item -m32, -m64
+Pass command line to the i386/x86_64 cross compiler.
+
 @end table
 
@@ -362,4 +399,22 @@
 @c man end
 
+@c man begin ENVIRONMENT
+Environment variables that affect how tcc operates.
+
+@table @option
+
+@item CPATH
+@item C_INCLUDE_PATH
+A colon-separated list of directories searched for include files,
+directories given with @option{-I} are searched first.
+
+@item LIBRARY_PATH
+A colon-separated list of directories searched for libraries for the
+@option{-l} option, directories given with @option{-L} are searched first.
+
+@end table
+
+@c man end
+
 @ignore
 
@@ -368,4 +423,5 @@
 
 @c man begin SEEALSO
+cpp(1),
 gcc(1)
 @c man end
@@ -389,10 +445,11 @@
 
 TCC implements many features of the new C standard: ISO C99. Currently
-missing items are: complex and imaginary numbers and variable length
-arrays.
+missing items are: complex and imaginary numbers.
 
 Currently implemented ISOC99 features:
 
 @itemize
+
+@item variable length arrays.
 
 @item 64 bit @code{long long} types are fully supported.
@@ -597,6 +654,5 @@
 @itemize
 
-@item @code{__TINYC__} is a predefined macro to @code{1} to
-indicate that you use TCC.
+@item @code{__TINYC__} is a predefined macro to indicate that you use TCC.
 
 @item @code{#!} at the start of a line is ignored to allow scripting.
@@ -614,5 +670,5 @@
 Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
 assembler supports a gas-like syntax (GNU assembler). You can
-desactivate assembler support if you want a smaller TinyCC executable
+deactivate assembler support if you want a smaller TinyCC executable
 (the C compiler does not rely on the assembler).
 
@@ -703,5 +759,5 @@
 @cindex ascii directive
 
-All directives are preceeded by a '.'. The following directives are
+All directives are preceded by a '.'. The following directives are
 supported:
 
@@ -922,5 +978,5 @@
 @section Types
 
-The types are stored in a single 'int' variable. It was choosen in the
+The types are stored in a single 'int' variable. It was chosen in the
 first stages of development when tcc was much simpler. Now, it may not
 be the best solution.
@@ -949,5 +1005,5 @@
 #define VT_CONSTANT   0x0800  /* const modifier */
 #define VT_VOLATILE   0x1000  /* volatile modifier */
-#define VT_SIGNED     0x2000  /* signed type */
+#define VT_DEFSIGN    0x2000  /* signed type */
 
 #define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
@@ -991,5 +1047,5 @@
 
 @code{Sym.v} contains the symbol name (remember
-an idenfier is also a token, so a string is never necessary to store
+an identifier is also a token, so a string is never necessary to store
 it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
 the register in which the corresponding variable is stored. @code{Sym.c} is
@@ -1034,5 +1090,5 @@
 @section Sections
 
-The generated code and datas are written in sections. The structure
+The generated code and data are written in sections. The structure
 @code{Section} contains all the necessary information for a given
 section. @code{new_section()} creates a new section. ELF file semantics
@@ -1059,5 +1115,5 @@
 @item stab_section
 @itemx stabstr_section
-are used when debugging is actived to store debug information
+are used when debugging is active to store debug information
 
 @item symtab_section
@@ -1159,6 +1215,8 @@
 
 @item VT_LLOCAL
-is a saved lvalue on the stack. @code{VT_LLOCAL} should be eliminated
-ASAP because its semantics are rather complicated.
+is a saved lvalue on the stack. @code{VT_LVAL} must also be set with
+@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
 
 @item VT_MUSTCAST
@@ -1219,5 +1277,5 @@
 @item gen_opi(op)
 must generate the binary integer operation @var{op} on the two top
-entries of the stack which are guaranted to contain integer types.
+entries of the stack which are guaranteed to contain integer types.
 
 The result value should be put on the stack.
@@ -1225,5 +1283,5 @@
 @item gen_opf(op)
 same as @code{gen_opi()} for floating point operations. The two top
-entries of the stack are guaranted to contain floating point values of
+entries of the stack are guaranteed to contain floating point values of
 same types.
 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.1
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcc.1	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.1	(revision 331)
@@ -0,0 +1,458 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "TCC 1"
+.TH TCC 1 "2018-01-07" "0.9.27" "Tiny C Compiler"
+.SH "NAME"
+tcc \- Tiny C Compiler
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+usage: tcc [options] [\fIinfile1\fR \fIinfile2\fR...] [\fB\-run\fR \fIinfile\fR \fIargs\fR...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\s-1TCC\s0 options are a very much like gcc options. The main difference is that \s-1TCC\s0
+can also execute directly the resulting program and give it runtime
+arguments.
+.PP
+Here are some examples to understand the logic:
+.ie n .IP """\f(CBtcc \-run a.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-run a.c\f(CW\fR" 4
+.IX Item "tcc -run a.c"
+Compile \fIa.c\fR and execute it directly
+.ie n .IP """\f(CBtcc \-run a.c arg1\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-run a.c arg1\f(CW\fR" 4
+.IX Item "tcc -run a.c arg1"
+Compile a.c and execute it directly. arg1 is given as first argument to
+the \f(CW\*(C`main()\*(C'\fR of a.c.
+.ie n .IP """\f(CBtcc a.c \-run b.c arg1\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc a.c \-run b.c arg1\f(CW\fR" 4
+.IX Item "tcc a.c -run b.c arg1"
+Compile \fIa.c\fR and \fIb.c\fR, link them together and execute them. arg1 is given
+as first argument to the \f(CW\*(C`main()\*(C'\fR of the resulting program. 
+.ie n .IP """\f(CBtcc \-o myprog a.c b.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-o myprog a.c b.c\f(CW\fR" 4
+.IX Item "tcc -o myprog a.c b.c"
+Compile \fIa.c\fR and \fIb.c\fR, link them and generate the executable \fImyprog\fR.
+.ie n .IP """\f(CBtcc \-o myprog a.o b.o\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-o myprog a.o b.o\f(CW\fR" 4
+.IX Item "tcc -o myprog a.o b.o"
+link \fIa.o\fR and \fIb.o\fR together and generate the executable \fImyprog\fR.
+.ie n .IP """\f(CBtcc \-c a.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c a.c\f(CW\fR" 4
+.IX Item "tcc -c a.c"
+Compile \fIa.c\fR and generate object file \fIa.o\fR.
+.ie n .IP """\f(CBtcc \-c asmfile.S\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c asmfile.S\f(CW\fR" 4
+.IX Item "tcc -c asmfile.S"
+Preprocess with C preprocess and assemble \fIasmfile.S\fR and generate
+object file \fIasmfile.o\fR.
+.ie n .IP """\f(CBtcc \-c asmfile.s\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c asmfile.s\f(CW\fR" 4
+.IX Item "tcc -c asmfile.s"
+Assemble (but not preprocess) \fIasmfile.s\fR and generate object file
+\&\fIasmfile.o\fR.
+.ie n .IP """\f(CBtcc \-r \-o ab.o a.c b.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-r \-o ab.o a.c b.c\f(CW\fR" 4
+.IX Item "tcc -r -o ab.o a.c b.c"
+Compile \fIa.c\fR and \fIb.c\fR, link them together and generate the object file \fIab.o\fR.
+.PP
+Scripting:
+.PP
+\&\s-1TCC\s0 can be invoked from \fIscripts\fR, just as shell scripts. You just
+need to add \f(CW\*(C`#!/usr/local/bin/tcc \-run\*(C'\fR at the start of your C source:
+.PP
+.Vb 2
+\&        #!/usr/local/bin/tcc -run
+\&        #include <stdio.h>
+.Ve
+.PP
+.Vb 5
+\&        int main() 
+\&        {
+\&            printf("Hello World\en");
+\&            return 0;
+\&        }
+.Ve
+.PP
+\&\s-1TCC\s0 can read C source code from \fIstandard input\fR when \fB\-\fR is used in 
+place of \fBinfile\fR. Example:
+.PP
+.Vb 1
+\&        echo 'main(){puts("hello");}' | tcc -run -
+.Ve
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-c\fR" 4
+.IX Item "-c"
+Generate an object file.
+.IP "\fB\-o outfile\fR" 4
+.IX Item "-o outfile"
+Put object file, executable, or dll into output file \fIoutfile\fR.
+.IP "\fB\-run source [args...]\fR" 4
+.IX Item "-run source [args...]"
+Compile file \fIsource\fR and run it with the command line arguments
+\&\fIargs\fR. In order to be able to give more than one argument to a
+script, several \s-1TCC\s0 options can be given \fIafter\fR the
+\&\fB\-run\fR option, separated by spaces:
+.Sp
+.Vb 1
+\&        tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+.Ve
+.Sp
+In a script, it gives the following header:
+.Sp
+.Vb 1
+\&        #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+.Ve
+.IP "\fB\-v\fR" 4
+.IX Item "-v"
+Display \s-1TCC\s0 version.
+.IP "\fB\-vv\fR" 4
+.IX Item "-vv"
+Show included files.  As sole argument, print search dirs.  \-vvv shows tries too.
+.IP "\fB\-bench\fR" 4
+.IX Item "-bench"
+Display compilation statistics.
+.PP
+Preprocessor options:
+.IP "\fB\-Idir\fR" 4
+.IX Item "-Idir"
+Specify an additional include path. Include paths are searched in the
+order they are specified.
+.Sp
+System include paths are always searched after. The default system
+include paths are: \fI/usr/local/include\fR, \fI/usr/include\fR
+and \fIPREFIX/lib/tcc/include\fR. (\fI\s-1PREFIX\s0\fR is usually
+\&\fI/usr\fR or \fI/usr/local\fR).
+.IP "\fB\-Dsym[=val]\fR" 4
+.IX Item "-Dsym[=val]"
+Define preprocessor symbol \fBsym\fR to
+val. If val is not present, its value is \fB1\fR. Function-like macros can
+also be defined: \fB\-DF(a)=a+1\fR
+.IP "\fB\-Usym\fR" 4
+.IX Item "-Usym"
+Undefine preprocessor symbol \fBsym\fR.
+.IP "\fB\-E\fR" 4
+.IX Item "-E"
+Preprocess only, to stdout or file (with \-o).
+.PP
+Compilation flags:
+.PP
+Note: each of the following options has a negative form beginning with
+\&\fB\-fno\-\fR.
+.IP "\fB\-funsigned\-char\fR" 4
+.IX Item "-funsigned-char"
+Let the \f(CW\*(C`char\*(C'\fR type be unsigned.
+.IP "\fB\-fsigned\-char\fR" 4
+.IX Item "-fsigned-char"
+Let the \f(CW\*(C`char\*(C'\fR type be signed.
+.IP "\fB\-fno\-common\fR" 4
+.IX Item "-fno-common"
+Do not generate common symbols for uninitialized data.
+.IP "\fB\-fleading\-underscore\fR" 4
+.IX Item "-fleading-underscore"
+Add a leading underscore at the beginning of each C symbol.
+.IP "\fB\-fms\-extensions\fR" 4
+.IX Item "-fms-extensions"
+Allow a \s-1MS\s0 C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+.IP "\fB\-fdollars\-in\-identifiers\fR" 4
+.IX Item "-fdollars-in-identifiers"
+Allow dollar signs in identifiers
+.PP
+Warning options:
+.IP "\fB\-w\fR" 4
+.IX Item "-w"
+Disable all warnings.
+.PP
+Note: each of the following warning options has a negative form beginning with
+\&\fB\-Wno\-\fR.
+.IP "\fB\-Wimplicit\-function\-declaration\fR" 4
+.IX Item "-Wimplicit-function-declaration"
+Warn about implicit function declaration.
+.IP "\fB\-Wunsupported\fR" 4
+.IX Item "-Wunsupported"
+Warn about unsupported \s-1GCC\s0 features that are ignored by \s-1TCC\s0.
+.IP "\fB\-Wwrite\-strings\fR" 4
+.IX Item "-Wwrite-strings"
+Make string constants be of type \f(CW\*(C`const char *\*(C'\fR instead of \f(CW\*(C`char
+*\*(C'\fR.
+.IP "\fB\-Werror\fR" 4
+.IX Item "-Werror"
+Abort compilation if warnings are issued.
+.IP "\fB\-Wall\fR" 4
+.IX Item "-Wall"
+Activate all warnings, except \fB\-Werror\fR, \fB\-Wunusupported\fR and
+\&\fB\-Wwrite\-strings\fR.
+.PP
+Linker options:
+.IP "\fB\-Ldir\fR" 4
+.IX Item "-Ldir"
+Specify an additional static library path for the \fB\-l\fR option. The
+default library paths are \fI/usr/local/lib\fR, \fI/usr/lib\fR and \fI/lib\fR.
+.IP "\fB\-lxxx\fR" 4
+.IX Item "-lxxx"
+Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+\&\fB\-L\fR option and \fB\s-1LIBRARY_PATH\s0\fR variable.
+.IP "\fB\-Bdir\fR" 4
+.IX Item "-Bdir"
+Set the path where the tcc internal libraries (and include files) can be
+found (default is \fIPREFIX/lib/tcc\fR).
+.IP "\fB\-shared\fR" 4
+.IX Item "-shared"
+Generate a shared library instead of an executable.
+.IP "\fB\-soname name\fR" 4
+.IX Item "-soname name"
+set name for shared library to be used at runtime
+.IP "\fB\-static\fR" 4
+.IX Item "-static"
+Generate a statically linked executable (default is a shared linked
+executable).
+.IP "\fB\-rdynamic\fR" 4
+.IX Item "-rdynamic"
+Export global symbols to the dynamic linker. It is useful when a library
+opened with \f(CW\*(C`dlopen()\*(C'\fR needs to access executable symbols.
+.IP "\fB\-r\fR" 4
+.IX Item "-r"
+Generate an object file combining all input files.
+.IP "\fB\-Wl,\-rpath=path\fR" 4
+.IX Item "-Wl,-rpath=path"
+Put custom search path for dynamic libraries into executable.
+.IP "\fB\-Wl,\-\-enable\-new\-dtags\fR" 4
+.IX Item "-Wl,--enable-new-dtags"
+When putting a custom search path for dynamic libraries into the executable,
+create the new \s-1ELF\s0 dynamic tag \s-1DT_RUNPATH\s0 instead of the old legacy \s-1DT_RPATH\s0.
+.IP "\fB\-Wl,\-\-oformat=fmt\fR" 4
+.IX Item "-Wl,--oformat=fmt"
+Use \fIfmt\fR as output format. The supported output formats are:
+.RS 4
+.ie n .IP """elf32\-i386""" 4
+.el .IP "\f(CWelf32\-i386\fR" 4
+.IX Item "elf32-i386"
+\&\s-1ELF\s0 output format (default)
+.ie n .IP """binary""" 4
+.el .IP "\f(CWbinary\fR" 4
+.IX Item "binary"
+Binary image (only for executable output)
+.ie n .IP """coff""" 4
+.el .IP "\f(CWcoff\fR" 4
+.IX Item "coff"
+\&\s-1COFF\s0 output format (only for executable output for TMS320C67xx target)
+.RE
+.RS 4
+.RE
+.IP "\fB\-Wl,\-subsystem=console/gui/wince/...\fR" 4
+.IX Item "-Wl,-subsystem=console/gui/wince/..."
+Set type for \s-1PE\s0 (Windows) executables.
+.IP "\fB\-Wl,\-[Ttext=# | section\-alignment=# | file\-alignment=# | image\-base=# | stack=#]\fR" 4
+.IX Item "-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]"
+Modify executable layout.
+.IP "\fB\-Wl,\-Bsymbolic\fR" 4
+.IX Item "-Wl,-Bsymbolic"
+Set \s-1DT_SYMBOLIC\s0 tag.
+.IP "\fB\-Wl,\-(no\-)whole\-archive\fR" 4
+.IX Item "-Wl,-(no-)whole-archive"
+Turn on/off linking of all objects in archives.
+.PP
+Debugger options:
+.IP "\fB\-g\fR" 4
+.IX Item "-g"
+Generate run time debug information so that you get clear run time
+error messages: \f(CW\*(C` test.c:68: in function 'test5()': dereferencing
+invalid pointer\*(C'\fR instead of the laconic \f(CW\*(C`Segmentation
+fault\*(C'\fR.
+.IP "\fB\-b\fR" 4
+.IX Item "-b"
+Generate additional support code to check
+memory allocations and array/pointer bounds. \fB\-g\fR is implied. Note
+that the generated code is slower and bigger in this case.
+.Sp
+Note: \fB\-b\fR is only available on i386 when using libtcc for the moment.
+.IP "\fB\-bt N\fR" 4
+.IX Item "-bt N"
+Display N callers in stack traces. This is useful with \fB\-g\fR or
+\&\fB\-b\fR.
+.PP
+Misc options:
+.IP "\fB\-MD\fR" 4
+.IX Item "-MD"
+Generate makefile fragment with dependencies.
+.IP "\fB\-MF depfile\fR" 4
+.IX Item "-MF depfile"
+Use \fIdepfile\fR as output for \-MD.
+.IP "\fB\-print\-search\-dirs\fR" 4
+.IX Item "-print-search-dirs"
+Print the configured installation directory and a list of library
+and include directories tcc will search.
+.IP "\fB\-dumpversion\fR" 4
+.IX Item "-dumpversion"
+Print version.
+.PP
+Target specific options:
+.IP "\fB\-mms\-bitfields\fR" 4
+.IX Item "-mms-bitfields"
+Use an algorithm for bitfield alignment consistent with \s-1MSVC\s0. Default is
+gcc's algorithm.
+.IP "\fB\-mfloat\-abi (\s-1ARM\s0 only)\fR" 4
+.IX Item "-mfloat-abi (ARM only)"
+Select the float \s-1ABI\s0. Possible values: \f(CW\*(C`softfp\*(C'\fR and \f(CW\*(C`hard\*(C'\fR
+.IP "\fB\-mno\-sse\fR" 4
+.IX Item "-mno-sse"
+Do not use sse registers on x86_64
+.IP "\fB\-m32, \-m64\fR" 4
+.IX Item "-m32, -m64"
+Pass command line to the i386/x86_64 cross compiler.
+.PP
+Note: \s-1GCC\s0 options \fB\-Ox\fR, \fB\-fx\fR and \fB\-mx\fR are
+ignored.
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+Environment variables that affect how tcc operates.
+.IP "\fB\s-1CPATH\s0\fR" 4
+.IX Item "CPATH"
+.PD 0
+.IP "\fBC_INCLUDE_PATH\fR" 4
+.IX Item "C_INCLUDE_PATH"
+.PD
+A colon-separated list of directories searched for include files,
+directories given with \fB\-I\fR are searched first.
+.IP "\fB\s-1LIBRARY_PATH\s0\fR" 4
+.IX Item "LIBRARY_PATH"
+A colon-separated list of directories searched for libraries for the
+\&\fB\-l\fR option, directories given with \fB\-L\fR are searched first.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIcpp\fR\|(1),
+\&\fIgcc\fR\|(1)
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Fabrice Bellard
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcc.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.c	(revision 331)
@@ -19,134 +19,191 @@
  */
 
-#ifdef ONE_SOURCE
-#include "libtcc.c"
+#include "tcc.h"
+#if ONE_SOURCE
+# include "libtcc.c"
+#endif
+#include "tcctools.c"
+
+static const char help[] =
+    "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
+    "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
+    "       tcc [options...] -run infile [arguments...]\n"
+    "General options:\n"
+    "  -c          compile only - generate an object file\n"
+    "  -o outfile  set output filename\n"
+    "  -run        run compiled source\n"
+    "  -fflag      set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
+    "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
+    "  -w          disable all warnings\n"
+    "  -v -vv      show version, show search paths or loaded files\n"
+    "  -h -hh      show this, show more help\n"
+    "  -bench      show compilation statistics\n"
+    "  -           use stdin pipe as infile\n"
+    "  @listfile   read arguments from listfile\n"
+    "Preprocessor options:\n"
+    "  -Idir       add include path 'dir'\n"
+    "  -Dsym[=val] define 'sym' with value 'val'\n"
+    "  -Usym       undefine 'sym'\n"
+    "  -E          preprocess only\n"
+    "Linker options:\n"
+    "  -Ldir       add library path 'dir'\n"
+    "  -llib       link with dynamic or static library 'lib'\n"
+    "  -r          generate (relocatable) object file\n"
+    "  -shared     generate a shared library/dll\n"
+    "  -rdynamic   export all global symbols to dynamic linker\n"
+    "  -soname     set name for shared library to be used at runtime\n"
+    "  -Wl,-opt[=val]  set linker option (see tcc -hh)\n"
+    "Debugger options:\n"
+    "  -g          generate runtime debug info\n"
+#ifdef CONFIG_TCC_BCHECK
+    "  -b          compile with built-in memory and bounds checker (implies -g)\n"
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+    "  -bt N       show N callers in stack traces\n"
+#endif
+    "Misc. options:\n"
+    "  -x[c|a|n]   specify type of the next infile\n"
+    "  -nostdinc   do not use standard system include paths\n"
+    "  -nostdlib   do not link with standard crt and libraries\n"
+    "  -Bdir       set tcc's private include/library dir\n"
+    "  -MD         generate dependency file for make\n"
+    "  -MF file    specify dependency file name\n"
+    "  -m32/64     defer to i386/x86_64 cross compiler\n"
+    "Tools:\n"
+    "  create library  : tcc -ar [rcsv] lib.a files\n"
+#ifdef TCC_TARGET_PE
+    "  create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
+#endif
+    ;
+
+static const char help2[] =
+    "Tiny C Compiler "TCC_VERSION" - More Options\n"
+    "Special options:\n"
+    "  -P -P1                        with -E: no/alternative #line output\n"
+    "  -dD -dM                       with -E: output #define directives\n"
+    "  -pthread                      same as -D_REENTRANT and -lpthread\n"
+    "  -On                           same as -D__OPTIMIZE__ for n > 0\n"
+    "  -Wp,-opt                      same as -opt\n"
+    "  -include file                 include 'file' above each input file\n"
+    "  -isystem dir                  add 'dir' to system include path\n"
+    "  -static                       link to static libraries (not recommended)\n"
+    "  -dumpversion                  print version\n"
+    "  -print-search-dirs            print search paths\n"
+    "  -dt                           with -run/-E: auto-define 'test_...' macros\n"
+    "Ignored options:\n"
+    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
+    "-W... warnings:\n"
+    "  all                           turn on some (*) warnings\n"
+    "  error                         stop after first warning\n"
+    "  unsupported                   warn about ignored options, pragmas, etc.\n"
+    "  write-strings                 strings are const\n"
+    "  implicit-function-declaration warn for missing prototype (*)\n"
+    "-f[no-]... flags:\n"
+    "  unsigned-char                 default char is unsigned\n"
+    "  signed-char                   default char is signed\n"
+    "  common                        use common section instead of bss\n"
+    "  leading-underscore            decorate extern symbols\n"
+    "  ms-extensions                 allow anonymous struct in struct\n"
+    "  dollars-in-identifiers        allow '$' in C symbols\n"
+    "-m... target specific options:\n"
+    "  ms-bitfields                  use MSVC bitfield layout\n"
+#ifdef TCC_TARGET_ARM
+    "  float-abi                     hard/softfp on arm\n"
+#endif
+#ifdef TCC_TARGET_X86_64
+    "  no-sse                        disable floats on x86_64\n"
+#endif
+    "-Wl,... linker options:\n"
+    "  -nostdlib                     do not link with standard crt/libs\n"
+    "  -[no-]whole-archive           load lib(s) fully/only as needed\n"
+    "  -export-all-symbols           same as -rdynamic\n"
+    "  -image-base= -Ttext=          set base address of executable\n"
+    "  -section-alignment=           set section alignment in executable\n"
+#ifdef TCC_TARGET_PE
+    "  -file-alignment=              set PE file alignment\n"
+    "  -stack=                       set PE stack reserve\n"
+    "  -large-address-aware          set related PE option\n"
+    "  -subsystem=[console/windows]  set PE subsystem\n"
+    "  -oformat=[pe-* binary]        set executable output format\n"
+    "Predefined macros:\n"
+    "  tcc -E -dM - < nul\n"
 #else
-#include "tcc.h"
-#endif
-
-static void help(void)
-{
-    printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
-           "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
-           "       tcc [options...] -run infile [arguments...]\n"
-           "General options:\n"
-           "  -c          compile only - generate an object file\n"
-           "  -o outfile  set output filename\n"
-           "  -run        run compiled source\n"
-           "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
-           "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
-           "  -w          disable all warnings\n"
-           "  -v          show version\n"
-           "  -vv         show included files (as sole argument: show search paths)\n"
-           "  -dumpversion\n"
-           "  -bench      show compilation statistics\n"
-           "Preprocessor options:\n"
-           "  -E          preprocess only\n"
-           "  -Idir       add include path 'dir'\n"
-           "  -Dsym[=val] define 'sym' with value 'val'\n"
-           "  -Usym       undefine 'sym'\n"
-           "Linker options:\n"
-           "  -Ldir       add library path 'dir'\n"
-           "  -llib       link with dynamic or static library 'lib'\n"
-           "  -pthread    link with -lpthread and -D_REENTRANT (POSIX Linux)\n"
-           "  -r          generate (relocatable) object file\n"
-           "  -rdynamic   export all global symbols to dynamic linker\n"
-           "  -shared     generate a shared library\n"
-           "  -soname     set name for shared library to be used at runtime\n"
-           "  -static     static linking\n"
-           "  -Wl,-opt[=val]  set linker option (see manual)\n"
-           "Debugger options:\n"
-           "  -g          generate runtime debug info\n"
-#ifdef CONFIG_TCC_BCHECK
-           "  -b          compile with built-in memory and bounds checker (implies -g)\n"
-#endif
-#ifdef CONFIG_TCC_BACKTRACE
-           "  -bt N       show N callers in stack traces\n"
-#endif
-           "Misc options:\n"
-           "  -nostdinc   do not use standard system include paths\n"
-           "  -nostdlib   do not link with standard crt and libraries\n"
-           "  -Bdir       use 'dir' as tcc internal library and include path\n"
-           "  -MD         generate target dependencies for make\n"
-           "  -MF depfile put generated dependencies here\n"
-           );
-}
-
-/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-#ifdef _WIN32
-#include <process.h>
-static int execvp_win32(const char *prog, char **argv)
-{
-    int ret = spawnvp(P_NOWAIT, prog, (char const*const*)argv);
-    if (-1 == ret)
-        return ret;
-    cwait(&ret, ret, WAIT_CHILD);
-    exit(ret);
-}
-#define execvp execvp_win32
-#endif
-static void exec_other_tcc(TCCState *s, char **argv, const char *optarg)
-{
-    char child_path[4096], *child_name; const char *target;
-    switch (atoi(optarg)) {
+    "  -rpath=                       set dynamic library search path\n"
+    "  -enable-new-dtags             set DT_RUNPATH instead of DT_RPATH\n"
+    "  -soname=                      set DT_SONAME elf tag\n"
+    "  -Bsymbolic                    set DT_SYMBOLIC elf tag\n"
+    "  -oformat=[elf32/64-* binary]  set executable output format\n"
+    "  -init= -fini= -as-needed -O   (ignored)\n"
+    "Predefined macros:\n"
+    "  tcc -E -dM - < /dev/null\n"
+#endif
+    "See also the manual for more details.\n"
+    ;
+
+static const char version[] =
+    "tcc version "TCC_VERSION" ("
 #ifdef TCC_TARGET_I386
-        case 32: break;
-        case 64: target = "x86_64";
+        "i386"
+#elif defined TCC_TARGET_X86_64
+        "x86_64"
+#elif defined TCC_TARGET_C67
+        "C67"
+#elif defined TCC_TARGET_ARM
+        "ARM"
+#elif defined TCC_TARGET_ARM64
+        "AArch64"
+#endif
+#ifdef TCC_ARM_HARDFLOAT
+        " Hard Float"
+#endif
+#ifdef TCC_TARGET_PE
+        " Windows"
+#elif defined(TCC_TARGET_MACHO)
+        " Darwin"
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+        " FreeBSD"
 #else
-        case 64: break;
-        case 32: target = "i386";
-#endif
-            pstrcpy(child_path, sizeof child_path - 40, argv[0]);
-            child_name = tcc_basename(child_path);
-            strcpy(child_name, target);
-#ifdef TCC_TARGET_PE
-            strcat(child_name, "-win32");
-#endif
-            strcat(child_name, "-tcc");
-            if (strcmp(argv[0], child_path)) {
-                if (s->verbose > 0)
-                    printf("tcc: using '%s'\n", child_name), fflush(stdout);
-                execvp(argv[0] = child_path, argv);
-            }
-            tcc_error("'%s' not found", child_name);
-        case 0: /* ignore -march etc. */
-            break;
-        default:
-            tcc_warning("unsupported option \"-m%s\"", optarg);
-    }
-}
-#else
-#define exec_other_tcc(s, argv, optarg)
-#endif
-
-static void gen_makedeps(TCCState *s, const char *target, const char *filename)
-{
-    FILE *depout;
-    char buf[1024], *ext;
+        " Linux"
+#endif
+    ")\n"
+    ;
+
+static void print_dirs(const char *msg, char **paths, int nb_paths)
+{
     int i;
-
-    if (!filename) {
-        /* compute filename automatically
-         * dir/file.o -> dir/file.d             */
-        pstrcpy(buf, sizeof(buf), target);
-        ext = tcc_fileextension(buf);
-        pstrcpy(ext, sizeof(buf) - (ext-buf), ".d");
-        filename = buf;
-    }
-
-    if (s->verbose)
-        printf("<- %s\n", filename);
-
-    /* XXX return err codes instead of error() ? */
-    depout = fopen(filename, "w");
-    if (!depout)
-        tcc_error("could not open '%s'", filename);
-
-    fprintf(depout, "%s : \\\n", target);
-    for (i=0; i<s->nb_target_deps; ++i)
-        fprintf(depout, " %s \\\n", s->target_deps[i]);
-    fprintf(depout, "\n");
-    fclose(depout);
+    printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
+    for(i = 0; i < nb_paths; i++)
+        printf("  %s\n", paths[i]);
+}
+
+static void print_search_dirs(TCCState *s)
+{
+    printf("install: %s\n", s->tcc_lib_path);
+    /* print_dirs("programs", NULL, 0); */
+    print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
+    print_dirs("libraries", s->library_paths, s->nb_library_paths);
+    printf("libtcc1:\n  %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
+#ifndef TCC_TARGET_PE
+    print_dirs("crt", s->crt_paths, s->nb_crt_paths);
+    printf("elfinterp:\n  %s\n",  DEFAULT_ELFINTERP(s));
+#endif
+}
+
+static void set_environment(TCCState *s)
+{
+    char * path;
+
+    path = getenv("C_INCLUDE_PATH");
+    if(path != NULL) {
+        tcc_add_sysinclude_path(s, path);
+    }
+    path = getenv("CPATH");
+    if(path != NULL) {
+        tcc_add_include_path(s, path);
+    }
+    path = getenv("LIBRARY_PATH");
+    if(path != NULL) {
+        tcc_add_library_path(s, path);
+    }
 }
 
@@ -159,5 +216,5 @@
     if (first_file && strcmp(first_file, "-"))
         name = tcc_basename(first_file);
-    pstrcpy(buf, sizeof(buf), name);
+    snprintf(buf, sizeof(buf), "%s", name);
     ext = tcc_fileextension(buf);
 #ifdef TCC_TARGET_PE
@@ -169,184 +226,146 @@
     else
 #endif
-    if (( (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) ||
-          (s->output_type == TCC_OUTPUT_PREPROCESS) )
-        && *ext)
+    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
         strcpy(ext, ".o");
     else
         strcpy(buf, "a.out");
-
     return tcc_strdup(buf);
 }
 
-static void print_paths(const char *msg, char **paths, int nb_paths)
-{
-    int i;
-    printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
-    for(i = 0; i < nb_paths; i++)
-        printf("  %s\n", paths[i]);
-}
-
-static void display_info(TCCState *s, int what)
-{
-    switch (what) {
-    case 0:
-        printf("tcc version %s ("
-#ifdef TCC_TARGET_I386
-        "i386"
-# ifdef TCC_TARGET_PE
-        " Win32"
-# endif
-#elif defined TCC_TARGET_X86_64
-        "x86-64"
-# ifdef TCC_TARGET_PE
-        " Win64"
-# endif
-#elif defined TCC_TARGET_ARM
-        "ARM"
-# ifdef TCC_ARM_HARDFLOAT
-        " Hard Float"
-# endif
-# ifdef TCC_TARGET_PE
-        " WinCE"
-# endif
-#endif
-#ifndef TCC_TARGET_PE
-# ifdef __linux
-        " Linux"
-# endif
-#endif
-        ")\n", TCC_VERSION);
-        break;
-    case 1:
-        printf("install: %s/\n", s->tcc_lib_path);
-        /* print_paths("programs", NULL, 0); */
-        print_paths("crt", s->crt_paths, s->nb_crt_paths);
-        print_paths("libraries", s->library_paths, s->nb_library_paths);
-        print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths);
-        printf("elfinterp:\n  %s\n",  CONFIG_TCC_ELFINTERP);
-        break;
-    }
-}
-
-static int64_t getclock_us(void)
-{
-#if 0//def _WIN32
-    struct _timeb tb;
-    _ftime(&tb);
-    return (tb.time * 1000LL + tb.millitm) * 1000LL;
+static unsigned getclock_ms(void)
+{
+#ifdef _WIN32
+    return GetTickCount();
 #else
     struct timeval tv;
     gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000LL + tv.tv_usec;
-#endif
-}
-
-int tcc_main(int argc, char **argv)
+    return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
+#endif
+}
+
+int tcc_main(int argc0, char **argv0)
 {
     TCCState *s;
-    int ret, optind, i, bench;
-    int64_t start_time = 0;
-    const char *first_file = NULL;
-
+    int ret, opt, n = 0, t = 0;
+    unsigned start_time = 0;
+    const char *first_file;
+    int argc; char **argv;
+    FILE *ppfp = stdout;
+
+redo:
+    argc = argc0, argv = argv0;
     s = tcc_new();
-    s->output_type = TCC_OUTPUT_EXE;
-
-    optind = tcc_parse_args(s, argc - 1, argv + 1);
-
-    if (optind == 0) {
-        help();
-        return 1;
-    }
-
-    if (s->option_m)
-        exec_other_tcc(s, argv, s->option_m);
-
-    if (s->verbose)
-        display_info(s, 0);
-
-    if (s->print_search_dirs || (s->verbose == 2 && optind == 1)) {
-        tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
-        display_info(s, 1);
-        return 0;
-    }
-
-    if (s->verbose && optind == 1)
-        return 0;
-
-    if (s->nb_files == 0)
-        tcc_error("no input files\n");
-
-    /* check -c consistency : only single file handled. XXX: checks file type */
-    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
-        if (s->nb_libraries != 0)
-            tcc_error("cannot specify libraries with -c");
-        /* accepts only a single input file */
-        if (s->nb_files != 1)
-            tcc_error("cannot specify multiple files with -c");
-    }
-    
-    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
-        if (!s->outfile) {
-            s->ppfp = stdout;
+    opt = tcc_parse_args(s, &argc, &argv, 1);
+
+    if ((n | t) == 0) {
+        if (opt == OPT_HELP)
+            return printf(help), 1;
+        if (opt == OPT_HELP2)
+            return printf(help2), 1;
+        if (opt == OPT_M32 || opt == OPT_M64)
+            tcc_tool_cross(s, argv, opt); /* never returns */
+        if (s->verbose)
+            printf(version);
+        if (opt == OPT_AR)
+            return tcc_tool_ar(s, argc, argv);
+#ifdef TCC_TARGET_PE
+        if (opt == OPT_IMPDEF)
+            return tcc_tool_impdef(s, argc, argv);
+#endif
+        if (opt == OPT_V)
+            return 0;
+        if (opt == OPT_PRINT_DIRS) {
+            /* initialize search dirs */
+            set_environment(s);
+            tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+            print_search_dirs(s);
+            return 0;
+        }
+
+        n = s->nb_files;
+        if (n == 0)
+            tcc_error("no input files\n");
+
+        if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+            if (s->outfile) {
+                ppfp = fopen(s->outfile, "w");
+                if (!ppfp)
+                    tcc_error("could not write '%s'", s->outfile);
+            }
+        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
+            if (s->nb_libraries)
+                tcc_error("cannot specify libraries with -c");
+            if (n > 1 && s->outfile)
+                tcc_error("cannot specify output file with -c many files");
         } else {
-            s->ppfp = fopen(s->outfile, "w");
-            if (!s->ppfp)
-                tcc_error("could not write '%s'", s->outfile);
+            if (s->option_pthread)
+                tcc_set_options(s, "-lpthread");
         }
-    }
-
-    bench = s->do_bench;
-    if (bench)
-        start_time = getclock_us();
-
+
+        if (s->do_bench)
+            start_time = getclock_ms();
+    }
+
+    set_environment(s);
+    if (s->output_type == 0)
+        s->output_type = TCC_OUTPUT_EXE;
     tcc_set_output_type(s, s->output_type);
+    s->ppfp = ppfp;
+
+    if ((s->output_type == TCC_OUTPUT_MEMORY
+      || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
+        s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
 
     /* compile or add each files or library */
-    for(i = ret = 0; i < s->nb_files && ret == 0; i++) {
-        const char *filename;
-
-        filename = s->files[i];
-        if (filename[0] == '-' && filename[1] == 'l') {
-            if (tcc_add_library(s, filename + 2) < 0) {
-                tcc_error_noabort("cannot find '%s'", filename);
+    for (first_file = NULL, ret = 0;;) {
+        struct filespec *f = s->files[s->nb_files - n];
+        s->filetype = f->type;
+        s->alacarte_link = f->alacarte;
+        if (f->type == AFF_TYPE_LIB) {
+            if (tcc_add_library_err(s, f->name) < 0)
                 ret = 1;
-            }
         } else {
             if (1 == s->verbose)
-                printf("-> %s\n", filename);
-            if (tcc_add_file(s, filename) < 0)
+                printf("-> %s\n", f->name);
+            if (!first_file)
+                first_file = f->name;
+            if (tcc_add_file(s, f->name) < 0)
                 ret = 1;
-            if (!first_file)
-                first_file = filename;
         }
-    }
-
-    if (0 == ret) {
-        if (bench)
-            tcc_print_stats(s, getclock_us() - start_time);
-
+        s->filetype = 0;
+        s->alacarte_link = 1;
+        if (--n == 0 || ret
+            || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
+            break;
+    }
+
+    if (s->run_test) {
+        t = 0;
+    } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+        ;
+    } else if (0 == ret) {
         if (s->output_type == TCC_OUTPUT_MEMORY) {
 #ifdef TCC_IS_NATIVE
-            ret = tcc_run(s, argc - 1 - optind, argv + 1 + optind);
-#else
-            tcc_error_noabort("-run is not available in a cross compiler");
-            ret = 1;
-#endif
-        } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
-             if (s->outfile)
-                fclose(s->ppfp);
+            ret = tcc_run(s, argc, argv);
+#endif
         } else {
             if (!s->outfile)
                 s->outfile = default_outputfile(s, first_file);
-            ret = !!tcc_output_file(s, s->outfile);
-            /* dump collected dependencies */
-            if (s->gen_deps && !ret)
+            if (tcc_output_file(s, s->outfile))
+                ret = 1;
+            else if (s->gen_deps)
                 gen_makedeps(s, s->outfile, s->deps_outfile);
         }
     }
 
+    if (s->do_bench && (n | t | ret) == 0)
+        tcc_print_stats(s, getclock_ms() - start_time);
     tcc_delete(s);
-    if (bench)
-        tcc_memstats();
+    if (ret == 0 && n)
+        goto redo; /* compile more files with -c */
+    if (t)
+        goto redo; /* run more tests with -dt -run */
+    if (ppfp && ppfp != stdout)
+        fclose(ppfp);
     return ret;
 }
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcc.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.h	(revision 331)
@@ -1,5 +1,5 @@
 /*
  *  TCC - Tiny C Compiler
- * 
+ *
  *  Copyright (c) 2001-2004 Fabrice Bellard
  *
@@ -25,9 +25,4 @@
 #include "config.h"
 
-#ifdef CONFIG_TCCBOOT
-#include "tccboot.h"
-#define CONFIG_TCC_STATIC
-#else
-
 #include <stdlib.h>
 #include <stdio.h>
@@ -36,9 +31,4 @@
 #include <errno.h>
 #include <math.h>
-#include <signal.h>
-#define SA_RESETHAND  0x80000000
-#define FPE_INTDIV 1
-#define FPE_FLTDIV 3
-typedef struct { int si_signo, si_errno, si_code; } siginfo_t;
 #include <fcntl.h>
 #include <setjmp.h>
@@ -48,28 +38,43 @@
 # include <unistd.h>
 # include <sys/time.h>
-/*# include <sys/ucontext.h>*/
-typedef struct __ucontext ucontext_t;
-/*# include <sys/mman.h>*/
-#define	PROT_READ      1
-#define	PROT_WRITE     2
-#define	PROT_EXEC      4
 # ifndef CONFIG_TCC_STATIC
 #  include <dlfcn.h>
 # endif
-#else
-# include <unistd.h>
-# include <sys/time.h>
-# include <sys/ucontext.h>
-# include <sys/mman.h>
+/* XXX: need to define this to use them in non ISOC99 context */
+extern float strtof (const char *__nptr, char **__endptr);
+extern long double strtold (const char *__nptr, char **__endptr);
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h> /* open, close etc. */
+# include <direct.h> /* getcwd */
+# ifdef __GNUC__
 #  include <stdint.h>
+# endif
 # define inline __inline
-# define inp next_inp
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+# ifndef __GNUC__
+#  define strtold (long double)strtod
+#  define strtof (float)strtod
+#  define strtoll _strtoi64
+#  define strtoull _strtoui64
+# endif
 # ifdef LIBTCC_AS_DLL
 #  define LIBTCCAPI __declspec(dllexport)
 #  define PUB_FUNC LIBTCCAPI
 # endif
-#endif
-
-#endif /* !CONFIG_TCCBOOT */
+# define inp next_inp /* inp is an intrinsic on msvc/mingw */
+# ifdef _MSC_VER
+#  pragma warning (disable : 4244)  // conversion from 'uint64_t' to 'int', possible loss of data
+#  pragma warning (disable : 4267)  // conversion from 'size_t' to 'int', possible loss of data
+#  pragma warning (disable : 4996)  // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
+#  pragma warning (disable : 4018)  // signed/unsigned mismatch
+#  pragma warning (disable : 4146)  // unary minus operator applied to unsigned type, result still unsigned
+#  define ssize_t intptr_t
+# endif
+# undef CONFIG_TCC_STATIC
+#endif
 
 #ifndef O_BINARY
@@ -77,67 +82,70 @@
 #endif
 
-#include "elf.h"
-#ifdef TCC_TARGET_X86_64
-# define ELFCLASSW ELFCLASS64
-# define ElfW(type) Elf##64##_##type
-# define ELFW(type) ELF##64##_##type
-# define ElfW_Rel ElfW(Rela)
-# define SHT_RELX SHT_RELA
-# define REL_SECTION_FMT ".rela%s"
-/* XXX: DLL with PLT would only work with x86-64 for now */
-# define TCC_OUTPUT_DLL_WITH_PLT
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+#ifndef countof
+#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
+#endif
+
+#ifdef _MSC_VER
+# define NORETURN __declspec(noreturn)
+# define ALIGNED(x) __declspec(align(x))
 #else
-# define ELFCLASSW ELFCLASS32
-# define ElfW(type) Elf##32##_##type
-# define ELFW(type) ELF##32##_##type
-# define ElfW_Rel ElfW(Rel)
-# define SHT_RELX SHT_REL
-# define REL_SECTION_FMT ".rel%s"
-#endif
-
-/* target address type */
-#define addr_t ElfW(Addr)
-
-#include "stab.h"
-#include "libtcc.h"
+# define NORETURN __attribute__((noreturn))
+# define ALIGNED(x) __attribute__((aligned(x)))
+#endif
+
+#ifdef _WIN32
+# define IS_DIRSEP(c) (c == '/' || c == '\\')
+# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
+# define PATHCMP stricmp
+# define PATHSEP ";"
+#else
+# define IS_DIRSEP(c) (c == '/')
+# define IS_ABSPATH(p) IS_DIRSEP(p[0])
+# define PATHCMP strcmp
+# define PATHSEP ":"
+#endif
+
+/* -------------------------------------------- */
 
 /* parser debug */
-//#define PARSE_DEBUG
+/* #define PARSE_DEBUG */
 /* preprocessor debug */
-//#define PP_DEBUG
+/* #define PP_DEBUG */
 /* include file debug */
-//#define INC_DEBUG
+/* #define INC_DEBUG */
 /* memory leak debug */
-//#define MEM_DEBUG
+/* #define MEM_DEBUG */
 /* assembler debug */
-//#define ASM_DEBUG
+/* #define ASM_DEBUG */
 
 /* target selection */
-//#define TCC_TARGET_I386   /* i386 code generator */
-//#define TCC_TARGET_ARM    /* ARMv4 code generator */
-//#define TCC_TARGET_C67    /* TMS320C67xx code generator */
-//#define TCC_TARGET_X86_64 /* x86-64 code generator */
-//#define TCC_TARGET_IL   /* IL code generator */
+/* #define TCC_TARGET_I386   *//* i386 code generator */
+/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
+/* #define TCC_TARGET_ARM    *//* ARMv4 code generator */
+/* #define TCC_TARGET_ARM64  *//* ARMv8 code generator */
+/* #define TCC_TARGET_C67    *//* TMS320C67xx code generator */
 
 /* default target is I386 */
 #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
-    !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64) && \
-    !defined(TCC_TARGET_IL) 
-#define TCC_TARGET_I386
-#endif
-
-#if !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
-    !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
-#define CONFIG_TCC_BCHECK /* enable bound checking code */
-#endif
-
-/* define it to include assembler support */
-#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67)
-#define CONFIG_TCC_ASM
-#endif
-
-/* object format selection */
-#if defined(TCC_TARGET_C67)
-#define TCC_TARGET_COFF
+    !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
+    !defined(TCC_TARGET_X86_64)
+# if defined __x86_64__ || defined _AMD64_
+#  define TCC_TARGET_X86_64
+# elif defined __arm__
+#  define TCC_TARGET_ARM
+#  define TCC_ARM_EABI
+#  define TCC_ARM_HARDFLOAT
+# elif defined __aarch64__
+#  define TCC_TARGET_ARM64
+# else
+#  define TCC_TARGET_I386
+# endif
+# ifdef _WIN32
+#  define TCC_TARGET_PE 1
+# endif
 #endif
 
@@ -150,4 +158,6 @@
 # elif defined __arm__ && defined TCC_TARGET_ARM
 #  define TCC_IS_NATIVE
+# elif defined __aarch64__ && defined TCC_TARGET_ARM64
+#  define TCC_IS_NATIVE
 # endif
 #endif
@@ -155,4 +165,8 @@
 #if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT
 # define CONFIG_TCC_BACKTRACE
+# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \
+  && !defined TCC_UCLIBC && !defined TCC_MUSL
+# define CONFIG_TCC_BCHECK /* enable bound checking code */
+# endif
 #endif
 
@@ -163,13 +177,20 @@
 #endif
 #ifndef CONFIG_TCCDIR
-# define CONFIG_TCCDIR "."
+# define CONFIG_TCCDIR "/usr/local/lib/tcc"
 #endif
 #ifndef CONFIG_LDDIR
 # define CONFIG_LDDIR "lib"
 #endif
+#ifdef CONFIG_TRIPLET
+# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET
+# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s
+#else
+# define USE_TRIPLET(s) s
+# define ALSO_TRIPLET(s) s
+#endif
 
 /* path to find crt1.o, crti.o and crtn.o */
 #ifndef CONFIG_TCC_CRTPREFIX
-# define CONFIG_TCC_CRTPREFIX CONFIG_SYSROOT "/usr/" CONFIG_LDDIR
+# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
 #endif
 
@@ -179,17 +200,10 @@
 #ifndef CONFIG_TCC_SYSINCLUDEPATHS
 # ifdef TCC_TARGET_PE
-#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include;{B}/include/winapi"
-# elif defined CONFIG_MULTIARCHDIR
-#  define CONFIG_TCC_SYSINCLUDEPATHS \
-        CONFIG_SYSROOT "/usr/local/include" \
-    ":" CONFIG_SYSROOT "/usr/local/include/" CONFIG_MULTIARCHDIR \
-    ":" CONFIG_SYSROOT "/usr/include" \
-    ":" CONFIG_SYSROOT "/usr/include/" CONFIG_MULTIARCHDIR \
-    ":" "{B}/include"
+#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
 # else
 #  define CONFIG_TCC_SYSINCLUDEPATHS \
-        CONFIG_SYSROOT "/usr/local/include" \
-    ":" CONFIG_SYSROOT "/usr/include" \
-    ":" "{B}/include"
+        "{B}/include" \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
 # endif
 #endif
@@ -201,7 +215,7 @@
 # else
 #  define CONFIG_TCC_LIBPATHS \
-        CONFIG_SYSROOT "/usr/" CONFIG_LDDIR \
-    ":" CONFIG_SYSROOT "/" CONFIG_LDDIR \
-    ":" CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR
+        ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
 # endif
 #endif
@@ -212,22 +226,86 @@
 #  define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
 # elif defined __FreeBSD_kernel__
-#  define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
-# elif defined TCC_ARM_HARDFLOAT
-#  define CONFIG_TCC_ELFINTERP "/lib/ld-linux-armhf.so.3"
-# elif defined TCC_ARM_EABI
-#  define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.3"
-# elif defined(TCC_TARGET_X86_64)
-#  define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
-# elif defined(TCC_UCLIBC)
-#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0"
+#  if defined(TCC_TARGET_X86_64)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
+#  endif
+# elif defined __DragonFly__
+#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
+# elif defined __NetBSD__
+#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
+# elif defined __GNU__
+#  define CONFIG_TCC_ELFINTERP "/lib/ld.so"
 # elif defined(TCC_TARGET_PE)
 #  define CONFIG_TCC_ELFINTERP "-"
-# else
-#  define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
+# elif defined(TCC_UCLIBC)
+#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
+# elif defined TCC_TARGET_ARM64
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
+#  endif
+# elif defined(TCC_TARGET_X86_64)
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
+#  endif
+# elif !defined(TCC_ARM_EABI)
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
+#  endif
 # endif
 #endif
 
+/* var elf_interp dans *-gen.c */
+#ifdef CONFIG_TCC_ELFINTERP
+# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
+#else
+# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
+#endif
+
+/* (target specific) libtcc1.a */
+#ifndef TCC_LIBTCC1
+# define TCC_LIBTCC1 "libtcc1.a"
+#endif
+
 /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
-#define TCC_LIBGCC CONFIG_SYSROOT "/" CONFIG_LDDIR "/libgcc_s.so.1"
+#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
+#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
+#endif
+
+/* -------------------------------------------- */
+
+#include "libtcc.h"
+#include "elf.h"
+#include "stab.h"
+
+/* -------------------------------------------- */
+
+#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */
+# define PUB_FUNC
+#endif
+
+#ifndef ONE_SOURCE
+# define ONE_SOURCE 1
+#endif
+
+#if ONE_SOURCE
+#define ST_INLN static inline
+#define ST_FUNC static
+#define ST_DATA static
+#else
+#define ST_INLN
+#define ST_FUNC
+#define ST_DATA extern
+#endif
+
+#ifdef TCC_PROFILE /* profile all functions */
+# define static
+#endif
 
 /* -------------------------------------------- */
@@ -237,19 +315,53 @@
 #ifdef TCC_TARGET_I386
 # include "i386-gen.c"
+# include "i386-link.c"
 #endif
 #ifdef TCC_TARGET_X86_64
 # include "x86_64-gen.c"
+# include "x86_64-link.c"
 #endif
 #ifdef TCC_TARGET_ARM
 # include "arm-gen.c"
+# include "arm-link.c"
+# include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+# include "arm64-gen.c"
+# include "arm64-link.c"
 #endif
 #ifdef TCC_TARGET_C67
+# define TCC_TARGET_COFF
 # include "coff.h"
 # include "c67-gen.c"
-#endif
-#ifdef TCC_TARGET_IL
-#include "il-gen.c"
+# include "c67-link.c"
 #endif
 #undef TARGET_DEFS_ONLY
+
+/* -------------------------------------------- */
+
+#if PTR_SIZE == 8
+# define ELFCLASSW ELFCLASS64
+# define ElfW(type) Elf##64##_##type
+# define ELFW(type) ELF##64##_##type
+# define ElfW_Rel ElfW(Rela)
+# define SHT_RELX SHT_RELA
+# define REL_SECTION_FMT ".rela%s"
+#else
+# define ELFCLASSW ELFCLASS32
+# define ElfW(type) Elf##32##_##type
+# define ELFW(type) ELF##32##_##type
+# define ElfW_Rel ElfW(Rel)
+# define SHT_RELX SHT_REL
+# define REL_SECTION_FMT ".rel%s"
+#endif
+/* target address type */
+#define addr_t ElfW(Addr)
+#define ElfSym ElfW(Sym)
+
+#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
+# define LONG_SIZE 8
+#else
+# define LONG_SIZE 4
+#endif
 
 /* -------------------------------------------- */
@@ -259,7 +371,8 @@
 #define VSTACK_SIZE         256
 #define STRING_MAX_SIZE     1024
+#define TOKSTR_MAX_SIZE     256
 #define PACK_STACK_SIZE     8
 
-#define TOK_HASH_SIZE       8192 /* must be a power of two */
+#define TOK_HASH_SIZE       16384 /* must be a power of two */
 #define TOK_ALLOC_INCR      512  /* must be a power of two */
 #define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
@@ -287,5 +400,4 @@
     void *data; /* either 'char *' or 'nwchar_t *' */
     int size_allocated;
-    void *data_allocated; /* if non NULL, data has been malloced */
 } CString;
 
@@ -301,11 +413,9 @@
     double d;
     float f;
-    int i;
-    unsigned int ui;
-    unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
-    long long ll;
-    unsigned long long ull;
-    struct CString *cstr;
-    void *ptr;
+    uint64_t i;
+    struct {
+        int size;
+        const void *data;
+    } str;
     int tab[LDOUBLE_SIZE/4];
 } CValue;
@@ -318,20 +428,60 @@
                               type. If not used, set to VT_CONST */
     CValue c;              /* constant, if VT_CONST */
-    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
+    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST), or if
+    			      result of unary() for an identifier. */
 } SValue;
+
+/* symbol attributes */
+struct SymAttr {
+    unsigned short
+    aligned     : 5, /* alignment as log2+1 (0 == unspecified) */
+    packed      : 1,
+    weak        : 1,
+    visibility  : 2,
+    dllexport   : 1,
+    dllimport   : 1,
+    unused      : 5;
+};
+
+/* function attributes or temporary attributes for parsing */
+struct FuncAttr {
+    unsigned
+    func_call   : 3, /* calling convention (0..5), see below */
+    func_type   : 2, /* FUNC_OLD/NEW/ELLIPSIS */
+    func_args   : 8; /* PE __stdcall args */
+};
+
+/* GNUC attribute definition */
+typedef struct AttributeDef {
+    struct SymAttr a;
+    struct FuncAttr f;
+    struct Section *section;
+    int alias_target; /* token */
+    int asm_label; /* associated asm label */
+    char attr_mode; /* __attribute__((__mode__(...))) */
+} AttributeDef;
 
 /* symbol management */
 typedef struct Sym {
-    int v;    /* symbol token */
-    char *asm_label;    /* associated asm label */
-    long r;    /* associated register */
+    int v; /* symbol token */
+    unsigned short r; /* associated register or VT_CONST/VT_LOCAL and LVAL type */
+    struct SymAttr a; /* symbol attributes */
     union {
-        long c;    /* associated number */
-        int *d;   /* define token stream */
+        struct {
+            int c; /* associated number or Elf symbol index */
+            union {
+                int sym_scope; /* scope level for locals */
+                int jnext; /* next jump label */
+                struct FuncAttr f; /* function attributes */
+                int auxtype; /* bitfield access type */
+            };
+        };
+        long long enum_val; /* enum constant if IS_ENUM_VAL */
+        int *d; /* define token stream */
     };
-    CType type;    /* associated type */
+    CType type; /* associated type */
     union {
-        struct Sym *next; /* next related symbol */
-        long jnext; /* next jump label */
+        struct Sym *next; /* next related symbol (for fields and anoms) */
+        int asm_label; /* associated asm label */
     };
     struct Sym *prev; /* prev symbol in stack */
@@ -340,12 +490,4 @@
 
 /* section definition */
-/* XXX: use directly ELF structure for parameters ? */
-/* special flag to indicate that the section should not be linked to
-   the other ones */
-#define SHF_PRIVATE 0x80000000
-
-/* special flag, too */
-#define SECTION_ABS ((void *)1)
-
 typedef struct Section {
     unsigned long data_offset; /* current data offset */
@@ -365,6 +507,6 @@
     struct Section *link;    /* link to another section */
     struct Section *reloc;   /* corresponding section for relocation, if any */
-    struct Section *hash;     /* hash table for symbols */
-    struct Section *next;
+    struct Section *hash;    /* hash table for symbols */
+    struct Section *prev;    /* previous section on section stack */
     char name[1];           /* section name */
 } Section;
@@ -376,30 +518,4 @@
 } DLLReference;
 
-/* GNUC attribute definition */
-typedef struct AttributeDef {
-    unsigned
-      func_call     : 3, /* calling convention (0..5), see below */
-      aligned       : 5, /* alignement (0..16) */
-      packed        : 1,
-      func_export   : 1,
-      func_import   : 1,
-      func_args     : 5,
-      mode          : 4,
-      weak          : 1,
-      fill          : 11;
-    struct Section *section;
-    int alias_target;    /* token */
-} AttributeDef;
-
-/* gr: wrappers for casting sym->r for other purposes */
-#define FUNC_CALL(r) (((AttributeDef*)&(r))->func_call)
-#define FUNC_EXPORT(r) (((AttributeDef*)&(r))->func_export)
-#define FUNC_IMPORT(r) (((AttributeDef*)&(r))->func_import)
-#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
-#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
-#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
-#define ATTR_MODE(r)  (((AttributeDef*)&(r))->mode)
-#define INT_ATTR(ad) (*(int*)(ad))
-
 /* -------------------------------------------------- */
 
@@ -408,10 +524,10 @@
 #define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
 
-/* stored in 'Sym.c' field */
+/* stored in 'Sym->f.func_type' field */
 #define FUNC_NEW       1 /* ansi function prototype */
 #define FUNC_OLD       2 /* old function prototype */
 #define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
 
-/* stored in 'Sym.r' field */
+/* stored in 'Sym->f.func_call' field */
 #define FUNC_CDECL     0 /* standard c call */
 #define FUNC_STDCALL   1 /* pascal c call */
@@ -442,22 +558,17 @@
     struct BufferedFile *prev;
     int line_num;    /* current line number - here to simplify code */
+    int line_ref;    /* tcc -E: last printed line */
     int ifndef_macro;  /* #ifndef macro / #endif search */
     int ifndef_macro_saved; /* saved ifndef_macro */
     int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
+    int include_next_index; /* next search path */
     char filename[1024];    /* filename */
-    unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
+    char *true_filename; /* filename not modified by # line directive */
+    unsigned char unget[4];
+    unsigned char buffer[1]; /* extra size for CH_EOB char */
 } BufferedFile;
 
 #define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
 #define CH_EOF   (-1)   /* end of file */
-
-/* parsing state (used to save parser state to reparse part of the
-   source several times) */
-typedef struct ParseState {
-    const int *macro_ptr;
-    int line_num;
-    int tok;
-    CValue tokc;
-} ParseState;
 
 /* used to record tokens */
@@ -465,11 +576,17 @@
     int *str;
     int len;
+    int lastlen;
     int allocated_len;
     int last_line_num;
+    int save_line_num;
+    /* used to chain token-strings with begin/end_macro() */
+    struct TokenString *prev;
+    const int *prev_ptr;
+    char alloc;
 } TokenString;
 
 /* inline functions */
 typedef struct InlineFunc {
-    int *token_str;
+    TokenString *func_str;
     Sym *sym;
     char filename[1];
@@ -480,19 +597,21 @@
 typedef struct CachedInclude {
     int ifndef_macro;
+    int once;
     int hash_next; /* -1 if none */
     char filename[1]; /* path specified in #include */
 } CachedInclude;
 
-#define CACHED_INCLUDES_HASH_SIZE 512
+#define CACHED_INCLUDES_HASH_SIZE 32
 
 #ifdef CONFIG_TCC_ASM
 typedef struct ExprValue {
-    uint32_t v;
+    uint64_t v;
     Sym *sym;
+    int pcrel;
 } ExprValue;
 
 #define MAX_ASM_OPERANDS 30
 typedef struct ASMOperand {
-    int id; /* GCC 3 optionnal identifier (0 if number only supported */
+    int id; /* GCC 3 optional identifier (0 if number only supported */
     char *constraint;
     char asm_str[16]; /* computed asm string for operand */
@@ -508,6 +627,10 @@
 #endif
 
+/* extra symbol attributes (not in symbol table) */
 struct sym_attr {
-    unsigned long got_offset;
+    unsigned got_offset;
+    unsigned plt_offset;
+    int plt_sym;
+    int dyn_index;
 #ifdef TCC_TARGET_ARM
     unsigned char plt_thumb_stub:1;
@@ -529,4 +652,5 @@
     char *soname; /* as specified on the command line (-soname) */
     char *rpath; /* as specified on the command line (-Wl,-rpath=) */
+    int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */
 
     /* output type, see TCC_OUTPUT_XXX */
@@ -538,5 +662,8 @@
     int char_is_unsigned;
     int leading_underscore;
-    
+    int ms_extensions;	/* allow nested named struct w/o identifier behave like unnamed */
+    int dollars_in_identifiers;	/* allows '$' char in identifiers */
+    int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
+
     /* warning switches */
     int warn_write_strings;
@@ -545,4 +672,5 @@
     int warn_none;
     int warn_implicit_function_declaration;
+    int warn_gcc_compat;
 
     /* compile with debug symbol (and use them if error during execution) */
@@ -552,15 +680,22 @@
     int do_bounds_check;
 #endif
+#ifdef TCC_TARGET_ARM
+    enum float_abi float_abi; /* float ABI of the generated code*/
+#endif
+    int run_test; /* nth test to run with -dt -run */
 
     addr_t text_addr; /* address of text section */
     int has_text_addr;
 
-    unsigned long section_align; /* section alignment */
+    unsigned section_align; /* section alignment */
 
     char *init_symbol; /* symbols to call at load-time (not used currently) */
     char *fini_symbol; /* symbols to call at unload-time (not used currently) */
-    
+
 #ifdef TCC_TARGET_I386
     int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
+#endif
+#ifdef TCC_TARGET_X86_64
+    int nosse; /* For -mno-sse support. */
 #endif
 
@@ -583,4 +718,8 @@
     char **crt_paths;
     int nb_crt_paths;
+
+    /* -include files */
+    char **cmd_include_files;
+    int nb_cmd_include_files;
 
     /* error handling */
@@ -593,4 +732,11 @@
     /* output file for preprocessing (-E) */
     FILE *ppfp;
+    enum {
+	LINE_MACRO_OUTPUT_FORMAT_GCC,
+	LINE_MACRO_OUTPUT_FORMAT_NONE,
+	LINE_MACRO_OUTPUT_FORMAT_STD,
+    LINE_MACRO_OUTPUT_FORMAT_P10 = 11
+    } Pflag; /* -P switch */
+    char dflag; /* -dX value */
 
     /* for -MD/-MF: collected dependencies for this compilation */
@@ -613,4 +759,6 @@
     int pack_stack[PACK_STACK_SIZE];
     int *pack_stack_ptr;
+    char **pragma_libs;
+    int nb_pragma_libs;
 
     /* inline functions are stored as token lists and compiled last
@@ -629,8 +777,4 @@
     Section *got;
     Section *plt;
-    struct sym_attr *sym_attrs;
-    int nb_sym_attrs;
-    /* give the correspondance from symtab indexes to dynsym indexes */
-    int *symtab_to_dynsym;
 
     /* temporary dynamic symbol sections (for dll loading) */
@@ -638,14 +782,17 @@
     /* exported dynamic symbol section */
     Section *dynsym;
-    /* copy of the gobal symtab_section variable */
+    /* copy of the global symtab_section variable */
     Section *symtab;
-    /* tiny assembler state */
-    Sym *asm_labels;
+    /* extra attributes (eg. GOT/PLT value) for symtab symbols */
+    struct sym_attr *sym_attrs;
+    int nb_sym_attrs;
 
 #ifdef TCC_TARGET_PE
     /* PE info */
     int pe_subsystem;
+    unsigned pe_characteristics;
     unsigned pe_file_align;
     unsigned pe_stack_size;
+    addr_t pe_imagebase;
 # ifdef TCC_TARGET_X86_64
     Section *uw_pdata;
@@ -656,29 +803,28 @@
 
 #ifdef TCC_IS_NATIVE
-    /* for tcc_relocate */
-    void *runtime_mem;
-# ifdef HAVE_SELINUX
-    void *write_mem;
-    unsigned long mem_size;
-# endif
-# if !defined TCC_TARGET_PE && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM)
-    /* write PLT and GOT here */
-    char *runtime_plt_and_got;
-    unsigned runtime_plt_and_got_offset;
-#  define TCC_HAS_RUNTIME_PLTGOT
-# endif
+    const char *runtime_main;
+    void **runtime_mem;
+    int nb_runtime_mem;
 #endif
 
     /* used by main and tcc_parse_args only */
-    char **files; /* files seen on command line */
+    struct filespec **files; /* files seen on command line */
     int nb_files; /* number thereof */
     int nb_libraries; /* number of libs thereof */
+    int filetype;
     char *outfile; /* output filename */
-    char *option_m; /* only -m32/-m64 handled */
-    int print_search_dirs; /* option */
     int option_r; /* option -r */
     int do_bench; /* option -bench */
     int gen_deps; /* option -MD  */
     char *deps_outfile; /* option -MF */
+    int option_pthread; /* -pthread option */
+    int argc;
+    char **argv;
+};
+
+struct filespec {
+    char type;
+    char alacarte;
+    char name[1];
 };
 
@@ -691,5 +837,4 @@
 #define VT_JMP       0x0034  /* value is the consequence of jmp true (even) */
 #define VT_JMPI      0x0035  /* value is the consequence of jmp false (odd) */
-#define VT_REF       0x0040  /* value is pointer to structure rather than address */
 #define VT_LVAL      0x0100  /* var is an lvalue */
 #define VT_SYM       0x0200  /* a symbol value is added */
@@ -707,10 +852,10 @@
 /* types */
 #define VT_BTYPE       0x000f  /* mask for basic type */
-#define VT_INT              0  /* integer type */
+#define VT_VOID             0  /* void type */
 #define VT_BYTE             1  /* signed byte type */
 #define VT_SHORT            2  /* short type */
-#define VT_VOID             3  /* void type */
-#define VT_PTR              4  /* pointer */
-#define VT_ENUM             5  /* enum definition */
+#define VT_INT              3  /* integer type */
+#define VT_LLONG            4  /* 64 bit integer */
+#define VT_PTR              5  /* pointer */
 #define VT_FUNC             6  /* function type */
 #define VT_STRUCT           7  /* struct/union definition */
@@ -719,29 +864,43 @@
 #define VT_LDOUBLE         10  /* IEEE long double */
 #define VT_BOOL            11  /* ISOC99 boolean type */
-#define VT_LLONG           12  /* 64 bit integer */
-#define VT_LONG            13  /* long integer (NEVER USED as type, only
-                                  during parsing) */
+#define VT_QLONG           13  /* 128-bit integer. Only used for x86-64 ABI */
+#define VT_QFLOAT          14  /* 128-bit float. Only used for x86-64 ABI */
+
 #define VT_UNSIGNED    0x0010  /* unsigned type */
-#define VT_ARRAY       0x0020  /* array type (also has VT_PTR) */
-#define VT_BITFIELD    0x0040  /* bitfield modifier */
-#define VT_CONSTANT    0x0800  /* const modifier */
-#define VT_VOLATILE    0x1000  /* volatile modifier */
-#define VT_SIGNED      0x2000  /* signed type */
-#define VT_VLA     0x00020000  /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_DEFSIGN     0x0020  /* explicitly signed or unsigned */
+#define VT_ARRAY       0x0040  /* array type (also has VT_PTR) */
+#define VT_BITFIELD    0x0080  /* bitfield modifier */
+#define VT_CONSTANT    0x0100  /* const modifier */
+#define VT_VOLATILE    0x0200  /* volatile modifier */
+#define VT_VLA         0x0400  /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_LONG        0x0800  /* long type (also has VT_INT rsp. VT_LLONG) */
 
 /* storage */
-#define VT_EXTERN  0x00000080  /* extern definition */
-#define VT_STATIC  0x00000100  /* static variable */
-#define VT_TYPEDEF 0x00000200  /* typedef definition */
-#define VT_INLINE  0x00000400  /* inline definition */
-#define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
-#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
-#define VT_WEAK    0x00010000  /* weak symbol */
-
-#define VT_STRUCT_SHIFT 18     /* shift for bitfield shift values (max: 32 - 2*6) */
+#define VT_EXTERN  0x00001000  /* extern definition */
+#define VT_STATIC  0x00002000  /* static variable */
+#define VT_TYPEDEF 0x00004000  /* typedef definition */
+#define VT_INLINE  0x00008000  /* inline definition */
+/* currently unused: 0x000[1248]0000  */
+
+#define VT_STRUCT_SHIFT 20     /* shift for bitfield shift values (32 - 2*6) */
+#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
+#define BIT_POS(t) (((t) >> VT_STRUCT_SHIFT) & 0x3f)
+#define BIT_SIZE(t) (((t) >> (VT_STRUCT_SHIFT + 6)) & 0x3f)
+
+#define VT_UNION    (1 << VT_STRUCT_SHIFT | VT_STRUCT)
+#define VT_ENUM     (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
+#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
+
+#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
+#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
+#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
 
 /* type mask (except storage) */
-#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK)
-#define VT_TYPE (~(VT_STORAGE))
+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
+#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
+
+/* symbol was created by tccasm.c first */
+#define VT_ASM (VT_VOID | VT_UNSIGNED)
+#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
 
 /* token values */
@@ -763,5 +922,4 @@
 #define TOK_LAND  0xa0
 #define TOK_LOR   0xa1
-
 #define TOK_DEC   0xa2
 #define TOK_MID   0xa3 /* inc/dec, to void constant */
@@ -770,14 +928,23 @@
 #define TOK_UMOD  0xb1 /* unsigned modulo */
 #define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
-#define TOK_CINT   0xb3 /* number in tokc */
-#define TOK_CCHAR 0xb4 /* char constant in tokc */
-#define TOK_STR   0xb5 /* pointer to string in tokc */
-#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
-#define TOK_LCHAR    0xb7
-#define TOK_LSTR     0xb8
-#define TOK_CFLOAT   0xb9 /* float constant */
-#define TOK_LINENUM  0xba /* line number info */
-#define TOK_CDOUBLE  0xc0 /* double constant */
-#define TOK_CLDOUBLE 0xc1 /* long double constant */
+
+/* tokens that carry values (in additional token string space / tokc) --> */
+#define TOK_CCHAR   0xb3 /* char constant in tokc */
+#define TOK_LCHAR   0xb4
+#define TOK_CINT    0xb5 /* number in tokc */
+#define TOK_CUINT   0xb6 /* unsigned int constant */
+#define TOK_CLLONG  0xb7 /* long long constant */
+#define TOK_CULLONG 0xb8 /* unsigned long long constant */
+#define TOK_STR     0xb9 /* pointer to string in tokc */
+#define TOK_LSTR    0xba
+#define TOK_CFLOAT  0xbb /* float constant */
+#define TOK_CDOUBLE 0xbc /* double constant */
+#define TOK_CLDOUBLE 0xbd /* long double constant */
+#define TOK_PPNUM   0xbe /* preprocessor number */
+#define TOK_PPSTR   0xbf /* preprocessor string */
+#define TOK_LINENUM 0xc0 /* line number info */
+#define TOK_TWODOTS 0xa8 /* C++ token ? */
+/* <-- */
+
 #define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
 #define TOK_ADDC1    0xc3 /* add with carry generation */
@@ -785,17 +952,18 @@
 #define TOK_SUBC1    0xc5 /* add with carry generation */
 #define TOK_SUBC2    0xc6 /* add with carry use */
-#define TOK_CUINT    0xc8 /* unsigned int constant */
-#define TOK_CLLONG   0xc9 /* long long constant */
-#define TOK_CULLONG  0xca /* unsigned long long constant */
-#define TOK_ARROW    0xcb
-#define TOK_DOTS     0xcc /* three dots */
-#define TOK_SHR      0xcd /* unsigned shift right */
-#define TOK_PPNUM    0xce /* preprocessor number */
-#define TOK_NOSUBST  0xcf /* means following token has already been pp'd */
+#define TOK_ARROW    0xc7
+#define TOK_DOTS     0xc8 /* three dots */
+#define TOK_SHR      0xc9 /* unsigned shift right */
+#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
+#define TOK_PLCHLDR  0xcb /* placeholder token as defined in C99 */
+#define TOK_NOSUBST  0xcc /* means following token has already been pp'd */
+#define TOK_PPJOIN   0xcd /* A '##' in the right position to mean pasting */
+#define TOK_CLONG    0xce /* long constant */
+#define TOK_CULONG   0xcf /* unsigned long constant */
 
 #define TOK_SHL   0x01 /* shift left */
 #define TOK_SAR   0x02 /* signed shift right */
-  
-/* assignement operators : normal operator or 0x80 */
+
+/* assignment operators : normal operator or 0x80 */
 #define TOK_A_MOD 0xa5
 #define TOK_A_AND 0xa6
@@ -809,21 +977,15 @@
 #define TOK_A_SAR 0x82
 
-#ifndef offsetof
-#define offsetof(type, field) ((size_t) &((type *)0)->field)
-#endif
-
-#ifndef countof
-#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
-#endif
-
 #define TOK_EOF       (-1)  /* end of file */
 #define TOK_LINEFEED  10    /* line feed */
 
-/* all identificators and strings have token above that */
+/* all identifiers and strings have token above that */
 #define TOK_IDENT 256
 
 #define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
 #define TOK_ASM_int TOK_INT
-#define TOK_ASM_weak TOK_WEAK1
+#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
+#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
+#define TOK_ASMDIR_LAST TOK_ASMDIR_section
 
 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
@@ -872,117 +1034,47 @@
  DEF_FP1(x)
 
-#define DEF_ASMTEST(x) \
- DEF_ASM(x ## o) \
- DEF_ASM(x ## no) \
- DEF_ASM(x ## b) \
- DEF_ASM(x ## c) \
- DEF_ASM(x ## nae) \
- DEF_ASM(x ## nb) \
- DEF_ASM(x ## nc) \
- DEF_ASM(x ## ae) \
- DEF_ASM(x ## e) \
- DEF_ASM(x ## z) \
- DEF_ASM(x ## ne) \
- DEF_ASM(x ## nz) \
- DEF_ASM(x ## be) \
- DEF_ASM(x ## na) \
- DEF_ASM(x ## nbe) \
- DEF_ASM(x ## a) \
- DEF_ASM(x ## s) \
- DEF_ASM(x ## ns) \
- DEF_ASM(x ## p) \
- DEF_ASM(x ## pe) \
- DEF_ASM(x ## np) \
- DEF_ASM(x ## po) \
- DEF_ASM(x ## l) \
- DEF_ASM(x ## nge) \
- DEF_ASM(x ## nl) \
- DEF_ASM(x ## ge) \
- DEF_ASM(x ## le) \
- DEF_ASM(x ## ng) \
- DEF_ASM(x ## nle) \
- DEF_ASM(x ## g)
-
-#endif // defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+#define DEF_ASMTEST(x,suffix) \
+ DEF_ASM(x ## o ## suffix) \
+ DEF_ASM(x ## no ## suffix) \
+ DEF_ASM(x ## b ## suffix) \
+ DEF_ASM(x ## c ## suffix) \
+ DEF_ASM(x ## nae ## suffix) \
+ DEF_ASM(x ## nb ## suffix) \
+ DEF_ASM(x ## nc ## suffix) \
+ DEF_ASM(x ## ae ## suffix) \
+ DEF_ASM(x ## e ## suffix) \
+ DEF_ASM(x ## z ## suffix) \
+ DEF_ASM(x ## ne ## suffix) \
+ DEF_ASM(x ## nz ## suffix) \
+ DEF_ASM(x ## be ## suffix) \
+ DEF_ASM(x ## na ## suffix) \
+ DEF_ASM(x ## nbe ## suffix) \
+ DEF_ASM(x ## a ## suffix) \
+ DEF_ASM(x ## s ## suffix) \
+ DEF_ASM(x ## ns ## suffix) \
+ DEF_ASM(x ## p ## suffix) \
+ DEF_ASM(x ## pe ## suffix) \
+ DEF_ASM(x ## np ## suffix) \
+ DEF_ASM(x ## po ## suffix) \
+ DEF_ASM(x ## l ## suffix) \
+ DEF_ASM(x ## nge ## suffix) \
+ DEF_ASM(x ## nl ## suffix) \
+ DEF_ASM(x ## ge ## suffix) \
+ DEF_ASM(x ## le ## suffix) \
+ DEF_ASM(x ## ng ## suffix) \
+ DEF_ASM(x ## nle ## suffix) \
+ DEF_ASM(x ## g ## suffix)
+
+#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */
 
 enum tcc_token {
-    TOK_LAST = TOK_IDENT - 1,
-#define DEF(id, str) id,
+    TOK_LAST = TOK_IDENT - 1
+#define DEF(id, str) ,id
 #include "tcctok.h"
 #undef DEF
 };
 
+/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */
 #define TOK_UIDENT TOK_DEFINE
-
-#if 0//def _WIN32
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#ifndef __GNUC__
-  #define strtold (long double)strtod
-  #define strtof (float)strtod
-  #define strtoll _strtoi64
-  #define strtoull _strtoui64
-#endif
-#else
-/* XXX: need to define this to use them in non ISOC99 context */
-extern float strtof (const char *__nptr, char **__endptr);
-extern long double strtold (const char *__nptr, char **__endptr);
-#endif
-
-#ifdef _WIN32
-#define IS_DIRSEP(c) (c == '/' || c == '\\')
-#define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
-#define PATHCMP stricmp
-#else
-#define IS_DIRSEP(c) (c == '/')
-#define IS_ABSPATH(p) IS_DIRSEP(p[0])
-#define PATHCMP strcmp
-#endif
-
-#ifdef TCC_TARGET_PE
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
-/* space exlcuding newline */
-static inline int is_space(int ch)
-{
-    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
-}
-
-static inline int isid(int c)
-{
-    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
-}
-
-static inline int isnum(int c)
-{
-    return c >= '0' && c <= '9';
-}
-
-static inline int isoct(int c)
-{
-    return c >= '0' && c <= '7';
-}
-
-static inline int toup(int c)
-{
-    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
-}
-
-#ifndef PUB_FUNC
-# define PUB_FUNC
-#endif
-
-#ifdef ONE_SOURCE
-#define ST_INLN static inline
-#define ST_FUNC static
-#define ST_DATA static
-#else
-#define ST_INLN
-#define ST_FUNC
-#define ST_DATA extern
-#endif
 
 /* ------------ libtcc.c ------------ */
@@ -995,19 +1087,12 @@
 ST_DATA struct TCCState *tcc_state;
 
-#ifdef MEM_DEBUG
-ST_DATA int mem_cur_size;
-ST_DATA int mem_max_size;
-#endif
-
-#define AFF_PRINT_ERROR     0x0001 /* print error if file not found */
-#define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */
-#define AFF_PREPROCESS      0x0004 /* preprocess file */
-
 /* public functions currently used by the tcc main function */
-PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
-PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
-PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num);
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
 PUB_FUNC char *tcc_basename(const char *name);
 PUB_FUNC char *tcc_fileextension (const char *name);
+
+#ifndef MEM_DEBUG
 PUB_FUNC void tcc_free(void *ptr);
 PUB_FUNC void *tcc_malloc(unsigned long size);
@@ -1015,4 +1100,17 @@
 PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
 PUB_FUNC char *tcc_strdup(const char *str);
+#else
+#define tcc_free(ptr)           tcc_free_debug(ptr)
+#define tcc_malloc(size)        tcc_malloc_debug(size, __FILE__, __LINE__)
+#define tcc_mallocz(size)       tcc_mallocz_debug(size, __FILE__, __LINE__)
+#define tcc_realloc(ptr,size)   tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
+#define tcc_strdup(str)         tcc_strdup_debug(str, __FILE__, __LINE__)
+PUB_FUNC void tcc_free_debug(void *ptr);
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
+#endif
+
 #define free(p) use_tcc_free(p)
 #define malloc(s) use_tcc_malloc(s)
@@ -1020,14 +1118,14 @@
 #undef strdup
 #define strdup(s) use_tcc_strdup(s)
-PUB_FUNC void tcc_memstats(void);
+PUB_FUNC void tcc_memcheck(void);
 PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
-PUB_FUNC void tcc_error(const char *fmt, ...);
+PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
 PUB_FUNC void tcc_warning(const char *fmt, ...);
 
 /* other utilities */
-ST_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
 ST_FUNC void dynarray_reset(void *pp, int *n);
-ST_FUNC void cstr_ccat(CString *cstr, int ch);
-ST_FUNC void cstr_cat(CString *cstr, const char *str);
+ST_INLN void cstr_ccat(CString *cstr, int ch);
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
 ST_FUNC void cstr_wccat(CString *cstr, int ch);
 ST_FUNC void cstr_new(CString *cstr);
@@ -1035,19 +1133,9 @@
 ST_FUNC void cstr_reset(CString *cstr);
 
-ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
-ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
-ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
-ST_FUNC void section_reserve(Section *sec, unsigned long size);
-ST_FUNC Section *find_section(TCCState *s1, const char *name);
-
-ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
-ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
-ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
-
 ST_INLN void sym_free(Sym *sym);
-ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);
 ST_FUNC Sym *sym_find2(Sym *s, int v);
 ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
-ST_FUNC void sym_pop(Sym **ptop, Sym *b);
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
 ST_INLN Sym *struct_find(int v);
 ST_INLN Sym *sym_find(int v);
@@ -1059,9 +1147,40 @@
 
 ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
+/* flags: */
+#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
+#define AFF_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
+#define AFF_TYPE_BIN        0x40 /* file to add is binary */
+/* s->filetype: */
+#define AFF_TYPE_NONE   0
+#define AFF_TYPE_C      1
+#define AFF_TYPE_ASM    2
+#define AFF_TYPE_ASMPP  3
+#define AFF_TYPE_LIB    4
+/* values from tcc_object_type(...) */
+#define AFF_BINTYPE_REL 1
+#define AFF_BINTYPE_DYN 2
+#define AFF_BINTYPE_AR  3
+#define AFF_BINTYPE_C67 4
+
+
 ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
 ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
-
-PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
-PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv);
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
+PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
+#ifdef _WIN32
+ST_FUNC char *normalize_slashes(char *path);
+#endif
+
+/* tcc_parse_args return codes: */
+#define OPT_HELP 1
+#define OPT_HELP2 2
+#define OPT_V 3
+#define OPT_PRINT_DIRS 4
+#define OPT_AR 5
+#define OPT_IMPDEF 6
+#define OPT_M32 32
+#define OPT_M64 64
 
 /* ------------ tccpp.c ------------ */
@@ -1091,13 +1210,23 @@
                                         token. line feed is also
                                         returned at eof */
-#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
+#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */
 #define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
+#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
+#define PARSE_FLAG_TOK_STR    0x0040 /* return parsed strings instead of TOK_PPSTR */
+
+/* isidnum_table flags: */
+#define IS_SPC 1
+#define IS_ID  2
+#define IS_NUM 4
 
 ST_FUNC TokenSym *tok_alloc(const char *str, int len);
-ST_FUNC char *get_tok_str(int v, CValue *cv);
-ST_FUNC void save_parse_state(ParseState *s);
-ST_FUNC void restore_parse_state(ParseState *s);
+ST_FUNC const char *get_tok_str(int v, CValue *cv);
+ST_FUNC void begin_macro(TokenString *str, int alloc);
+ST_FUNC void end_macro(void);
+ST_FUNC int set_idnum(int c, int val);
 ST_INLN void tok_str_new(TokenString *s);
-ST_FUNC void tok_str_free(int *str);
+ST_FUNC TokenString *tok_str_alloc(void);
+ST_FUNC void tok_str_free(TokenString *s);
+ST_FUNC void tok_str_free_str(int *str);
 ST_FUNC void tok_str_add(TokenString *s, int t);
 ST_FUNC void tok_str_add_tok(TokenString *s);
@@ -1108,5 +1237,5 @@
 ST_FUNC Sym *label_find(int v);
 ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
-ST_FUNC void label_pop(Sym **ptop, Sym *slast);
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
 ST_FUNC void parse_define(void);
 ST_FUNC void preprocess(int is_bof);
@@ -1114,26 +1243,30 @@
 ST_FUNC void next(void);
 ST_INLN void unget_tok(int last_tok);
-ST_FUNC void preprocess_init(TCCState *s1);
-ST_FUNC void preprocess_new(void);
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
+ST_FUNC void preprocess_end(TCCState *s1);
+ST_FUNC void tccpp_new(TCCState *s);
+ST_FUNC void tccpp_delete(TCCState *s);
 ST_FUNC int tcc_preprocess(TCCState *s1);
 ST_FUNC void skip(int c);
-ST_FUNC void expect(const char *msg);
+ST_FUNC NORETURN void expect(const char *msg);
+
+/* space excluding newline */
+static inline int is_space(int ch) {
+    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
+}
+static inline int isid(int c) {
+    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+static inline int isnum(int c) {
+    return c >= '0' && c <= '9';
+}
+static inline int isoct(int c) {
+    return c >= '0' && c <= '7';
+}
+static inline int toup(int c) {
+    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
+}
 
 /* ------------ tccgen.c ------------ */
-
-ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
-ST_DATA Section *cur_text_section; /* current section where function code is generated */
-#ifdef CONFIG_TCC_ASM
-ST_DATA Section *last_text_section; /* to handle .previous asm directive */
-#endif
-#ifdef CONFIG_TCC_BCHECK
-/* bound check related sections */
-ST_DATA Section *bounds_section; /* contains global data bound description */
-ST_DATA Section *lbounds_section; /* contains local data bound description */
-#endif
-/* symbol sections */
-ST_DATA Section *symtab_section, *strtab_section;
-/* debug sections */
-ST_DATA Section *stab_section, *stabstr_section;
 
 #define SYM_POOL_NB (8192 / sizeof(Sym))
@@ -1148,5 +1281,5 @@
 ST_DATA Sym *define_stack;
 ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
-ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
+ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
 #define vstack  (__vstack + 1)
 ST_DATA int rsym, anon_sym, ind, loc;
@@ -1156,13 +1289,26 @@
 ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic */
 ST_DATA int func_vc;
 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
-ST_DATA char *funcname;
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_FUNC void tcc_debug_start(TCCState *s1);
+ST_FUNC void tcc_debug_end(TCCState *s1);
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
+ST_FUNC void tcc_debug_line(TCCState *s1);
+
+ST_FUNC int tccgen_compile(TCCState *s1);
+ST_FUNC void free_inline_functions(TCCState *s);
+ST_FUNC void check_vstack(void);
 
 ST_INLN int is_float(int t);
 ST_FUNC int ieee_finite(double d);
 ST_FUNC void test_lvalue(void);
-ST_FUNC void swap(int *p, int *q);
 ST_FUNC void vpushi(int v);
+ST_FUNC ElfSym *elfsym(Sym *);
+ST_FUNC void update_storage(Sym *sym);
 ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
 ST_FUNC void vset(CType *type, int r, int v);
@@ -1178,6 +1324,8 @@
 ST_FUNC void vpushv(SValue *v);
 ST_FUNC void save_reg(int r);
+ST_FUNC void save_reg_upstack(int r, int n);
 ST_FUNC int get_reg(int rc);
 ST_FUNC void save_regs(int n);
+ST_FUNC void gaddrof(void);
 ST_FUNC int gv(int rc);
 ST_FUNC void gv2(int rc1, int rc2);
@@ -1188,4 +1336,5 @@
 ST_FUNC void vstore(void);
 ST_FUNC void inc(int post, int c);
+ST_FUNC void parse_mult_str (CString *astr, const char *msg);
 ST_FUNC void parse_asm_str(CString *astr);
 ST_FUNC int lvalue_type(int t);
@@ -1196,8 +1345,9 @@
 ST_FUNC void gexpr(void);
 ST_FUNC int expr_const(void);
-ST_FUNC void gen_inline_functions(void);
-ST_FUNC void decl(int l);
 #if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
 ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
+#endif
+#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
+ST_FUNC int classify_x86_64_va_arg(CType *ty);
 #endif
 
@@ -1218,11 +1368,48 @@
 } Stab_Sym;
 
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+ST_FUNC void tccelf_bounds_new(TCCState *s);
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+ST_FUNC void tccelf_new(TCCState *s);
+ST_FUNC void tccelf_delete(TCCState *s);
+ST_FUNC void tccelf_stab_new(TCCState *s);
+ST_FUNC void tccelf_begin_file(TCCState *s1);
+ST_FUNC void tccelf_end_file(TCCState *s1);
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
+ST_FUNC void section_reserve(Section *sec, unsigned long size);
+ST_FUNC Section *find_section(TCCState *s1, const char *name);
 ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
+#endif
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
 
 ST_FUNC int put_elf_str(Section *s, const char *sym);
 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
-ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
 ST_FUNC int find_elf_sym(Section *s, const char *name);
 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
 
 ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
@@ -1231,18 +1418,20 @@
 ST_FUNC void put_stabd(int type, int other, int desc);
 
-ST_FUNC void relocate_common_syms(void);
-ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
+ST_FUNC void resolve_common_syms(TCCState *s1);
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
 ST_FUNC void relocate_section(TCCState *s1, Section *s);
 
-ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
 ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
 ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
 ST_FUNC void tcc_add_bcheck(TCCState *s1);
+ST_FUNC void tcc_add_runtime(TCCState *s1);
 
 ST_FUNC void build_got_entries(TCCState *s1);
-ST_FUNC void tcc_add_runtime(TCCState *s1);
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
+ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
 
 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
-#ifdef TCC_IS_NATIVE
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
 ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
 #endif
@@ -1257,11 +1446,25 @@
 #endif
 
+/* ------------ xxx-link.c ------------ */
+
+/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
+   that unknown relocation don't create a GOT or PLT entry */
+enum gotplt_entry {
+    NO_GOTPLT_ENTRY,	/* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
+    BUILD_GOT_ONLY,	/* only build GOT (eg. TPOFF relocs) */
+    AUTO_GOTPLT_ENTRY,	/* generate if sym is UNDEF */
+    ALWAYS_GOTPLT_ENTRY	/* always generate (eg. PLTOFF relocs) */
+};
+
+ST_FUNC int code_reloc (int reloc_type);
+ST_FUNC int gotplt_entry_type (int reloc_type);
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
+ST_FUNC void relocate_init(Section *sr);
+ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
+ST_FUNC void relocate_plt(TCCState *s1);
+
 /* ------------ xxx-gen.c ------------ */
 
-#ifdef TCC_TARGET_X86_64
-ST_DATA const int reg_classes[NB_REGS+7];
-#else
 ST_DATA const int reg_classes[NB_REGS];
-#endif
 
 ST_FUNC void gsym_addr(int t, int a);
@@ -1269,4 +1472,5 @@
 ST_FUNC void load(int r, SValue *sv);
 ST_FUNC void store(int r, SValue *v);
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
 ST_FUNC void gfunc_call(int nb_args);
 ST_FUNC void gfunc_prolog(CType *func_type);
@@ -1275,4 +1479,9 @@
 ST_FUNC void gjmp_addr(int a);
 ST_FUNC int gtst(int inv, int t);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void gtst_addr(int inv, int a);
+#else
+#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a)
+#endif
 ST_FUNC void gen_opi(int op);
 ST_FUNC void gen_opf(int op);
@@ -1286,9 +1495,36 @@
 ST_FUNC void gen_cvt_itof(int t);
 #endif
+ST_FUNC void gen_vla_sp_save(int addr);
+ST_FUNC void gen_vla_sp_restore(int addr);
+ST_FUNC void gen_vla_alloc(CType *type, int align);
+
+static inline uint16_t read16le(unsigned char *p) {
+    return p[0] | (uint16_t)p[1] << 8;
+}
+static inline void write16le(unsigned char *p, uint16_t x) {
+    p[0] = x & 255;  p[1] = x >> 8 & 255;
+}
+static inline uint32_t read32le(unsigned char *p) {
+  return read16le(p) | (uint32_t)read16le(p + 2) << 16;
+}
+static inline void write32le(unsigned char *p, uint32_t x) {
+    write16le(p, x);  write16le(p + 2, x >> 16);
+}
+static inline void add32le(unsigned char *p, int32_t x) {
+    write32le(p, read32le(p) + x);
+}
+static inline uint64_t read64le(unsigned char *p) {
+  return read32le(p) | (uint64_t)read32le(p + 4) << 32;
+}
+static inline void write64le(unsigned char *p, uint64_t x) {
+    write32le(p, x);  write32le(p + 4, x >> 32);
+}
+static inline void add64le(unsigned char *p, int64_t x) {
+    write64le(p, read64le(p) + x);
+}
 
 /* ------------ i386-gen.c ------------ */
 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 ST_FUNC void g(int c);
-ST_FUNC int oad(int c, int s);
 ST_FUNC void gen_le16(int c);
 ST_FUNC void gen_le32(int c);
@@ -1306,11 +1542,26 @@
 ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
 ST_FUNC void gen_opl(int op);
+#ifdef TCC_TARGET_PE
+ST_FUNC void gen_vla_result(int addr);
+#endif
 #endif
 
 /* ------------ arm-gen.c ------------ */
 #ifdef TCC_TARGET_ARM
-ST_FUNC void arm_init_types(void);
-ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+PUB_FUNC const char *default_elfinterp(struct TCCState *s);
+#endif
+ST_FUNC void arm_init(struct TCCState *s);
 ST_FUNC void gen_cvt_itof1(int t);
+#endif
+
+/* ------------ arm64-gen.c ------------ */
+#ifdef TCC_TARGET_ARM64
+ST_FUNC void gen_cvt_sxtw(void);
+ST_FUNC void gen_opl(int op);
+ST_FUNC void gfunc_return(CType *func_type);
+ST_FUNC void gen_va_start(void);
+ST_FUNC void gen_va_arg(CType *t);
+ST_FUNC void gen_clear_cache(void);
 #endif
 
@@ -1331,4 +1582,5 @@
 #ifdef CONFIG_TCC_ASM
 ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
 ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
 ST_FUNC int asm_int_expr(TCCState *s1);
@@ -1336,5 +1588,9 @@
 /* ------------ i386-asm.c ------------ */
 ST_FUNC void gen_expr32(ExprValue *pe);
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_expr64(ExprValue *pe);
+#endif
 ST_FUNC void asm_opcode(TCCState *s1, int opcode);
+ST_FUNC int asm_parse_regvar(int t);
 ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
 ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
@@ -1348,9 +1604,17 @@
 ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
 ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
+#endif
 #ifdef TCC_TARGET_X86_64
 ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
 #endif
-#endif
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
+/* symbol properties stored in Elf32_Sym->st_other */
+# define ST_PE_EXPORT 0x10
+# define ST_PE_IMPORT 0x20
+# define ST_PE_STDCALL 0x40
+#endif
+#define ST_ASM_SET 0x04
 
 /* ------------ tccrun.c ----------------- */
@@ -1365,9 +1629,6 @@
 ST_FUNC void dlclose(void *p);
 ST_FUNC const char *dlerror(void);
-ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
-#elif !defined _WIN32
-ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
-#endif
-
+ST_FUNC void *dlsym(void *handle, const char *symbol);
+#endif
 #ifdef CONFIG_TCC_BACKTRACE
 ST_DATA int rt_num_callers;
@@ -1376,9 +1637,20 @@
 ST_FUNC void tcc_set_num_callers(int n);
 #endif
+ST_FUNC void tcc_run_free(TCCState *s1);
+#endif
+
+/* ------------ tcctools.c ----------------- */
+#if 0 /* included in tcc.c */
+ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
+#ifdef TCC_TARGET_PE
+ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
+#endif
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
 #endif
 
 /********************************************************/
 #undef ST_DATA
-#ifdef ONE_SOURCE
+#if ONE_SOURCE
 #define ST_DATA static
 #else
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccasm.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c	(revision 331)
@@ -32,5 +32,56 @@
 }
 
-ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
+static Sym* asm_new_label(TCCState *s1, int label, int is_local);
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
+
+static Sym *asm_label_find(int v)
+{
+    Sym *sym = sym_find(v);
+    while (sym && sym->sym_scope)
+        sym = sym->prev_tok;
+    return sym;
+}
+
+static Sym *asm_label_push(int v)
+{
+    /* We always add VT_EXTERN, for sym definition that's tentative
+       (for .set, removed for real defs), for mere references it's correct
+       as is.  */
+    Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
+    sym->r = VT_CONST | VT_SYM;
+    return sym;
+}
+
+/* Return a symbol we can use inside the assembler, having name NAME.
+   Symbols from asm and C source share a namespace.  If we generate
+   an asm symbol it's also a (file-global) C symbol, but it's
+   either not accessible by name (like "L.123"), or its type information
+   is such that it's not usable without a proper C declaration.
+
+   Sometimes we need symbols accessible by name from asm, which
+   are anonymous in C, in this case CSYM can be used to transfer
+   all information from that symbol to the (possibly newly created)
+   asm symbol.  */
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
+{
+    Sym *sym = asm_label_find(name);
+    if (!sym) {
+	sym = asm_label_push(name);
+	if (csym)
+	  sym->c = csym->c;
+    }
+    return sym;
+}
+
+static Sym* asm_section_sym(TCCState *s1, Section *sec)
+{
+    char buf[100];
+    int label = tok_alloc(buf,
+        snprintf(buf, sizeof buf, "L.%s", sec->name)
+        )->tok;
+    Sym *sym = asm_label_find(label);
+    return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
+}
 
 /* We do not use the C expression parser to handle symbols. Maybe the
@@ -40,18 +91,19 @@
 {
     Sym *sym;
-    int op, n, label;
+    int op, label;
+    uint64_t n;
     const char *p;
 
     switch(tok) {
     case TOK_PPNUM:
-        p = tokc.cstr->data;
-        n = strtoul(p, (char **)&p, 0);
+        p = tokc.str.data;
+        n = strtoull(p, (char **)&p, 0);
         if (*p == 'b' || *p == 'f') {
             /* backward or forward label */
             label = asm_get_local_label_name(s1, n);
-            sym = label_find(label);
+            sym = asm_label_find(label);
             if (*p == 'b') {
                 /* backward : find the last corresponding defined label */
-                if (sym && sym->r == 0)
+                if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
                     sym = sym->prev_tok;
                 if (!sym)
@@ -59,15 +111,16 @@
             } else {
                 /* forward */
-                if (!sym || sym->r) {
+                if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
                     /* if the last label is defined, then define a new one */
-                    sym = label_push(&s1->asm_labels, label, 0);
-                    sym->type.t = VT_STATIC | VT_VOID;
+		    sym = asm_label_push(label);
                 }
             }
-            pe->v = 0;
-            pe->sym = sym;
+	    pe->v = 0;
+	    pe->sym = sym;
+	    pe->pcrel = 0;
         } else if (*p == '\0') {
             pe->v = n;
             pe->sym = NULL;
+	    pe->pcrel = 0;
         } else {
             tcc_error("invalid number syntax");
@@ -95,4 +148,5 @@
 	pe->v = tokc.i;
 	pe->sym = NULL;
+	pe->pcrel = 0;
 	next();
 	break;
@@ -102,20 +156,25 @@
         skip(')');
         break;
+    case '.':
+        pe->v = ind;
+        pe->sym = asm_section_sym(s1, cur_text_section);
+        pe->pcrel = 0;
+        next();
+        break;
     default:
         if (tok >= TOK_IDENT) {
+	    ElfSym *esym;
             /* label case : if the label was not found, add one */
-            sym = label_find(tok);
-            if (!sym) {
-                sym = label_push(&s1->asm_labels, tok, 0);
-                /* NOTE: by default, the symbol is global */
-                sym->type.t = VT_VOID;
-            }
-            if (sym->r == SHN_ABS) {
+	    sym = get_asm_sym(tok, NULL);
+	    esym = elfsym(sym);
+            if (esym && esym->st_shndx == SHN_ABS) {
                 /* if absolute symbol, no need to put a symbol value */
-                pe->v = sym->jnext;
+                pe->v = esym->st_value;
                 pe->sym = NULL;
+		pe->pcrel = 0;
             } else {
                 pe->v = 0;
                 pe->sym = sym;
+		pe->pcrel = 0;
             }
             next();
@@ -220,23 +279,72 @@
             /* NOTE: we are less powerful than gas in that case
                because we store only one symbol in the expression */
-            if (!pe->sym && !e2.sym) {
-                /* OK */
-            } else if (pe->sym && !e2.sym) {
-                /* OK */
-            } else if (pe->sym && e2.sym) {
-                if (pe->sym == e2.sym) { 
-                    /* OK */
-                } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
-                    /* we also accept defined symbols in the same section */
-                    pe->v += pe->sym->jnext - e2.sym->jnext;
-                } else {
-                    goto cannot_relocate;
-                }
-                pe->sym = NULL; /* same symbols can be substracted to NULL */
-            } else {
-            cannot_relocate:
-                tcc_error("invalid operation with label");
-            }
-        }
+	    if (!e2.sym) {
+		/* OK */
+	    } else if (pe->sym == e2.sym) { 
+		/* OK */
+		pe->sym = NULL; /* same symbols can be subtracted to NULL */
+	    } else {
+		ElfSym *esym1, *esym2;
+		esym1 = elfsym(pe->sym);
+		esym2 = elfsym(e2.sym);
+		if (esym1 && esym1->st_shndx == esym2->st_shndx
+		    && esym1->st_shndx != SHN_UNDEF) {
+		    /* we also accept defined symbols in the same section */
+		    pe->v += esym1->st_value - esym2->st_value;
+		    pe->sym = NULL;
+		} else if (esym2->st_shndx == cur_text_section->sh_num) {
+		    /* When subtracting a defined symbol in current section
+		       this actually makes the value PC-relative.  */
+		    pe->v -= esym2->st_value - ind - 4;
+		    pe->pcrel = 1;
+		    e2.sym = NULL;
+		} else {
+cannot_relocate:
+		    tcc_error("invalid operation with label");
+		}
+	    }
+        }
+    }
+}
+
+static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_sum(s1, pe);
+    for(;;) {
+        op = tok;
+	if (op != TOK_EQ && op != TOK_NE
+	    && (op > TOK_GT || op < TOK_ULE))
+            break;
+        next();
+        asm_expr_sum(s1, &e2);
+        if (pe->sym || e2.sym)
+            tcc_error("invalid operation with label");
+        switch(op) {
+	case TOK_EQ:
+	    pe->v = pe->v == e2.v;
+	    break;
+	case TOK_NE:
+	    pe->v = pe->v != e2.v;
+	    break;
+	case TOK_LT:
+	    pe->v = (int64_t)pe->v < (int64_t)e2.v;
+	    break;
+	case TOK_GE:
+	    pe->v = (int64_t)pe->v >= (int64_t)e2.v;
+	    break;
+	case TOK_LE:
+	    pe->v = (int64_t)pe->v <= (int64_t)e2.v;
+	    break;
+	case TOK_GT:
+	    pe->v = (int64_t)pe->v > (int64_t)e2.v;
+	    break;
+        default:
+            break;
+        }
+	/* GAS compare results are -1/0 not 1/0.  */
+	pe->v = -(int64_t)pe->v;
     }
 }
@@ -244,5 +352,5 @@
 ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
 {
-    asm_expr_sum(s1, pe);
+    asm_expr_cmp(s1, pe);
 }
 
@@ -256,57 +364,61 @@
 }
 
-/* NOTE: the same name space as C labels is used to avoid using too
-   much memory when storing labels in TokenStrings */
-static void asm_new_label1(TCCState *s1, int label, int is_local,
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
                            int sh_num, int value)
 {
     Sym *sym;
-
-    sym = label_find(label);
+    ElfSym *esym;
+
+    sym = asm_label_find(label);
     if (sym) {
-        if (sym->r) {
+	esym = elfsym(sym);
+	/* A VT_EXTERN symbol, even if it has a section is considered
+	   overridable.  This is how we "define" .set targets.  Real
+	   definitions won't have VT_EXTERN set.  */
+        if (esym && esym->st_shndx != SHN_UNDEF) {
             /* the label is already defined */
-            if (!is_local) {
-                tcc_error("assembler label '%s' already defined", 
-                      get_tok_str(label, NULL));
-            } else {
-                /* redefinition of local labels is possible */
+            if (IS_ASM_SYM(sym)
+                && (is_local == 1 || (sym->type.t & VT_EXTERN)))
                 goto new_label;
-            }
+            if (!(sym->type.t & VT_EXTERN))
+                tcc_error("assembler label '%s' already defined",
+                          get_tok_str(label, NULL));
         }
     } else {
     new_label:
-        sym = label_push(&s1->asm_labels, label, 0);
-        sym->type.t = VT_STATIC | VT_VOID;
-    }
-    sym->r = sh_num;
-    sym->jnext = value;
-}
-
-static void asm_new_label(TCCState *s1, int label, int is_local)
-{
-    asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
-}
-
-static void asm_free_labels(TCCState *st)
-{
-    Sym *s, *s1;
-    Section *sec;
-    
-    for(s = st->asm_labels; s != NULL; s = s1) {
-        s1 = s->prev;
-        /* define symbol value in object file */
-        if (s->r) {
-            if (s->r == SHN_ABS)
-                sec = SECTION_ABS;
-            else
-                sec = st->sections[s->r];
-            put_extern_sym2(s, sec, s->jnext, 0, 0);
-        }
-        /* remove label */
-        table_ident[s->v - TOK_IDENT]->sym_label = NULL;
-        sym_free(s);
-    }
-    st->asm_labels = NULL;
+        sym = asm_label_push(label);
+    }
+    if (!sym->c)
+      put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
+    esym = elfsym(sym);
+    esym->st_shndx = sh_num;
+    esym->st_value = value;
+    if (is_local != 2)
+        sym->type.t &= ~VT_EXTERN;
+    return sym;
+}
+
+static Sym* asm_new_label(TCCState *s1, int label, int is_local)
+{
+    return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
+}
+
+/* Set the value of LABEL to that of some expression (possibly
+   involving other symbols).  LABEL can be overwritten later still.  */
+static Sym* set_symbol(TCCState *s1, int label)
+{
+    long n;
+    ExprValue e;
+    Sym *sym;
+    ElfSym *esym;
+    next();
+    asm_expr(s1, &e);
+    n = e.v;
+    esym = elfsym(e.sym);
+    if (esym)
+	n += esym->st_value;
+    sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
+    elfsym(sym)->st_other |= ST_ASM_SET;
+    return sym;
 }
 
@@ -325,5 +437,21 @@
 }
 
-static void asm_parse_directive(TCCState *s1)
+static void push_section(TCCState *s1, const char *name)
+{
+    Section *sec = find_section(s1, name);
+    sec->prev = cur_text_section;
+    use_section1(s1, sec);
+}
+
+static void pop_section(TCCState *s1)
+{
+    Section *prev = cur_text_section->prev;
+    if (!prev)
+        tcc_error(".popsection without .pushsection");
+    cur_text_section->prev = NULL;
+    use_section1(s1, prev);
+}
+
+static void asm_parse_directive(TCCState *s1, int global)
 {
     int n, offset, v, size, tok1;
@@ -332,14 +460,22 @@
 
     /* assembler directive */
-    next();
     sec = cur_text_section;
     switch(tok) {
-    case TOK_ASM_align:
-    case TOK_ASM_skip:
-    case TOK_ASM_space:
+    case TOK_ASMDIR_align:
+    case TOK_ASMDIR_balign:
+    case TOK_ASMDIR_p2align:
+    case TOK_ASMDIR_skip:
+    case TOK_ASMDIR_space:
         tok1 = tok;
         next();
         n = asm_int_expr(s1);
-        if (tok1 == TOK_ASM_align) {
+        if (tok1 == TOK_ASMDIR_p2align)
+        {
+            if (n < 0 || n > 30)
+                tcc_error("invalid p2align, must be between 0 and 30");
+            n = 1 << n;
+            tok1 = TOK_ASMDIR_align;
+        }
+        if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
             if (n < 0 || (n & (n-1)) != 0)
                 tcc_error("alignment must be a positive power of two");
@@ -350,4 +486,6 @@
                 sec->sh_addralign = n;
         } else {
+	    if (n < 0)
+	        n = 0;
             size = n;
         }
@@ -365,5 +503,9 @@
         ind += size;
         break;
-    case TOK_ASM_quad:
+    case TOK_ASMDIR_quad:
+#ifdef TCC_TARGET_X86_64
+	size = 8;
+	goto asm_data;
+#else
         next();
         for(;;) {
@@ -371,5 +513,5 @@
             const char *p;
 
-            p = tokc.cstr->data;
+            p = tokc.str.data;
             if (tok != TOK_PPNUM) {
             error_constant:
@@ -392,13 +534,14 @@
         }
         break;
-    case TOK_ASM_byte:
+#endif
+    case TOK_ASMDIR_byte:
         size = 1;
         goto asm_data;
-    case TOK_ASM_word:
-    case TOK_SHORT:
+    case TOK_ASMDIR_word:
+    case TOK_ASMDIR_short:
         size = 2;
         goto asm_data;
-    case TOK_LONG:
-    case TOK_INT:
+    case TOK_ASMDIR_long:
+    case TOK_ASMDIR_int:
         size = 4;
     asm_data:
@@ -410,4 +553,8 @@
                 if (size == 4) {
                     gen_expr32(&e);
+#ifdef TCC_TARGET_X86_64
+		} else if (size == 8) {
+		    gen_expr64(&e);
+#endif
                 } else {
                     if (e.sym)
@@ -426,5 +573,5 @@
         }
         break;
-    case TOK_ASM_fill:
+    case TOK_ASMDIR_fill:
         {
             int repeat, size, val, i, j;
@@ -468,10 +615,42 @@
         }
         break;
-    case TOK_ASM_org:
+    case TOK_ASMDIR_rept:
+        {
+            int repeat;
+            TokenString *init_str;
+            next();
+            repeat = asm_int_expr(s1);
+            init_str = tok_str_alloc();
+            while (next(), tok != TOK_ASMDIR_endr) {
+                if (tok == CH_EOF)
+                    tcc_error("we at end of file, .endr not found");
+                tok_str_add_tok(init_str);
+            }
+            tok_str_add(init_str, -1);
+            tok_str_add(init_str, 0);
+            begin_macro(init_str, 1);
+            while (repeat-- > 0) {
+                tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
+				      global);
+                macro_ptr = init_str->str;
+            }
+            end_macro();
+            next();
+            break;
+        }
+    case TOK_ASMDIR_org:
         {
             unsigned long n;
-            next();
-            /* XXX: handle section symbols too */
-            n = asm_int_expr(s1);
+	    ExprValue e;
+	    ElfSym *esym;
+            next();
+	    asm_expr(s1, &e);
+	    n = e.v;
+	    esym = elfsym(e.sym);
+	    if (esym) {
+		if (esym->st_shndx != cur_text_section->sh_num)
+		  expect("constant or same-section symbol");
+		n += esym->st_value;
+	    }
             if (n < ind)
                 tcc_error("attempt to .org backwards");
@@ -481,26 +660,35 @@
         }
         break;
-    case TOK_ASM_globl:
-    case TOK_ASM_global:
-    case TOK_ASM_weak:
-    tok1 = tok;
+    case TOK_ASMDIR_set:
+	next();
+	tok1 = tok;
+	next();
+	/* Also accept '.set stuff', but don't do anything with this.
+	   It's used in GAS to set various features like '.set mips16'.  */
+	if (tok == ',')
+	    set_symbol(s1, tok1);
+	break;
+    case TOK_ASMDIR_globl:
+    case TOK_ASMDIR_global:
+    case TOK_ASMDIR_weak:
+    case TOK_ASMDIR_hidden:
+	tok1 = tok;
 	do { 
             Sym *sym;
-
-            next();
-            sym = label_find(tok);
-            if (!sym) {
-                sym = label_push(&s1->asm_labels, tok, 0);
-                sym->type.t = VT_VOID;
-            }
-            sym->type.t &= ~VT_STATIC;
-            if (tok1 == TOK_ASM_weak)
-                sym->type.t |= VT_WEAK;
+            next();
+            sym = get_asm_sym(tok, NULL);
+	    if (tok1 != TOK_ASMDIR_hidden)
+                sym->type.t &= ~VT_STATIC;
+            if (tok1 == TOK_ASMDIR_weak)
+                sym->a.weak = 1;
+	    else if (tok1 == TOK_ASMDIR_hidden)
+	        sym->a.visibility = STV_HIDDEN;
+            update_storage(sym);
             next();
 	} while (tok == ',');
 	break;
-    case TOK_ASM_string:
-    case TOK_ASM_ascii:
-    case TOK_ASM_asciz:
+    case TOK_ASMDIR_string:
+    case TOK_ASMDIR_ascii:
+    case TOK_ASMDIR_asciz:
         {
             const uint8_t *p;
@@ -512,7 +700,7 @@
                 if (tok != TOK_STR)
                     expect("string constant");
-                p = tokc.cstr->data;
-                size = tokc.cstr->size;
-                if (t == TOK_ASM_ascii && size > 0)
+                p = tokc.str.data;
+                size = tokc.str.size;
+                if (t == TOK_ASMDIR_ascii && size > 0)
                     size--;
                 for(i = 0; i < size; i++)
@@ -527,7 +715,7 @@
 	}
 	break;
-    case TOK_ASM_text:
-    case TOK_ASM_data:
-    case TOK_ASM_bss:
+    case TOK_ASMDIR_text:
+    case TOK_ASMDIR_data:
+    case TOK_ASMDIR_bss:
 	{ 
             char sname[64];
@@ -539,9 +727,12 @@
 		next();
             }
-            sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
+            if (n)
+                sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
+            else
+                sprintf(sname, "%s", get_tok_str(tok1, NULL));
             use_section(s1, sname);
 	}
 	break;
-    case TOK_ASM_file:
+    case TOK_ASMDIR_file:
         {
             char filename[512];
@@ -551,5 +742,5 @@
 
             if (tok == TOK_STR)
-                pstrcat(filename, sizeof(filename), tokc.cstr->data);
+                pstrcat(filename, sizeof(filename), tokc.str.data);
             else
                 pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
@@ -561,5 +752,5 @@
         }
         break;
-    case TOK_ASM_ident:
+    case TOK_ASMDIR_ident:
         {
             char ident[256];
@@ -569,5 +760,5 @@
 
             if (tok == TOK_STR)
-                pstrcat(ident, sizeof(ident), tokc.cstr->data);
+                pstrcat(ident, sizeof(ident), tokc.str.data);
             else
                 pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
@@ -579,26 +770,26 @@
         }
         break;
-    case TOK_ASM_size:
+    case TOK_ASMDIR_size:
         { 
             Sym *sym;
 
             next();
-            sym = label_find(tok);
+            sym = asm_label_find(tok);
             if (!sym) {
                 tcc_error("label not found: %s", get_tok_str(tok, NULL));
             }
 
-            next();
-            skip(',');
             /* XXX .size name,label2-label1 */
             if (s1->warn_unsupported)
                 tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
 
-            while (tok != '\n' && tok != CH_EOF) {
+            next();
+            skip(',');
+            while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
                 next();
             }
         }
         break;
-    case TOK_ASM_type:
+    case TOK_ASMDIR_type:
         { 
             Sym *sym;
@@ -606,22 +797,17 @@
 
             next();
-            sym = label_find(tok);
-            if (!sym) {
-                sym = label_push(&s1->asm_labels, tok, 0);
-                sym->type.t = VT_VOID;
-            }
-
+            sym = get_asm_sym(tok, NULL);
             next();
             skip(',');
             if (tok == TOK_STR) {
-                newtype = tokc.cstr->data;
+                newtype = tokc.str.data;
             } else {
                 if (tok == '@' || tok == '%')
-                    skip(tok);
+                    next();
                 newtype = get_tok_str(tok, NULL);
             }
 
             if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
-                sym->type.t = VT_FUNC;
+                sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
             }
             else if (s1->warn_unsupported)
@@ -632,8 +818,11 @@
         }
         break;
-    case TOK_SECTION1:
+    case TOK_ASMDIR_pushsection:
+    case TOK_ASMDIR_section:
         {
             char sname[256];
-
+	    int old_nb_section = s1->nb_sections;
+
+	    tok1 = tok;
             /* XXX: support more options */
             next();
@@ -641,5 +830,5 @@
             while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
                 if (tok == TOK_STR)
-                    pstrcat(sname, sizeof(sname), tokc.cstr->data);
+                    pstrcat(sname, sizeof(sname), tokc.str.data);
                 else
                     pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
@@ -652,10 +841,24 @@
                     expect("string constant");
                 next();
+                if (tok == ',') {
+                    next();
+                    if (tok == '@' || tok == '%')
+                        next();
+                    next();
+                }
             }
             last_text_section = cur_text_section;
-            use_section(s1, sname);
-        }
-        break;
-    case TOK_ASM_previous:
+	    if (tok1 == TOK_ASMDIR_section)
+	        use_section(s1, sname);
+	    else
+	        push_section(s1, sname);
+	    /* If we just allocated a new section reset its alignment to
+	       1.  new_section normally acts for GCC compatibility and
+	       sets alignment to PTR_SIZE.  The assembler behaves different. */
+	    if (old_nb_section != s1->nb_sections)
+	        cur_text_section->sh_addralign = 1;
+        }
+        break;
+    case TOK_ASMDIR_previous:
         { 
             Section *sec;
@@ -668,6 +871,10 @@
         }
         break;
+    case TOK_ASMDIR_popsection:
+	next();
+	pop_section(s1);
+	break;
 #ifdef TCC_TARGET_I386
-    case TOK_ASM_code16:
+    case TOK_ASMDIR_code16:
         {
             next();
@@ -675,5 +882,5 @@
         }
         break;
-    case TOK_ASM_code32:
+    case TOK_ASMDIR_code32:
         {
             next();
@@ -684,5 +891,5 @@
 #ifdef TCC_TARGET_X86_64
     /* added for compatibility with GAS */
-    case TOK_ASM_code64:
+    case TOK_ASMDIR_code64:
         next();
         break;
@@ -696,51 +903,19 @@
 
 /* assemble a file */
-static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
 {
     int opcode;
-
-#if 0
-    /* print stats about opcodes */
-    {
-        const ASMInstr *pa;
-        int freq[4];
-        int op_vals[500];
-        int nb_op_vals, i, j;
-
-        nb_op_vals = 0;
-        memset(freq, 0, sizeof(freq));
-        for(pa = asm_instrs; pa->sym != 0; pa++) {
-            freq[pa->nb_ops]++;
-            for(i=0;i<pa->nb_ops;i++) {
-                for(j=0;j<nb_op_vals;j++) {
-                    if (pa->op_type[i] == op_vals[j])
-                        goto found;
-                }
-                op_vals[nb_op_vals++] = pa->op_type[i];
-            found: ;
-            }
-        }
-        for(i=0;i<nb_op_vals;i++) {
-            int v = op_vals[i];
-            if ((v & (v - 1)) != 0)
-                printf("%3d: %08x\n", i, v);
-        }
-        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
-               sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
-               freq[0], freq[1], freq[2], freq[3]);
-    }
-#endif
-
-    /* XXX: undefine C labels */
-
-    ch = file->buf_ptr[0];
-    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
-    parse_flags = PARSE_FLAG_ASM_COMMENTS;
+    int saved_parse_flags = parse_flags;
+
+    parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
     if (do_preprocess)
         parse_flags |= PARSE_FLAG_PREPROCESS;
-    next();
     for(;;) {
+        next();
         if (tok == TOK_EOF)
             break;
+        /* generate line number info */
+        if (global && s1->do_debug)
+            tcc_debug_line(s1);
         parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
     redo:
@@ -749,10 +924,10 @@
             while (tok != TOK_LINEFEED)
                 next();
-        } else if (tok == '.') {
-            asm_parse_directive(s1);
+        } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
+            asm_parse_directive(s1, global);
         } else if (tok == TOK_PPNUM) {
             const char *p;
             int n;
-            p = tokc.cstr->data;
+            p = tokc.str.data;
             n = strtoul(p, (char **)&p, 10);
             if (*p != '\0')
@@ -773,8 +948,5 @@
                 goto redo;
             } else if (tok == '=') {
-                int n;
-                next();
-                n = asm_int_expr(s1);
-                asm_new_label1(s1, opcode, 0, SHN_ABS, n);
+		set_symbol(s1, opcode);
                 goto redo;
             } else {
@@ -783,13 +955,10 @@
         }
         /* end of line */
-        if (tok != ';' && tok != TOK_LINEFEED){
+        if (tok != ';' && tok != TOK_LINEFEED)
             expect("end of line");
-        }
         parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
-        next();
-    }
-
-    asm_free_labels(s1);
-
+    }
+
+    parse_flags = saved_parse_flags;
     return 0;
 }
@@ -798,27 +967,13 @@
 ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
 {
-    Sym *define_start;
     int ret;
-
-    preprocess_init(s1);
-
+    tcc_debug_start(s1);
     /* default section is text */
     cur_text_section = text_section;
     ind = cur_text_section->data_offset;
-
-    define_start = define_stack;
-
-    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
-       symbols can be safely used */
-    put_elf_sym(symtab_section, 0, 0,
-                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
-                SHN_ABS, file->filename);
-
-    ret = tcc_assemble_internal(s1, do_preprocess);
-
+    nocode_wanted = 0;
+    ret = tcc_assemble_internal(s1, do_preprocess, 1);
     cur_text_section->data_offset = ind;
-
-    free_defines(define_start); 
-
+    tcc_debug_end(s1);
     return ret;
 }
@@ -830,20 +985,16 @@
    C preprocessing. NOTE: str is modified by modifying the '\0' at the
    end */
-static void tcc_assemble_inline(TCCState *s1, char *str, int len)
-{
-    int saved_parse_flags;
-    const int *saved_macro_ptr;
-
-    saved_parse_flags = parse_flags;
-    saved_macro_ptr = macro_ptr;
+static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
+{
+    const int *saved_macro_ptr = macro_ptr;
+    int dotid = set_idnum('.', IS_ID);
 
     tcc_open_bf(s1, ":asm:", len);
     memcpy(file->buffer, str, len);
-
     macro_ptr = NULL;
-    tcc_assemble_internal(s1, 0);
+    tcc_assemble_internal(s1, 0, global);
     tcc_close();
 
-    parse_flags = saved_parse_flags;
+    set_idnum('.', dotid);
     macro_ptr = saved_macro_ptr;
 }
@@ -891,5 +1042,4 @@
 
 static void subst_asm_operands(ASMOperand *operands, int nb_operands, 
-                               int nb_outputs,
                                CString *out_str, CString *in_str)
 {
@@ -910,5 +1060,9 @@
             modifier = 0;
             if (*str == 'c' || *str == 'n' ||
-                *str == 'b' || *str == 'w' || *str == 'h')
+                *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' ||
+		*str == 'q' ||
+		/* P in GCC would add "@PLT" to symbol refs in PIC mode,
+		   and make literal operands not be decorated with '$'.  */
+		*str == 'P')
                 modifier = *str++;
             index = find_constraint(operands, nb_operands, str, &str);
@@ -942,4 +1096,5 @@
         nb_operands = *nb_operands_ptr;
         for(;;) {
+	    CString astr;
             if (nb_operands >= MAX_ASM_OPERANDS)
                 tcc_error("too many asm operands");
@@ -954,13 +1109,13 @@
                 skip(']');
             }
-            if (tok != TOK_STR)
-                expect("string constant");
-            op->constraint = tcc_malloc(tokc.cstr->size);
-            strcpy(op->constraint, tokc.cstr->data);
-            next();
+	    parse_mult_str(&astr, "string constant");
+            op->constraint = tcc_malloc(astr.size);
+            strcpy(op->constraint, astr.data);
+	    cstr_free(&astr);
             skip('(');
             gexpr();
             if (is_output) {
-                test_lvalue();
+                if (!(vtop->type.t & VT_ARRAY))
+                    test_lvalue();
             } else {
                 /* we want to avoid LLOCAL case, except when the 'm'
@@ -1024,5 +1179,5 @@
                         if (tok != TOK_STR)
                             expect("string constant");
-                        asm_clobber(clobber_regs, tokc.cstr->data);
+                        asm_clobber(clobber_regs, tokc.str.data);
                         next();
                         if (tok == ',') {
@@ -1055,5 +1210,5 @@
 #endif
     if (must_subst) {
-        subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
+        subst_asm_operands(operands, nb_operands, &astr1, &astr);
         cstr_free(&astr);
     } else {
@@ -1069,5 +1224,5 @@
 
     /* assemble the string with tcc internal assembler */
-    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
+    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
 
     /* restore the current C token */
@@ -1091,5 +1246,8 @@
 {
     CString astr;
-
+    int saved_nocode_wanted = nocode_wanted;
+
+    /* Global asm blocks are always emitted.  */
+    nocode_wanted = 0;
     next();
     parse_asm_str(&astr);
@@ -1107,5 +1265,5 @@
 
     /* assemble the string with tcc internal assembler */
-    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
+    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
     
     cur_text_section->data_offset = ind;
@@ -1115,4 +1273,5 @@
 
     cstr_free(&astr);
+    nocode_wanted = saved_nocode_wanted;
 }
 #endif /* CONFIG_TCC_ASM */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccelf.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c	(revision 331)
@@ -1,5 +1,5 @@
 /*
  *  ELF file handling for TCC
- * 
+ *
  *  Copyright (c) 2001-2004 Fabrice Bellard
  *
@@ -21,5 +21,303 @@
 #include "tcc.h"
 
+/* Define this to get some debug output during relocation processing.  */
+#undef DEBUG_RELOC
+
+/********************************************************/
+/* global variables */
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+/* XXX: avoid static variable */
 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
+
+/* special flag to indicate that the section should not be linked to the other ones */
+#define SHF_PRIVATE 0x80000000
+/* section is dynsymtab_section */
+#define SHF_DYNSYM 0x40000000
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC void tccelf_new(TCCState *s)
+{
+    /* no section zero */
+    dynarray_add(&s->sections, &s->nb_sections, NULL);
+
+    /* create standard sections */
+    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
+    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
+    common_section->sh_num = SHN_COMMON;
+
+    /* symbols are always generated for linking stage */
+    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
+                                ".strtab",
+                                ".hashtab", SHF_PRIVATE);
+    s->symtab = symtab_section;
+
+    /* private symbol table for dynamic symbols */
+    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
+                                      ".dynstrtab",
+                                      ".dynhashtab", SHF_PRIVATE);
+    get_sym_attr(s, 0, 1);
+}
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void tccelf_bounds_new(TCCState *s)
+{
+    /* create bounds sections */
+    bounds_section = new_section(s, ".bounds",
+                                 SHT_PROGBITS, SHF_ALLOC);
+    lbounds_section = new_section(s, ".lbounds",
+                                  SHT_PROGBITS, SHF_ALLOC);
+}
+#endif
+
+ST_FUNC void tccelf_stab_new(TCCState *s)
+{
+    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
+    stab_section->sh_entsize = sizeof(Stab_Sym);
+    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
+    put_elf_str(stabstr_section, "");
+    stab_section->link = stabstr_section;
+    /* put first entry */
+    put_stabs("", 0, 0, 0, 0);
+}
+
+static void free_section(Section *s)
+{
+    tcc_free(s->data);
+}
+
+ST_FUNC void tccelf_delete(TCCState *s1)
+{
+    int i;
+
+    /* free all sections */
+    for(i = 1; i < s1->nb_sections; i++)
+        free_section(s1->sections[i]);
+    dynarray_reset(&s1->sections, &s1->nb_sections);
+
+    for(i = 0; i < s1->nb_priv_sections; i++)
+        free_section(s1->priv_sections[i]);
+    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
+
+    /* free any loaded DLLs */
+#ifdef TCC_IS_NATIVE
+    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
+        DLLReference *ref = s1->loaded_dlls[i];
+        if ( ref->handle )
+# ifdef _WIN32
+            FreeLibrary((HMODULE)ref->handle);
+# else
+            dlclose(ref->handle);
+# endif
+    }
+#endif
+    /* free loaded dlls array */
+    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
+    tcc_free(s1->sym_attrs);
+
+    symtab_section = NULL; /* for tccrun.c:rt_printline() */
+}
+
+/* save section data state */
+ST_FUNC void tccelf_begin_file(TCCState *s1)
+{
+    Section *s; int i;
+    for (i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        s->sh_offset = s->data_offset;
+    }
+    /* disable symbol hashing during compilation */
+    s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
+#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
+    s1->uw_sym = 0;
+#endif
+}
+
+/* At the end of compilation, convert any UNDEF syms to global, and merge
+   with previously existing symbols */
+ST_FUNC void tccelf_end_file(TCCState *s1)
+{
+    Section *s = s1->symtab;
+    int first_sym, nb_syms, *tr, i;
+
+    first_sym = s->sh_offset / sizeof (ElfSym);
+    nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
+    s->data_offset = s->sh_offset;
+    s->link->data_offset = s->link->sh_offset;
+    s->hash = s->reloc, s->reloc = NULL;
+    tr = tcc_mallocz(nb_syms * sizeof *tr);
+
+    for (i = 0; i < nb_syms; ++i) {
+        ElfSym *sym = (ElfSym*)s->data + first_sym + i;
+        if (sym->st_shndx == SHN_UNDEF
+            && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
+            sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
+        tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
+            sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
+    }
+    /* now update relocations */
+    for (i = 1; i < s1->nb_sections; i++) {
+        Section *sr = s1->sections[i];
+        if (sr->sh_type == SHT_RELX && sr->link == s) {
+            ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
+            ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
+            for (; rel < rel_end; ++rel) {
+                int n = ELFW(R_SYM)(rel->r_info) - first_sym;
+                //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
+                rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
+            }
+        }
+    }
+    tcc_free(tr);
+}
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
+{
+    Section *sec;
+
+    sec = tcc_mallocz(sizeof(Section) + strlen(name));
+    strcpy(sec->name, name);
+    sec->sh_type = sh_type;
+    sec->sh_flags = sh_flags;
+    switch(sh_type) {
+    case SHT_HASH:
+    case SHT_REL:
+    case SHT_RELA:
+    case SHT_DYNSYM:
+    case SHT_SYMTAB:
+    case SHT_DYNAMIC:
+        sec->sh_addralign = 4;
+        break;
+    case SHT_STRTAB:
+        sec->sh_addralign = 1;
+        break;
+    default:
+        sec->sh_addralign =  PTR_SIZE; /* gcc/pcc default alignment */
+        break;
+    }
+
+    if (sh_flags & SHF_PRIVATE) {
+        dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
+    } else {
+        sec->sh_num = s1->nb_sections;
+        dynarray_add(&s1->sections, &s1->nb_sections, sec);
+    }
+
+    return sec;
+}
+
+ST_FUNC Section *new_symtab(TCCState *s1,
+                           const char *symtab_name, int sh_type, int sh_flags,
+                           const char *strtab_name,
+                           const char *hash_name, int hash_sh_flags)
+{
+    Section *symtab, *strtab, *hash;
+    int *ptr, nb_buckets;
+
+    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
+    symtab->sh_entsize = sizeof(ElfW(Sym));
+    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
+    put_elf_str(strtab, "");
+    symtab->link = strtab;
+    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
+
+    nb_buckets = 1;
+
+    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
+    hash->sh_entsize = sizeof(int);
+    symtab->hash = hash;
+    hash->link = symtab;
+
+    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
+    ptr[0] = nb_buckets;
+    ptr[1] = 1;
+    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
+    return symtab;
+}
+
+/* realloc section and set its content to zero */
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
+{
+    unsigned long size;
+    unsigned char *data;
+
+    size = sec->data_allocated;
+    if (size == 0)
+        size = 1;
+    while (size < new_size)
+        size = size * 2;
+    data = tcc_realloc(sec->data, size);
+    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
+    sec->data = data;
+    sec->data_allocated = size;
+}
+
+/* reserve at least 'size' bytes aligned per 'align' in section
+   'sec' from current offset, and return the aligned offset */
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
+{
+    size_t offset, offset1;
+
+    offset = (sec->data_offset + align - 1) & -align;
+    offset1 = offset + size;
+    if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
+        section_realloc(sec, offset1);
+    sec->data_offset = offset1;
+    if (align > sec->sh_addralign)
+        sec->sh_addralign = align;
+    return offset;
+}
+
+/* reserve at least 'size' bytes in section 'sec' from
+   sec->data_offset. */
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
+{
+    size_t offset = section_add(sec, size, 1);
+    return sec->data + offset;
+}
+
+/* reserve at least 'size' bytes from section start */
+ST_FUNC void section_reserve(Section *sec, unsigned long size)
+{
+    if (size > sec->data_allocated)
+        section_realloc(sec, size);
+    if (size > sec->data_offset)
+        sec->data_offset = size;
+}
+
+/* return a reference to a section, and create it if it does not
+   exists */
+ST_FUNC Section *find_section(TCCState *s1, const char *name)
+{
+    Section *sec;
+    int i;
+    for(i = 1; i < s1->nb_sections; i++) {
+        sec = s1->sections[i];
+        if (!strcmp(name, sec->name))
+            return sec;
+    }
+    /* sections are created as PROGBITS */
+    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
+}
+
+/* ------------------------------------------------------------------------- */
 
 ST_FUNC int put_elf_str(Section *s, const char *sym)
@@ -31,5 +329,5 @@
     offset = s->data_offset;
     ptr = section_ptr_add(s, len);
-    memcpy(ptr, sym, len);
+    memmove(ptr, sym, len);
     return offset;
 }
@@ -39,5 +337,5 @@
 {
     unsigned long h = 0, g;
-    
+
     while (*name) {
         h = (h << 4) + *name++;
@@ -56,8 +354,11 @@
     ElfW(Sym) *sym;
     int *ptr, *hash, nb_syms, sym_index, h;
-    char *strtab;
+    unsigned char *strtab;
 
     strtab = s->link->data;
     nb_syms = s->data_offset / sizeof(ElfW(Sym));
+
+    if (!nb_buckets)
+        nb_buckets = ((int*)s->hash->data)[0];
 
     s->hash->data_offset = 0;
@@ -92,7 +393,7 @@
     ElfW(Sym) *sym;
     Section *hs;
-    
+
     sym = section_ptr_add(s, sizeof(ElfW(Sym)));
-    if (name)
+    if (name && name[0])
         name_offset = put_elf_str(s->link, name);
     else
@@ -111,9 +412,9 @@
         ptr = section_ptr_add(hs, sizeof(int));
         base = (int *)hs->data;
-        /* only add global or weak symbols */
+        /* only add global or weak symbols. */
         if (ELFW(ST_BIND)(info) != STB_LOCAL) {
             /* add another hashing entry */
             nbuckets = base[0];
-            h = elf_hash(name) % nbuckets;
+            h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
             *ptr = base[2 + h];
             base[2 + h] = sym_index;
@@ -132,6 +433,4 @@
 }
 
-/* find global ELF symbol 'name' and return its index. Return 0 if not
-   found. */
 ST_FUNC int find_elf_sym(Section *s, const char *name)
 {
@@ -140,14 +439,14 @@
     int nbuckets, sym_index, h;
     const char *name1;
-    
+
     hs = s->hash;
     if (!hs)
         return 0;
     nbuckets = ((int *)hs->data)[0];
-    h = elf_hash(name) % nbuckets;
+    h = elf_hash((unsigned char *) name) % nbuckets;
     sym_index = ((int *)hs->data)[2 + h];
     while (sym_index != 0) {
         sym = &((ElfW(Sym) *)s->data)[sym_index];
-        name1 = s->link->data + sym->st_name;
+        name1 = (char *) s->link->data + sym->st_name;
         if (!strcmp(name, name1))
             return sym_index;
@@ -179,9 +478,9 @@
 }
 
-#ifdef TCC_IS_NATIVE
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
 /* return elf symbol value or error */
 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
 {
-    return (void*)get_elf_sym_addr(s, name, 1);
+    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
 }
 #endif
@@ -189,6 +488,6 @@
 /* add an elf symbol : check if it is already defined and patch
    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
-ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
-                       int info, int other, int sh_num, const char *name)
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
+                       int info, int other, int shndx, const char *name)
 {
     ElfW(Sym) *esym;
@@ -199,5 +498,5 @@
     sym_type = ELFW(ST_TYPE)(info);
     sym_vis = ELFW(ST_VISIBILITY)(other);
-        
+
     if (sym_bind != STB_LOCAL) {
         /* we search global or weak symbols */
@@ -206,4 +505,7 @@
             goto do_def;
         esym = &((ElfW(Sym) *)s->data)[sym_index];
+        if (esym->st_value == value && esym->st_size == size && esym->st_info == info
+            && esym->st_other == other && esym->st_shndx == shndx)
+            return sym_index;
         if (esym->st_shndx != SHN_UNDEF) {
             esym_bind = ELFW(ST_BIND)(esym->st_info);
@@ -221,5 +523,5 @@
                              | new_vis;
             other = esym->st_other; /* in case we have to patch esym */
-            if (sh_num == SHN_UNDEF) {
+            if (shndx == SHN_UNDEF) {
                 /* ignore adding of undefined symbol if the
                    corresponding symbol is already defined */
@@ -233,15 +535,22 @@
             } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
                 /* ignore hidden symbols after */
-            } else if (esym->st_shndx == SHN_COMMON
-                    && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
-                /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
-                   No idea if this is the correct solution ... */
+            } else if ((esym->st_shndx == SHN_COMMON
+                            || esym->st_shndx == bss_section->sh_num)
+                        && (shndx < SHN_LORESERVE
+                            && shndx != bss_section->sh_num)) {
+                /* data symbol gets precedence over common/bss */
                 goto do_patch;
-            } else if (s == tcc_state->dynsymtab_section) {
+            } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
+                /* data symbol keeps precedence over common/bss */
+            } else if (s->sh_flags & SHF_DYNSYM) {
                 /* we accept that two DLL define the same symbol */
+	    } else if (esym->st_other & ST_ASM_SET) {
+		/* If the existing symbol came from an asm .set
+		   we can override.  */
+		goto do_patch;
             } else {
 #if 0
                 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
-                       sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
+                       sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
 #endif
                 tcc_error_noabort("'%s' defined twice", name);
@@ -250,5 +559,5 @@
         do_patch:
             esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
-            esym->st_shndx = sh_num;
+            esym->st_shndx = shndx;
             new_undef_sym = 1;
             esym->st_value = value;
@@ -258,7 +567,7 @@
     } else {
     do_def:
-        sym_index = put_elf_sym(s, value, size, 
-                                ELFW(ST_INFO)(sym_bind, sym_type), other, 
-                                sh_num, name);
+        sym_index = put_elf_sym(s, value, size,
+                                ELFW(ST_INFO)(sym_bind, sym_type), other,
+                                shndx, name);
     }
     return sym_index;
@@ -266,6 +575,6 @@
 
 /* put relocation */
-ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
-                          int type, int symbol)
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
+                            int type, int symbol, addr_t addend)
 {
     char buf[256];
@@ -288,7 +597,53 @@
     rel->r_offset = offset;
     rel->r_info = ELFW(R_INFO)(symbol, type);
-#ifdef TCC_TARGET_X86_64
-    rel->r_addend = 0;
-#endif
+#if SHT_RELX == SHT_RELA
+    rel->r_addend = addend;
+#else
+    if (addend)
+        tcc_error("non-zero addend on REL architecture");
+#endif
+}
+
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+                           int type, int symbol)
+{
+    put_elf_reloca(symtab, s, offset, type, symbol, 0);
+}
+
+/* Remove relocations for section S->reloc starting at oldrelocoffset
+   that are to the same place, retaining the last of them.  As side effect
+   the relocations are sorted.  Possibly reduces the number of relocs.  */
+ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
+{
+    Section *sr = s->reloc;
+    ElfW_Rel *r, *dest;
+    ssize_t a;
+    ElfW(Addr) addr;
+
+    if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
+      return;
+    /* The relocs we're dealing with are the result of initializer parsing.
+       So they will be mostly in order and there aren't many of them.
+       Secondly we need a stable sort (which qsort isn't).  We use
+       a simple insertion sort.  */
+    for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
+	ssize_t i = a - sizeof(*r);
+	addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
+	for (; i >= (ssize_t)oldrelocoffset &&
+	       ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
+	    ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
+	    *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
+	    *(ElfW_Rel*)(sr->data + i) = tmp;
+	}
+    }
+
+    r = (ElfW_Rel*)(sr->data + oldrelocoffset);
+    dest = r;
+    for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
+	if (dest->r_offset != r->r_offset)
+	  dest++;
+	*dest = *r;
+    }
+    sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
 }
 
@@ -312,9 +667,9 @@
 }
 
-ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, 
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
                         unsigned long value, Section *sec, int sym_index)
 {
     put_stabs(str, type, other, desc, value);
-    put_elf_reloc(symtab_section, stab_section, 
+    put_elf_reloc(symtab_section, stab_section,
                   stab_section->data_offset - sizeof(unsigned int),
                   R_DATA_32, sym_index);
@@ -331,622 +686,5 @@
 }
 
-/* In an ELF file symbol table, the local symbols must appear below
-   the global and weak ones. Since TCC cannot sort it while generating
-   the code, we must do it after. All the relocation tables are also
-   modified to take into account the symbol table sorting */
-static void sort_syms(TCCState *s1, Section *s)
-{
-    int *old_to_new_syms;
-    ElfW(Sym) *new_syms;
-    int nb_syms, i;
-    ElfW(Sym) *p, *q;
-    ElfW_Rel *rel, *rel_end;
-    Section *sr;
-    int type, sym_index;
-
-    nb_syms = s->data_offset / sizeof(ElfW(Sym));
-    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
-    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
-
-    /* first pass for local symbols */
-    p = (ElfW(Sym) *)s->data;
-    q = new_syms;
-    for(i = 0; i < nb_syms; i++) {
-        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
-            old_to_new_syms[i] = q - new_syms;
-            *q++ = *p;
-        }
-        p++;
-    }
-    /* save the number of local symbols in section header */
-    s->sh_info = q - new_syms;
-
-    /* then second pass for non local symbols */
-    p = (ElfW(Sym) *)s->data;
-    for(i = 0; i < nb_syms; i++) {
-        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
-            old_to_new_syms[i] = q - new_syms;
-            *q++ = *p;
-        }
-        p++;
-    }
-    
-    /* we copy the new symbols to the old */
-    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
-    tcc_free(new_syms);
-
-    /* now we modify all the relocations */
-    for(i = 1; i < s1->nb_sections; i++) {
-        sr = s1->sections[i];
-        if (sr->sh_type == SHT_RELX && sr->link == s) {
-            rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-            for(rel = (ElfW_Rel *)sr->data;
-                rel < rel_end;
-                rel++) {
-                sym_index = ELFW(R_SYM)(rel->r_info);
-                type = ELFW(R_TYPE)(rel->r_info);
-                sym_index = old_to_new_syms[sym_index];
-                rel->r_info = ELFW(R_INFO)(sym_index, type);
-            }
-        }
-    }
-    
-    tcc_free(old_to_new_syms);
-}
-
-/* relocate common symbols in the .bss section */
-ST_FUNC void relocate_common_syms(void)
-{
-    ElfW(Sym) *sym, *sym_end;
-    unsigned long offset, align;
-    
-    sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
-    for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
-        sym < sym_end;
-        sym++) {
-        if (sym->st_shndx == SHN_COMMON) {
-            /* align symbol */
-            align = sym->st_value;
-            offset = bss_section->data_offset;
-            offset = (offset + align - 1) & -align;
-            sym->st_value = offset;
-            sym->st_shndx = bss_section->sh_num;
-            offset += sym->st_size;
-            bss_section->data_offset = offset;
-        }
-    }
-}
-
-/* relocate symbol table, resolve undefined symbols if do_resolve is
-   true and output error if undefined symbol. */
-ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
-{
-    ElfW(Sym) *sym, *esym, *sym_end;
-    int sym_bind, sh_num, sym_index;
-    const char *name;
-
-    sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
-    for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
-        sym < sym_end;
-        sym++) {
-        sh_num = sym->st_shndx;
-        if (sh_num == SHN_UNDEF) {
-            name = strtab_section->data + sym->st_name;
-            if (do_resolve) {
-#if defined TCC_IS_NATIVE && !defined _WIN32
-                void *addr;
-                name = symtab_section->link->data + sym->st_name;
-                addr = resolve_sym(s1, name);
-                if (addr) {
-                    sym->st_value = (addr_t)addr;
-                    goto found;
-                }
-#endif
-            } else if (s1->dynsym) {
-                /* if dynamic symbol exist, then use it */
-                sym_index = find_elf_sym(s1->dynsym, name);
-                if (sym_index) {
-                    esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
-                    sym->st_value = esym->st_value;
-                    goto found;
-                }
-            }
-            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
-               it */
-            if (!strcmp(name, "_fp_hw"))
-                goto found;
-            /* only weak symbols are accepted to be undefined. Their
-               value is zero */
-            sym_bind = ELFW(ST_BIND)(sym->st_info);
-            if (sym_bind == STB_WEAK) {
-                sym->st_value = 0;
-            } else {
-                tcc_error_noabort("undefined symbol '%s'", name);
-            }
-        } else if (sh_num < SHN_LORESERVE) {
-            /* add section base */
-            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
-        }
-    found: ;
-    }
-}
-
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-#ifdef TCC_TARGET_X86_64
-#define JMP_TABLE_ENTRY_SIZE 14
-static addr_t add_jmp_table(TCCState *s1, addr_t val)
-{
-    char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
-    s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
-    /* jmp *0x0(%rip) */
-    p[0] = 0xff;
-    p[1] = 0x25;
-    *(int *)(p + 2) = 0;
-    *(addr_t *)(p + 6) = val;
-    return (addr_t)p;
-}
-
-static addr_t add_got_table(TCCState *s1, addr_t val)
-{
-    addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
-    s1->runtime_plt_and_got_offset += sizeof(addr_t);
-    *p = val;
-    return (addr_t)p;
-}
-#elif defined TCC_TARGET_ARM
-#define JMP_TABLE_ENTRY_SIZE 8
-static addr_t add_jmp_table(TCCState *s1, int val)
-{
-    uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
-    s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
-    /* ldr pc, [pc, #-4] */
-    p[0] = 0xE51FF004;
-    p[1] = val;
-    return (addr_t)p;
-}
-#endif
-#endif /* def TCC_HAS_RUNTIME_PLTGOT */
-
-/* relocate a given section (CPU dependent) */
-ST_FUNC void relocate_section(TCCState *s1, Section *s)
-{
-    Section *sr;
-    ElfW_Rel *rel, *rel_end, *qrel;
-    ElfW(Sym) *sym;
-    int type, sym_index;
-    unsigned char *ptr;
-    addr_t val, addr;
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-    int esym_index;
-#endif
-
-    sr = s->reloc;
-    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-    qrel = (ElfW_Rel *)sr->data;
-    for(rel = qrel;
-        rel < rel_end;
-        rel++) {
-        ptr = s->data + rel->r_offset;
-
-        sym_index = ELFW(R_SYM)(rel->r_info);
-        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-        val = sym->st_value;
-#ifdef TCC_TARGET_X86_64
-        val += rel->r_addend;
-#endif
-        type = ELFW(R_TYPE)(rel->r_info);
-        addr = s->sh_addr + rel->r_offset;
-
-        /* CPU specific */
-        switch(type) {
-#if defined(TCC_TARGET_I386)
-        case R_386_32:
-            if (s1->output_type == TCC_OUTPUT_DLL) {
-                esym_index = s1->symtab_to_dynsym[sym_index];
-                qrel->r_offset = rel->r_offset;
-                if (esym_index) {
-                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
-                    qrel++;
-                    break;
-                } else {
-                    qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
-                    qrel++;
-                }
-            }
-            *(int *)ptr += val;
-            break;
-        case R_386_PC32:
-            if (s1->output_type == TCC_OUTPUT_DLL) {
-                /* DLL relocation */
-                esym_index = s1->symtab_to_dynsym[sym_index];
-                if (esym_index) {
-                    qrel->r_offset = rel->r_offset;
-                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
-                    qrel++;
-                    break;
-                }
-            }
-            *(int *)ptr += val - addr;
-            break;
-        case R_386_PLT32:
-            *(int *)ptr += val - addr;
-            break;
-        case R_386_GLOB_DAT:
-        case R_386_JMP_SLOT:
-            *(int *)ptr = val;
-            break;
-        case R_386_GOTPC:
-            *(int *)ptr += s1->got->sh_addr - addr;
-            break;
-        case R_386_GOTOFF:
-            *(int *)ptr += val - s1->got->sh_addr;
-            break;
-        case R_386_GOT32:
-            /* we load the got offset */
-            *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
-            break;
-        case R_386_16:
-            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
-            output_file:
-            tcc_error("can only produce 16-bit binary files");
-            }
-            *(short *)ptr += val;
-            break;
-        case R_386_PC16:
-            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
-            goto output_file;
-            *(short *)ptr += val - addr;
-            break;
-#elif defined(TCC_TARGET_ARM)
-        case R_ARM_PC24:
-        case R_ARM_CALL:
-        case R_ARM_JUMP24:
-        case R_ARM_PLT32:
-            {
-                int x, is_thumb, is_call, h, blx_avail;
-                x = (*(int *)ptr)&0xffffff;
-                (*(int *)ptr) &= 0xff000000;
-                if (x & 0x800000)
-                    x -= 0x1000000;
-                x <<= 2;
-                blx_avail = (TCC_ARM_VERSION >= 5);
-                is_thumb = val & 1;
-                is_call = (type == R_ARM_CALL);
-                x += val - addr;
-                h = x & 2;
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-                if (s1->output_type == TCC_OUTPUT_MEMORY) {
-                    if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
-                        if (!(x & 3) || !blx_avail || !is_call) {
-                            x += add_jmp_table(s1, val) - val; /* add veneer */
-                            is_thumb = 0; /* Veneer uses ARM instructions */
-                        }
-                }
-#endif
-                if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
-                    if (!(x & 3) || !blx_avail || !is_call)
-                        tcc_error("can't relocate value at %x",addr);
-                x >>= 2;
-                x &= 0xffffff;
-                /* Only reached if blx is avail and it is a call */
-                if (is_thumb) {
-                    x |= h << 24;
-                    (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
-                }
-                (*(int *)ptr) |= x;
-            }
-            break;
-        /* Since these relocations only concern Thumb-2 and blx instruction was
-           introduced before Thumb-2, we can assume blx is available and not
-           guard its use */
-        case R_ARM_THM_CALL:
-        case R_ARM_THM_JUMP24:
-	    {
-                int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
-                int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
-                Section *plt;
-
-                /* weak reference */
-                if (sym->st_shndx == SHN_UNDEF &&
-                    ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
-                    break;
-
-                /* Get initial offset */
-                hi = (*(uint16_t *)ptr);
-                lo = (*(uint16_t *)(ptr+2));
-                s = (hi >> 10) & 1;
-                j1 = (lo >> 13) & 1;
-                j2 = (lo >> 11) & 1;
-                i1 = (j1 ^ s) ^ 1;
-                i2 = (j2 ^ s) ^ 1;
-                imm10 = hi & 0x3ff;
-                imm11 = lo & 0x7ff;
-                x = (s << 24) | (i1 << 23) | (i2 << 22) |
-                    (imm10 << 12) | (imm11 << 1);
-                if (x & 0x01000000)
-                    x -= 0x02000000;
-
-                /* Relocation infos */
-                to_thumb = val & 1;
-                plt = s1->plt;
-                to_plt = (val >= plt->sh_addr) &&
-                         (val < plt->sh_addr + plt->data_offset);
-                is_call = (type == R_ARM_THM_CALL);
-
-                /* Compute final offset */
-                if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
-                    x -= 4;
-                x += val - addr;
-                if (!to_thumb && is_call) {
-                    blx_bit = 0; /* bl -> blx */
-                    x = (x + 3) & -4; /* Compute offset from aligned PC */
-                }
-
-                /* Check that relocation is possible
-                   * offset must not be out of range
-                   * if target is to be entered in arm mode:
-                     - bit 1 must not set
-                     - instruction must be a call (bl) or a jump to PLT */
-                if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
-                    if (to_thumb || (val & 2) || (!is_call && !to_plt))
-                        tcc_error("can't relocate value at %x",addr);
-
-                /* Compute and store final offset */
-                s = (x >> 24) & 1;
-                i1 = (x >> 23) & 1;
-                i2 = (x >> 22) & 1;
-                j1 = s ^ (i1 ^ 1);
-                j2 = s ^ (i2 ^ 1);
-                imm10 = (x >> 12) & 0x3ff;
-                imm11 = (x >> 1) & 0x7ff;
-                (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
-                                     (s << 10) | imm10);
-                (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
-                                (j1 << 13) | blx_bit | (j2 << 11) |
-                                imm11);
-            }
-            break;
-        case R_ARM_MOVT_ABS:
-        case R_ARM_MOVW_ABS_NC:
-            {
-                int x, imm4, imm12;
-                if (type == R_ARM_MOVT_ABS)
-                    val >>= 16;
-                imm12 = val & 0xfff;
-                imm4 = (val >> 12) & 0xf;
-                x = (imm4 << 16) | imm12;
-                if (type == R_ARM_THM_MOVT_ABS)
-                    *(int *)ptr |= x;
-                else
-                    *(int *)ptr += x;
-        }
-            break;
-        case R_ARM_THM_MOVT_ABS:
-        case R_ARM_THM_MOVW_ABS_NC:
-            {
-                int x, i, imm4, imm3, imm8;
-                if (type == R_ARM_THM_MOVT_ABS)
-                    val >>= 16;
-                imm8 = val & 0xff;
-                imm3 = (val >> 8) & 0x7;
-                i = (val >> 11) & 1;
-                imm4 = (val >> 12) & 0xf;
-                x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
-                if (type == R_ARM_THM_MOVT_ABS)
-                    *(int *)ptr |= x;
-                else
-                    *(int *)ptr += x;
-        }
-            break;
-        case R_ARM_PREL31:
-            {
-                int x;
-                x = (*(int *)ptr) & 0x7fffffff;
-                (*(int *)ptr) &= 0x80000000;
-                x = (x * 2) / 2;
-                x += val - addr;
-                if((x^(x>>1))&0x40000000)
-                    tcc_error("can't relocate value at %x",addr);
-                (*(int *)ptr) |= x & 0x7fffffff;
-            }
-        case R_ARM_ABS32:
-            *(int *)ptr += val;
-            break;
-        case R_ARM_REL32:
-            *(int *)ptr += val - addr;
-            break;
-        case R_ARM_BASE_PREL:
-            *(int *)ptr += s1->got->sh_addr - addr;
-            break;
-        case R_ARM_GOTOFF32:
-            *(int *)ptr += val - s1->got->sh_addr;
-            break;
-        case R_ARM_GOT_BREL:
-            /* we load the got offset */
-            *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
-            break;
-        case R_ARM_COPY:
-            break;
-        case R_ARM_V4BX:
-            /* trade Thumb support for ARMv4 support */
-            if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
-                *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
-            break;
-        default:
-            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
-                type, (unsigned)addr, ptr, (unsigned)val);
-            break;
-#elif defined(TCC_TARGET_C67)
-        case R_C60_32:
-            *(int *)ptr += val;
-            break;
-        case R_C60LO16:
-            {
-                uint32_t orig;
-                
-                /* put the low 16 bits of the absolute address */
-                // add to what is already there
-                
-                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
-                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
-                
-                //patch both at once - assumes always in pairs Low - High
-                
-                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
-                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
-            }
-            break;
-        case R_C60HI16:
-            break;
-        default:
-            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
-                type, (unsigned)addr, ptr, (unsigned)val);
-            break;
-#elif defined(TCC_TARGET_X86_64)
-        case R_X86_64_64:
-            if (s1->output_type == TCC_OUTPUT_DLL) {
-                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
-                qrel->r_addend = *(long long *)ptr + val;
-                qrel++;
-            }
-            *(long long *)ptr += val;
-            break;
-        case R_X86_64_32:
-        case R_X86_64_32S:
-            if (s1->output_type == TCC_OUTPUT_DLL) {
-                /* XXX: this logic may depend on TCC's codegen
-                   now TCC uses R_X86_64_32 even for a 64bit pointer */
-                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
-                qrel->r_addend = *(int *)ptr + val;
-                qrel++;
-            }
-            *(int *)ptr += val;
-            break;
-
-        case R_X86_64_PC32:
-            if (s1->output_type == TCC_OUTPUT_DLL) {
-                /* DLL relocation */
-                esym_index = s1->symtab_to_dynsym[sym_index];
-                if (esym_index) {
-                    qrel->r_offset = rel->r_offset;
-                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
-                    qrel->r_addend = *(int *)ptr;
-                    qrel++;
-                    break;
-                }
-            }
-            /* fall through */
-        case R_X86_64_PLT32: {
-            long long diff;
-            diff = (long long)val - addr;
-            if (diff <= -2147483647 || diff > 2147483647) {
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-                /* XXX: naive support for over 32bit jump */
-                if (s1->output_type == TCC_OUTPUT_MEMORY) {
-                    val = (add_jmp_table(s1, val - rel->r_addend) +
-                           rel->r_addend);
-                    diff = val - addr;
-                }
-#endif
-                if (diff <= -2147483647 || diff > 2147483647) {
-                    tcc_error("internal error: relocation failed");
-                }
-            }
-            *(int *)ptr += diff;
-        }
-            break;
-        case R_X86_64_GLOB_DAT:
-        case R_X86_64_JUMP_SLOT:
-            /* They don't need addend */
-            *(int *)ptr = val - rel->r_addend;
-            break;
-        case R_X86_64_GOTPCREL:
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-            if (s1->output_type == TCC_OUTPUT_MEMORY) {
-                val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
-                *(int *)ptr += val - addr;
-                break;
-            }
-#endif
-            *(int *)ptr += (s1->got->sh_addr - addr +
-                            s1->sym_attrs[sym_index].got_offset - 4);
-            break;
-        case R_X86_64_GOTTPOFF:
-            *(int *)ptr += val - s1->got->sh_addr;
-            break;
-        case R_X86_64_GOT32:
-            /* we load the got offset */
-            *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
-            break;
-#elif  defined(TCC_TARGET_IL)
-#else
-#error unsupported processor
-#endif
-        }
-    }
-    /* if the relocation is allocated, we change its symbol table */
-    if (sr->sh_flags & SHF_ALLOC)
-        sr->link = s1->dynsym;
-}
-
-/* relocate relocation table in 'sr' */
-static void relocate_rel(TCCState *s1, Section *sr)
-{
-    Section *s;
-    ElfW_Rel *rel, *rel_end;
-    
-    s = s1->sections[sr->sh_info];
-    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-    for(rel = (ElfW_Rel *)sr->data;
-        rel < rel_end;
-        rel++) {
-        rel->r_offset += s->sh_addr;
-    }
-}
-
-/* count the number of dynamic relocations so that we can reserve
-   their space */
-static int prepare_dynamic_rel(TCCState *s1, Section *sr)
-{
-    ElfW_Rel *rel, *rel_end;
-    int sym_index, esym_index, type, count;
-
-    count = 0;
-    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-    for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
-        sym_index = ELFW(R_SYM)(rel->r_info);
-        type = ELFW(R_TYPE)(rel->r_info);
-        switch(type) {
-#if defined(TCC_TARGET_I386)
-        case R_386_32:
-#elif defined(TCC_TARGET_X86_64)
-        case R_X86_64_32:
-        case R_X86_64_32S:
-        case R_X86_64_64:
-#endif
-            count++;
-            break;
-#if defined(TCC_TARGET_I386)
-        case R_386_PC32:
-#elif defined(TCC_TARGET_X86_64)
-        case R_X86_64_PC32:
-#endif
-            esym_index = s1->symtab_to_dynsym[sym_index];
-            if (esym_index)
-                count++;
-            break;
-        default:
-            break;
-        }
-    }
-    if (count) {
-        /* allocate the section */
-        sr->sh_flags |= SHF_ALLOC;
-        sr->sh_size = count * sizeof(ElfW_Rel);
-    }
-    return count;
-}
-
-static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
 {
     int n;
@@ -954,4 +692,6 @@
 
     if (index >= s1->nb_sym_attrs) {
+        if (!alloc)
+            return s1->sym_attrs;
         /* find immediately bigger power of 2 and reallocate array */
         n = 1;
@@ -967,179 +707,310 @@
 }
 
-/* XXX: suppress that */
-static void put32(unsigned char *p, uint32_t val)
-{
-    p[0] = val;
-    p[1] = val >> 8;
-    p[2] = val >> 16;
-    p[3] = val >> 24;
-}
-
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
-    defined(TCC_TARGET_X86_64)
-static uint32_t get32(unsigned char *p)
-{
-    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-}
-#endif
+/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
+   using variable <elem> */
+#define for_each_elem(sec, startoff, elem, type) \
+    for (elem = (type *) sec->data + startoff; \
+         elem < (type *) (sec->data + sec->data_offset); elem++)
+
+/* In an ELF file symbol table, the local symbols must appear below
+   the global and weak ones. Since TCC cannot sort it while generating
+   the code, we must do it after. All the relocation tables are also
+   modified to take into account the symbol table sorting */
+static void sort_syms(TCCState *s1, Section *s)
+{
+    int *old_to_new_syms;
+    ElfW(Sym) *new_syms;
+    int nb_syms, i;
+    ElfW(Sym) *p, *q;
+    ElfW_Rel *rel;
+    Section *sr;
+    int type, sym_index;
+
+    nb_syms = s->data_offset / sizeof(ElfW(Sym));
+    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
+    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
+
+    /* first pass for local symbols */
+    p = (ElfW(Sym) *)s->data;
+    q = new_syms;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+    /* save the number of local symbols in section header */
+    if( s->sh_size )    /* this 'if' makes IDA happy */
+        s->sh_info = q - new_syms;
+
+    /* then second pass for non local symbols */
+    p = (ElfW(Sym) *)s->data;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+
+    /* we copy the new symbols to the old */
+    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
+    tcc_free(new_syms);
+
+    /* now we modify all the relocations */
+    for(i = 1; i < s1->nb_sections; i++) {
+        sr = s1->sections[i];
+        if (sr->sh_type == SHT_RELX && sr->link == s) {
+            for_each_elem(sr, 0, rel, ElfW_Rel) {
+                sym_index = ELFW(R_SYM)(rel->r_info);
+                type = ELFW(R_TYPE)(rel->r_info);
+                sym_index = old_to_new_syms[sym_index];
+                rel->r_info = ELFW(R_INFO)(sym_index, type);
+            }
+        }
+    }
+
+    tcc_free(old_to_new_syms);
+}
+
+/* relocate symbol table, resolve undefined symbols if do_resolve is
+   true and output error if undefined symbol. */
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
+{
+    ElfW(Sym) *sym;
+    int sym_bind, sh_num;
+    const char *name;
+
+    for_each_elem(symtab, 1, sym, ElfW(Sym)) {
+        sh_num = sym->st_shndx;
+        if (sh_num == SHN_UNDEF) {
+            name = (char *) s1->symtab->link->data + sym->st_name;
+            /* Use ld.so to resolve symbol for us (for tcc -run) */
+            if (do_resolve) {
+#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
+                void *addr = dlsym(RTLD_DEFAULT, name);
+                if (addr) {
+                    sym->st_value = (addr_t) addr;
+#ifdef DEBUG_RELOC
+		    printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
+#endif
+                    goto found;
+                }
+#endif
+            /* if dynamic symbol exist, it will be used in relocate_section */
+            } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
+                goto found;
+            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
+               it */
+            if (!strcmp(name, "_fp_hw"))
+                goto found;
+            /* only weak symbols are accepted to be undefined. Their
+               value is zero */
+            sym_bind = ELFW(ST_BIND)(sym->st_info);
+            if (sym_bind == STB_WEAK)
+                sym->st_value = 0;
+            else
+                tcc_error_noabort("undefined symbol '%s'", name);
+        } else if (sh_num < SHN_LORESERVE) {
+            /* add section base */
+            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+        }
+    found: ;
+    }
+}
+
+/* relocate a given section (CPU dependent) by applying the relocations
+   in the associated relocation section */
+ST_FUNC void relocate_section(TCCState *s1, Section *s)
+{
+    Section *sr = s->reloc;
+    ElfW_Rel *rel;
+    ElfW(Sym) *sym;
+    int type, sym_index;
+    unsigned char *ptr;
+    addr_t tgt, addr;
+
+    relocate_init(sr);
+
+    for_each_elem(sr, 0, rel, ElfW_Rel) {
+        ptr = s->data + rel->r_offset;
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        type = ELFW(R_TYPE)(rel->r_info);
+        tgt = sym->st_value;
+#if SHT_RELX == SHT_RELA
+        tgt += rel->r_addend;
+#endif
+        addr = s->sh_addr + rel->r_offset;
+        relocate(s1, rel, type, ptr, addr, tgt);
+    }
+    /* if the relocation is allocated, we change its symbol table */
+    if (sr->sh_flags & SHF_ALLOC)
+        sr->link = s1->dynsym;
+}
+
+/* relocate relocation table in 'sr' */
+static void relocate_rel(TCCState *s1, Section *sr)
+{
+    Section *s;
+    ElfW_Rel *rel;
+
+    s = s1->sections[sr->sh_info];
+    for_each_elem(sr, 0, rel, ElfW_Rel)
+        rel->r_offset += s->sh_addr;
+}
+
+/* count the number of dynamic relocations so that we can reserve
+   their space */
+static int prepare_dynamic_rel(TCCState *s1, Section *sr)
+{
+    ElfW_Rel *rel;
+    int sym_index, type, count;
+
+    count = 0;
+    for_each_elem(sr, 0, rel, ElfW_Rel) {
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        type = ELFW(R_TYPE)(rel->r_info);
+        switch(type) {
+#if defined(TCC_TARGET_I386)
+        case R_386_32:
+            if (!get_sym_attr(s1, sym_index, 0)->dyn_index
+                && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
+                /* don't fixup unresolved (weak) symbols */
+                rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
+                break;
+            }
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+#endif
+            count++;
+            break;
+#if defined(TCC_TARGET_I386)
+        case R_386_PC32:
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_PC32:
+#endif
+            if (get_sym_attr(s1, sym_index, 0)->dyn_index)
+                count++;
+            break;
+        default:
+            break;
+        }
+    }
+    if (count) {
+        /* allocate the section */
+        sr->sh_flags |= SHF_ALLOC;
+        sr->sh_size = count * sizeof(ElfW_Rel);
+    }
+    return count;
+}
 
 static void build_got(TCCState *s1)
 {
-    unsigned char *ptr;
-
     /* if no got, then create it */
     s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
     s1->got->sh_entsize = 4;
-    add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 
+    set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
                 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
-    ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
-#if PTR_SIZE == 4
-    /* keep space for _DYNAMIC pointer, if present */
-    put32(ptr, 0);
-    /* two dummy got entries */
-    put32(ptr + 4, 0);
-    put32(ptr + 8, 0);
-#else
-    /* keep space for _DYNAMIC pointer, if present */
-    put32(ptr, 0);
-    put32(ptr + 4, 0);
-    /* two dummy got entries */
-    put32(ptr + 8, 0);
-    put32(ptr + 12, 0);
-    put32(ptr + 16, 0);
-    put32(ptr + 20, 0);
-#endif
-}
-
-/* put a got entry corresponding to a symbol in symtab_section. 'size'
-   and 'info' can be modifed if more precise info comes from the DLL */
-static void put_got_entry(TCCState *s1,
-                          int reloc_type, unsigned long size, int info, 
-                          int sym_index)
-{
-    int index;
+    /* keep space for _DYNAMIC pointer and two dummy got entries */
+    section_ptr_add(s1->got, 3 * PTR_SIZE);
+}
+
+/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
+   in s1->symtab. When creating the dynamic symbol table entry for the GOT
+   relocation, use 'size' and 'info' for the corresponding symbol metadata.
+   Returns the offset of the GOT or (if any) PLT entry. */
+static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
+                                       unsigned long size,
+                                       int info, int sym_index)
+{
+    int need_plt_entry;
     const char *name;
     ElfW(Sym) *sym;
-    unsigned long offset;
-    int *ptr;
-
-    if (!s1->got)
-        build_got(s1);
-
-    /* if a got entry already exists for that symbol, no need to add one */
-    if (sym_index < s1->nb_sym_attrs &&
-        s1->sym_attrs[sym_index].got_offset)
-        return;
-
-    alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
+    struct sym_attr *attr;
+    unsigned got_offset;
+    char plt_name[100];
+    int len;
+
+    need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
+    attr = get_sym_attr(s1, sym_index, 1);
+
+    /* In case a function is both called and its address taken 2 GOT entries
+       are created, one for taking the address (GOT) and the other for the PLT
+       entry (PLTGOT).  */
+    if (need_plt_entry ? attr->plt_offset : attr->got_offset)
+        return attr;
+
+    /* create the GOT entry */
+    got_offset = s1->got->data_offset;
+    section_ptr_add(s1->got, PTR_SIZE);
+
+    /* Create the GOT relocation that will insert the address of the object or
+       function of interest in the GOT entry. This is a static relocation for
+       memory output (dlsym will give us the address of symbols) and dynamic
+       relocation otherwise (executable and DLLs). The relocation should be
+       done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
+       associated to a PLT entry) but is currently done at load time for an
+       unknown reason. */
+
+    sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+    name = (char *) symtab_section->link->data + sym->st_name;
 
     if (s1->dynsym) {
-        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-        name = symtab_section->link->data + sym->st_name;
-        offset = sym->st_value;
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
-        if (reloc_type ==
-#ifdef TCC_TARGET_X86_64
-            R_X86_64_JUMP_SLOT
-#else
-            R_386_JMP_SLOT
-#endif
-            ) {
-            Section *plt;
-            uint8_t *p;
-            int modrm;
-
-#if defined(TCC_OUTPUT_DLL_WITH_PLT)
-            modrm = 0x25;
-#else
-            /* if we build a DLL, we add a %ebx offset */
-            if (s1->output_type == TCC_OUTPUT_DLL)
-                modrm = 0xa3;
-            else
-                modrm = 0x25;
-#endif
-
-            /* add a PLT entry */
-            plt = s1->plt;
-            if (plt->data_offset == 0) {
-                /* first plt entry */
-                p = section_ptr_add(plt, 16);
-                p[0] = 0xff; /* pushl got + PTR_SIZE */
-                p[1] = modrm + 0x10;
-                put32(p + 2, PTR_SIZE);
-                p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
-                p[7] = modrm;
-                put32(p + 8, PTR_SIZE * 2);
-            }
-
-            p = section_ptr_add(plt, 16);
-            p[0] = 0xff; /* jmp *(got + x) */
-            p[1] = modrm;
-            put32(p + 2, s1->got->data_offset);
-            p[6] = 0x68; /* push $xxx */
-            put32(p + 7, (plt->data_offset - 32) >> 1);
-            p[11] = 0xe9; /* jmp plt_start */
-            put32(p + 12, -(plt->data_offset));
-
-            /* the symbol is modified so that it will be relocated to
-               the PLT */
-#if !defined(TCC_OUTPUT_DLL_WITH_PLT)
-            if (s1->output_type == TCC_OUTPUT_EXE)
-#endif
-                offset = plt->data_offset - 16;
-        }
-#elif defined(TCC_TARGET_ARM)
-        if (reloc_type == R_ARM_JUMP_SLOT) {
-            Section *plt;
-            uint8_t *p;
-            
-            /* if we build a DLL, we add a %ebx offset */
-            if (s1->output_type == TCC_OUTPUT_DLL)
-                tcc_error("DLLs unimplemented!");
-
-            /* add a PLT entry */
-            plt = s1->plt;
-            if (plt->data_offset == 0) {
-                /* first plt entry */
-                p = section_ptr_add(plt, 16);
-                put32(p     , 0xe52de004);
-                put32(p +  4, 0xe59fe010);
-                put32(p +  8, 0xe08fe00e);
-                put32(p + 12, 0xe5bef008);
-            }
-
-            if (s1->sym_attrs[sym_index].plt_thumb_stub) {
-                p = section_ptr_add(plt, 20);
-                put32(p  , 0x4778); // bx pc
-                put32(p+2, 0x46c0); // nop
-                p += 4;
-            } else
-                p = section_ptr_add(plt, 16);
-            put32(p  , 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
-            put32(p+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
-            put32(p+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
-            put32(p+12, s1->got->data_offset);
-
-            /* the symbol is modified so that it will be relocated to
-               the PLT */
-            if (s1->output_type == TCC_OUTPUT_EXE)
-                offset = plt->data_offset - 16;
-        }
-#elif defined(TCC_TARGET_C67)
-        tcc_error("C67 got not implemented");
-#elif  defined(TCC_TARGET_IL)
-        tcc_error("IL got not implemented");
-#else
-#error unsupported CPU
-#endif
-        index = put_elf_sym(s1->dynsym, offset, 
-                            size, info, 0, sym->st_shndx, name);
-        /* put a got entry */
-        put_elf_reloc(s1->dynsym, s1->got, 
-                      s1->got->data_offset, 
-                      reloc_type, index);
-    }
-    ptr = section_ptr_add(s1->got, PTR_SIZE);
-    *ptr = 0;
+	if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
+	    /* Hack alarm.  We don't want to emit dynamic symbols
+	       and symbol based relocs for STB_LOCAL symbols, but rather
+	       want to resolve them directly.  At this point the symbol
+	       values aren't final yet, so we must defer this.  We will later
+	       have to create a RELATIVE reloc anyway, so we misuse the
+	       relocation slot to smuggle the symbol reference until
+	       fill_local_got_entries.  Not that the sym_index is
+	       relative to symtab_section, not s1->dynsym!  Nevertheless
+	       we use s1->dyn_sym so that if this is the first call
+	       that got->reloc is correctly created.  Also note that
+	       RELATIVE relocs are not normally created for the .got,
+	       so the types serves as a marker for later (and is retained
+	       also for the final output, which is okay because then the
+	       got is just normal data).  */
+	    put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
+			  sym_index);
+	} else {
+	    if (0 == attr->dyn_index)
+                attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
+					      info, 0, sym->st_shndx, name);
+	    put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
+			  attr->dyn_index);
+	}
+    } else {
+        put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
+                      sym_index);
+    }
+
+    if (need_plt_entry) {
+        if (!s1->plt) {
+    	    s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
+    			          SHF_ALLOC | SHF_EXECINSTR);
+    	    s1->plt->sh_entsize = 4;
+        }
+
+        attr->plt_offset = create_plt_entry(s1, got_offset, attr);
+
+        /* create a symbol 'sym@plt' for the PLT jump vector */
+        len = strlen(name);
+        if (len > sizeof plt_name - 5)
+            len = sizeof plt_name - 5;
+        memcpy(plt_name, name, len);
+        strcpy(plt_name + len, "@plt");
+        attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
+            ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
+
+    } else {
+        attr->got_offset = got_offset;
+    }
+
+    return attr;
 }
 
@@ -1148,7 +1019,8 @@
 {
     Section *s;
-    ElfW_Rel *rel, *rel_end;
+    ElfW_Rel *rel;
     ElfW(Sym) *sym;
-    int i, type, reloc_type, sym_index;
+    int i, type, gotplt_entry, reloc_type, sym_index;
+    struct sym_attr *attr;
 
     for(i = 1; i < s1->nb_sections; i++) {
@@ -1159,125 +1031,79 @@
         if (s->link != symtab_section)
             continue;
-        rel_end = (ElfW_Rel *)(s->data + s->data_offset);
-        for(rel = (ElfW_Rel *)s->data;
-            rel < rel_end;
-            rel++) {
+        for_each_elem(s, 0, rel, ElfW_Rel) {
             type = ELFW(R_TYPE)(rel->r_info);
-            switch(type) {
-#if defined(TCC_TARGET_I386)
-            case R_386_GOT32:
-            case R_386_GOTOFF:
-            case R_386_GOTPC:
-            case R_386_PLT32:
-                if (!s1->got)
-                    build_got(s1);
-                if (type == R_386_GOT32 || type == R_386_PLT32) {
-                    sym_index = ELFW(R_SYM)(rel->r_info);
-                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-                    /* look at the symbol got offset. If none, then add one */
-                    if (type == R_386_GOT32)
-                        reloc_type = R_386_GLOB_DAT;
-                    else
-                        reloc_type = R_386_JMP_SLOT;
-                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
-                                  sym_index);
-                }
-                break;
-#elif defined(TCC_TARGET_ARM)
-            case R_ARM_GOT_BREL:
-            case R_ARM_GOTOFF32:
-            case R_ARM_BASE_PREL:
-            case R_ARM_PLT32:
-                if (!s1->got)
-                    build_got(s1);
-                if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
-                    sym_index = ELFW(R_SYM)(rel->r_info);
-                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-                    /* look at the symbol got offset. If none, then add one */
-                    if (type == R_ARM_GOT_BREL)
-                        reloc_type = R_ARM_GLOB_DAT;
-                    else
-                        reloc_type = R_ARM_JUMP_SLOT;
-                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
-                                  sym_index);
-                }
-                break;
-#elif defined(TCC_TARGET_C67)
-            case R_C60_GOT32:
-            case R_C60_GOTOFF:
-            case R_C60_GOTPC:
-            case R_C60_PLT32:
-                if (!s1->got)
-                    build_got(s1);
-                if (type == R_C60_GOT32 || type == R_C60_PLT32) {
-                    sym_index = ELFW(R_SYM)(rel->r_info);
-                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-                    /* look at the symbol got offset. If none, then add one */
-                    if (type == R_C60_GOT32)
-                        reloc_type = R_C60_GLOB_DAT;
-                    else
-                        reloc_type = R_C60_JMP_SLOT;
-                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
-                                  sym_index);
-                }
-                break;
-#elif defined(TCC_TARGET_X86_64)
-            case R_X86_64_GOT32:
-            case R_X86_64_GOTTPOFF:
-            case R_X86_64_GOTPCREL:
-            case R_X86_64_PLT32:
-                if (!s1->got)
-                    build_got(s1);
-                if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
-                    type == R_X86_64_PLT32) {
-                    sym_index = ELFW(R_SYM)(rel->r_info);
-                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-                    /* look at the symbol got offset. If none, then add one */
-                    if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
-                        reloc_type = R_X86_64_GLOB_DAT;
-                    else
-                        reloc_type = R_X86_64_JUMP_SLOT;
-                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
-                                  sym_index);
-                }
-                break;
-#elif  defined(TCC_TARGET_IL)
-#else
-#error unsupported CPU
-#endif
-            default:
-                break;
-            }
-        }
-    }
-}
-
-ST_FUNC Section *new_symtab(TCCState *s1,
-                           const char *symtab_name, int sh_type, int sh_flags,
-                           const char *strtab_name, 
-                           const char *hash_name, int hash_sh_flags)
-{
-    Section *symtab, *strtab, *hash;
-    int *ptr, nb_buckets;
-
-    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
-    symtab->sh_entsize = sizeof(ElfW(Sym));
-    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
-    put_elf_str(strtab, "");
-    symtab->link = strtab;
-    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
-    
-    nb_buckets = 1;
-
-    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
-    hash->sh_entsize = sizeof(int);
-    symtab->hash = hash;
-    hash->link = symtab;
-
-    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
-    ptr[0] = nb_buckets;
-    ptr[1] = 1;
-    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
-    return symtab;
+            gotplt_entry = gotplt_entry_type(type);
+            sym_index = ELFW(R_SYM)(rel->r_info);
+            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+            if (gotplt_entry == NO_GOTPLT_ENTRY) {
+                continue;
+            }
+
+            /* Automatically create PLT/GOT [entry] if it is an undefined
+	       reference (resolved at runtime), or the symbol is absolute,
+	       probably created by tcc_add_symbol, and thus on 64-bit
+	       targets might be too far from application code.  */
+            if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
+                if (sym->st_shndx == SHN_UNDEF) {
+                    ElfW(Sym) *esym;
+		    int dynindex;
+                    if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
+                        continue;
+		    /* Relocations for UNDEF symbols would normally need
+		       to be transferred into the executable or shared object.
+		       If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
+		       But TCC doesn't do that (at least for exes), so we
+		       need to resolve all such relocs locally.  And that
+		       means PLT slots for functions in DLLs and COPY relocs for
+		       data symbols.  COPY relocs were generated in
+		       bind_exe_dynsyms (and the symbol adjusted to be defined),
+		       and for functions we were generated a dynamic symbol
+		       of function type.  */
+		    if (s1->dynsym) {
+			/* dynsym isn't set for -run :-/  */
+			dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
+			esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
+			if (dynindex
+			    && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
+				|| (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
+				    && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
+			    goto jmp_slot;
+		    }
+                } else if (!(sym->st_shndx == SHN_ABS
+#ifndef TCC_TARGET_ARM
+			&& PTR_SIZE == 8
+#endif
+			))
+                    continue;
+            }
+
+#ifdef TCC_TARGET_X86_64
+            if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
+                (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
+		 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
+                rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
+                continue;
+            }
+#endif
+            if (code_reloc(type)) {
+            jmp_slot:
+                reloc_type = R_JMP_SLOT;
+            } else
+                reloc_type = R_GLOB_DAT;
+
+            if (!s1->got)
+                build_got(s1);
+
+            if (gotplt_entry == BUILD_GOT_ONLY)
+                continue;
+
+            attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
+                                 sym_index);
+
+            if (reloc_type == R_JMP_SLOT)
+                rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
+        }
+    }
 }
 
@@ -1291,4 +1117,5 @@
 }
 
+#ifndef TCC_TARGET_PE
 static void add_init_array_defines(TCCState *s1, const char *section_name)
 {
@@ -1297,5 +1124,5 @@
     char sym_start[1024];
     char sym_end[1024];
-    
+
     snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
     snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
@@ -1309,47 +1136,16 @@
     }
 
-    add_elf_sym(symtab_section, 
+    set_elf_sym(symtab_section,
                 0, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 s->sh_num, sym_start);
-    add_elf_sym(symtab_section, 
+    set_elf_sym(symtab_section,
                 end_offset, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 s->sh_num, sym_end);
 }
-
-ST_FUNC void tcc_add_bcheck(TCCState *s1)
-{
-#ifdef CONFIG_TCC_BCHECK
-    unsigned long *ptr;
-    Section *init_section;
-    unsigned char *pinit;
-    int sym_index;
-
-    if (0 == s1->do_bounds_check)
-        return;
-
-    /* XXX: add an object file to do that */
-    ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
-    *ptr = 0;
-    add_elf_sym(symtab_section, 0, 0,
-                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
-                bounds_section->sh_num, "__bounds_start");
-#ifdef TCC_TARGET_I386
-    if (s1->output_type != TCC_OUTPUT_MEMORY) {
-        /* add 'call __bound_init()' in .init section */
-        init_section = find_section(s1, ".init");
-        pinit = section_ptr_add(init_section, 5);
-        pinit[0] = 0xe8;
-        put32(pinit + 1, -4);
-        sym_index = find_elf_sym(symtab_section, "__bound_init");
-        put_elf_reloc(symtab_section, init_section,
-                      init_section->data_offset - 4, R_386_PC32, sym_index);
-    }
-#endif
-#endif
-}
-
-static inline int tcc_add_support(TCCState *s1, const char *filename)
+#endif
+
+static int tcc_add_support(TCCState *s1, const char *filename)
 {
     char buf[1024];
@@ -1358,17 +1154,52 @@
 }
 
+ST_FUNC void tcc_add_bcheck(TCCState *s1)
+{
+#ifdef CONFIG_TCC_BCHECK
+    addr_t *ptr;
+    int sym_index;
+
+    if (0 == s1->do_bounds_check)
+        return;
+    /* XXX: add an object file to do that */
+    ptr = section_ptr_add(bounds_section, sizeof(*ptr));
+    *ptr = 0;
+    set_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                bounds_section->sh_num, "__bounds_start");
+    /* pull bcheck.o from libtcc1.a */
+    sym_index = set_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                SHN_UNDEF, "__bound_init");
+    if (s1->output_type != TCC_OUTPUT_MEMORY) {
+        /* add 'call __bound_init()' in .init section */
+        Section *init_section = find_section(s1, ".init");
+        unsigned char *pinit = section_ptr_add(init_section, 5);
+        pinit[0] = 0xe8;
+        write32le(pinit + 1, -4);
+        put_elf_reloc(symtab_section, init_section,
+            init_section->data_offset - 4, R_386_PC32, sym_index);
+            /* R_386_PC32 = R_X86_64_PC32 = 2 */
+    }
+#endif
+}
+
 /* add tcc runtime libraries */
 ST_FUNC void tcc_add_runtime(TCCState *s1)
 {
     tcc_add_bcheck(s1);
-
+    tcc_add_pragma_libs(s1);
     /* add libc */
     if (!s1->nostdlib) {
-        tcc_add_library(s1, "c");
-#ifdef CONFIG_USE_LIBGCC
-        tcc_add_file(s1, TCC_LIBGCC);
-#elif !defined WITHOUT_LIBTCC
-        tcc_add_support(s1, "libtcc1.a");
-#endif
+        tcc_add_library_err(s1, "c");
+#ifdef TCC_LIBGCC
+        if (!s1->static_link) {
+            if (TCC_LIBGCC[0] == '/')
+                tcc_add_file(s1, TCC_LIBGCC);
+            else
+                tcc_add_dll(s1, TCC_LIBGCC, 0);
+        }
+#endif
+        tcc_add_support(s1, TCC_LIBTCC1);
         /* add crt end if not memory output */
         if (s1->output_type != TCC_OUTPUT_MEMORY)
@@ -1380,5 +1211,5 @@
    sections are filled (for example after allocating common
    symbols)) */
-ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
+static void tcc_add_linker_symbols(TCCState *s1)
 {
     char buf[1024];
@@ -1386,21 +1217,23 @@
     Section *s;
 
-    add_elf_sym(symtab_section, 
+    set_elf_sym(symtab_section,
                 text_section->data_offset, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 text_section->sh_num, "_etext");
-    add_elf_sym(symtab_section, 
+    set_elf_sym(symtab_section,
                 data_section->data_offset, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 data_section->sh_num, "_edata");
-    add_elf_sym(symtab_section, 
+    set_elf_sym(symtab_section,
                 bss_section->data_offset, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                 bss_section->sh_num, "_end");
+#ifndef TCC_TARGET_PE
     /* horrible new standard ldscript defines */
     add_init_array_defines(s1, ".preinit_array");
     add_init_array_defines(s1, ".init_array");
     add_init_array_defines(s1, ".fini_array");
-    
+#endif
+
     /* add start and stop symbols for sections whose name can be
        expressed in C */
@@ -1423,10 +1256,10 @@
             }
             snprintf(buf, sizeof(buf), "__start_%s", s->name);
-            add_elf_sym(symtab_section, 
+            set_elf_sym(symtab_section,
                         0, 0,
                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
                         s->sh_num, buf);
             snprintf(buf, sizeof(buf), "__stop_%s", s->name);
-            add_elf_sym(symtab_section,
+            set_elf_sym(symtab_section,
                         s->data_offset, 0,
                         ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
@@ -1437,6 +1270,24 @@
 }
 
+ST_FUNC void resolve_common_syms(TCCState *s1)
+{
+    ElfW(Sym) *sym;
+
+    /* Allocate common symbols in BSS.  */
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (sym->st_shndx == SHN_COMMON) {
+            /* symbol alignment is in st_value for SHN_COMMONs */
+	    sym->st_value = section_add(bss_section, sym->st_size,
+					sym->st_value);
+            sym->st_shndx = bss_section->sh_num;
+        }
+    }
+
+    /* Now assign linker provided symbols their value.  */
+    tcc_add_linker_symbols(s1);
+}
+
 static void tcc_output_binary(TCCState *s1, FILE *f,
-                              const int *section_order)
+                              const int *sec_order)
 {
     Section *s;
@@ -1445,5 +1296,5 @@
     offset = 0;
     for(i=1;i<s1->nb_sections;i++) {
-        s = s1->sections[section_order[i]];
+        s = s1->sections[sec_order[i]];
         if (s->sh_type != SHT_NOBITS &&
             (s->sh_flags & SHF_ALLOC)) {
@@ -1459,432 +1310,285 @@
 }
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#define	HAVE_PHDR	1
-#define	EXTRA_RELITEMS	14
-
-/* move the relocation value from .dynsym to .got */
-void patch_dynsym_undef(TCCState *s1, Section *s)
-{
-    uint32_t *gotd = (void *)s1->got->data;
-    ElfW(Sym) *sym, *sym_end;
-
-    gotd += 3;	// dummy entries in .got
-    /* relocate symbols in .dynsym */
-    sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
-    for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) {
-	if (sym->st_shndx == SHN_UNDEF) {
-	    *gotd++ = sym->st_value + 6; // XXX 6 is magic ?
-	    sym->st_value = 0;
+ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
+{
+    int sym_index = ELFW(R_SYM) (rel->r_info);
+    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+    unsigned offset = attr->got_offset;
+
+    if (0 == offset)
+        return;
+    section_reserve(s1->got, offset + PTR_SIZE);
+#ifdef TCC_TARGET_X86_64
+    write64le(s1->got->data + offset, sym->st_value);
+#else
+    write32le(s1->got->data + offset, sym->st_value);
+#endif
+}
+
+/* Perform relocation to GOT or PLT entries */
+ST_FUNC void fill_got(TCCState *s1)
+{
+    Section *s;
+    ElfW_Rel *rel;
+    int i;
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type != SHT_RELX)
+            continue;
+        /* no need to handle got relocations */
+        if (s->link != symtab_section)
+            continue;
+        for_each_elem(s, 0, rel, ElfW_Rel) {
+            switch (ELFW(R_TYPE) (rel->r_info)) {
+                case R_X86_64_GOT32:
+                case R_X86_64_GOTPCREL:
+		case R_X86_64_GOTPCRELX:
+		case R_X86_64_REX_GOTPCRELX:
+                case R_X86_64_PLT32:
+                    fill_got_entry(s1, rel);
+                    break;
+            }
+        }
+    }
+}
+
+/* See put_got_entry for a description.  This is the second stage
+   where GOT references to local defined symbols are rewritten.  */
+static void fill_local_got_entries(TCCState *s1)
+{
+    ElfW_Rel *rel;
+    for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
+	if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
+	    int sym_index = ELFW(R_SYM) (rel->r_info);
+	    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+	    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+	    unsigned offset = attr->got_offset;
+	    if (offset != rel->r_offset - s1->got->sh_addr)
+	      tcc_error_noabort("huh");
+	    rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
+#if SHT_RELX == SHT_RELA
+	    rel->r_addend = sym->st_value;
+#else
+	    /* All our REL architectures also happen to be 32bit LE.  */
+	    write32le(s1->got->data + offset, sym->st_value);
+#endif
 	}
     }
 }
-#else
-#define	HAVE_PHDR	0
-#define	EXTRA_RELITEMS	9
-
-/* zero plt offsets of weak symbols in .dynsym */
-void patch_dynsym_undef(TCCState *s1, Section *s)
-{
-    ElfW(Sym) *sym, *sym_end;
-
-    sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
-    for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
-        if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
-            sym->st_value = 0;
-}
-#endif
-
-ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
-{
-	int sym_index = ELFW(R_SYM) (rel->r_info);
-	ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
-	unsigned long offset;
-
-	if (sym_index >= s1->nb_sym_attrs)
-		return;
-	offset = s1->sym_attrs[sym_index].got_offset;
-	section_reserve(s1->got, offset + PTR_SIZE);
-#ifdef TCC_TARGET_X86_64
-	/* only works for x86-64 */
-	put32(s1->got->data + offset + 4, sym->st_value >> 32);
-#endif
-	put32(s1->got->data + offset, sym->st_value & 0xffffffff);
-}
-
-ST_FUNC void fill_got(TCCState *s1)
-{
-	Section *s;
-	ElfW_Rel *rel, *rel_end;
-	int i;
-
-	for(i = 1; i < s1->nb_sections; i++) {
-		s = s1->sections[i];
-		if (s->sh_type != SHT_RELX)
-			continue;
-		/* no need to handle got relocations */
-		if (s->link != symtab_section)
-			continue;
-		rel_end = (ElfW_Rel *) (s->data + s->data_offset);
-		for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
-			switch (ELFW(R_TYPE) (rel->r_info)) {
-			case R_X86_64_GOT32:
-			case R_X86_64_GOTPCREL:
-			case R_X86_64_PLT32:
-				fill_got_entry(s1, rel);
-				break;
-			}
-		}
-	}
-}
-
-
-/* output an ELF file */
-/* XXX: suppress unneeded sections */
-static int elf_output_file(TCCState *s1, const char *filename)
-{
-    ElfW(Ehdr) ehdr;
-    FILE *f;
-    int fd, mode, ret;
-    int *section_order;
-    int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
-    long long tmp;
-    addr_t addr;
-    Section *strsec, *s;
-    ElfW(Shdr) shdr, *sh;
-    ElfW(Phdr) *phdr, *ph;
-    Section *interp, *dynamic, *dynstr;
-    unsigned long saved_dynamic_data_offset;
-    ElfW(Sym) *sym;
-    int type, file_type;
-    addr_t rel_addr, rel_size;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    addr_t bss_addr, bss_size;
-#endif
-
-    file_type = s1->output_type;
-    s1->nb_errors = 0;
-
-    if (file_type != TCC_OUTPUT_OBJ) {
-        tcc_add_runtime(s1);
-    }
-
-    phdr = NULL;
-    section_order = NULL;
-    interp = NULL;
-    dynamic = NULL;
-    dynstr = NULL; /* avoid warning */
-    saved_dynamic_data_offset = 0; /* avoid warning */
-    
-    if (file_type != TCC_OUTPUT_OBJ) {
-        relocate_common_syms();
-
-        tcc_add_linker_symbols(s1);
-
-        if (!s1->static_link) {
-            const char *name;
-            int sym_index, index;
-            ElfW(Sym) *esym, *sym_end;
-
-            if (file_type == TCC_OUTPUT_EXE) {
-                char *ptr;
-		/* allow override the dynamic loader */
-		const char *elfint = getenv("LD_SO");
-		if (elfint == NULL)
-		    elfint = CONFIG_TCC_ELFINTERP;
-                /* add interpreter section only if executable */
-                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
-                interp->sh_addralign = 1;
-                ptr = section_ptr_add(interp, 1+strlen(elfint));
-                strcpy(ptr, elfint);
-            }
-
-            /* add dynamic symbol table */
-            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
-                                    ".dynstr", 
-                                    ".hash", SHF_ALLOC);
-            dynstr = s1->dynsym->link;
-            
-            /* add dynamic section */
-            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 
-                                  SHF_ALLOC | SHF_WRITE);
-            dynamic->link = dynstr;
-            dynamic->sh_entsize = sizeof(ElfW(Dyn));
-        
-            /* add PLT */
-            s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 
-                                  SHF_ALLOC | SHF_EXECINSTR);
-            s1->plt->sh_entsize = 4;
-
-            build_got(s1);
-
-            /* scan for undefined symbols and see if they are in the
-               dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
-               is found, then we add it in the PLT. If a symbol
-               STT_OBJECT is found, we add it in the .bss section with
-               a suitable relocation */
-            sym_end = (ElfW(Sym) *)(symtab_section->data + 
-                                    symtab_section->data_offset);
-            if (file_type == TCC_OUTPUT_EXE) {
-                for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
-                    sym < sym_end;
-                    sym++) {
-                    if (sym->st_shndx == SHN_UNDEF) {
-                        name = symtab_section->link->data + sym->st_name;
-                        sym_index = find_elf_sym(s1->dynsymtab_section, name);
-                        if (sym_index) {
-                            esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
-                            type = ELFW(ST_TYPE)(esym->st_info);
-                            if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
-                                /* Indirect functions shall have STT_FUNC type
-                                 * in executable dynsym section. Indeed, a dlsym
-                                 * call following a lazy resolution would pick
-                                 * the symbol value from the executable dynsym
-                                 * entry which would contain the address of the
-                                 * function wanted by the caller of dlsym
-                                 * instead of the address of the function that
-                                 * would return that address */
-                                put_got_entry(s1, R_JMP_SLOT, esym->st_size, 
-                                              ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
-                                              sym - (ElfW(Sym) *)symtab_section->data);
-                            } else if (type == STT_OBJECT) {
-                                unsigned long offset;
-                                ElfW(Sym) *dynsym, *dynsym_end;
-                                offset = bss_section->data_offset;
-                                /* XXX: which alignment ? */
-                                offset = (offset + 16 - 1) & -16;
-                                index = put_elf_sym(s1->dynsym, offset, esym->st_size, 
-                                                    esym->st_info, 0, 
-                                                    bss_section->sh_num, name);
-                                // Ensure R_COPY works for weak symbol aliases
-                                if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
-                                    dynsym_end = (ElfW(Sym) *)
-                                                 (s1->dynsymtab_section->data +
-                                                  s1->dynsymtab_section->data_offset);
-                                    for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
-                                        dynsym < dynsym_end; dynsym++) {
-                                        if ((dynsym->st_value == esym->st_value)
-                                           && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
-                                            char *dynname;
-                                            dynname = s1->dynsymtab_section->link->data
-                                                      + dynsym->st_name;
-                                            put_elf_sym(s1->dynsym, offset,
-                                                        dynsym->st_size,
-                                                        dynsym->st_info, 0,
-                                                        bss_section->sh_num,
-                                                        dynname);
-                                            break;
-                                        }
-                                    }
-                                }
-                                put_elf_reloc(s1->dynsym, bss_section, 
-                                              offset, R_COPY, index);
-                                offset += esym->st_size;
-                                bss_section->data_offset = offset;
-                            }
-                        } else {
-                                /* STB_WEAK undefined symbols are accepted */
-                                /* XXX: _fp_hw seems to be part of the ABI, so we ignore
-                                   it */
-                            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
-                                !strcmp(name, "_fp_hw")) {
-                            } else {
-                                tcc_error_noabort("undefined symbol '%s'", name);
-                            }
-                        }
-                    } else if (s1->rdynamic && 
-                               ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
-                        /* if -rdynamic option, then export all non
-                           local symbols */
-                        name = symtab_section->link->data + sym->st_name;
-                        put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
-                                    sym->st_info, 0, 
-                                    sym->st_shndx, name);
-                    }
-                }
-            
-                if (s1->nb_errors)
-                    goto fail;
-
-                /* now look at unresolved dynamic symbols and export
-                   corresponding symbol */
-                sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + 
-                                        s1->dynsymtab_section->data_offset);
-                for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; 
-                    esym < sym_end;
-                    esym++) {
-                    if (esym->st_shndx == SHN_UNDEF) {
-                        name = s1->dynsymtab_section->link->data + esym->st_name;
-                        sym_index = find_elf_sym(symtab_section, name);
-                        if (sym_index) {
-                            /* XXX: avoid adding a symbol if already
-                               present because of -rdynamic ? */
-                            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-                            put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
-                                        sym->st_info, 0, 
-                                        sym->st_shndx, name);
-                        } else {
-                            if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
-                                /* weak symbols can stay undefined */
-                            } else {
-                                tcc_warning("undefined dynamic symbol '%s'", name);
+
+/* Bind symbols of executable: resolve undefined symbols from exported symbols
+   in shared libraries and export non local defined symbols to shared libraries
+   if -rdynamic switch was given on command line */
+static void bind_exe_dynsyms(TCCState *s1)
+{
+    const char *name;
+    int sym_index, index;
+    ElfW(Sym) *sym, *esym;
+    int type;
+
+    /* Resolve undefined symbols from dynamic symbols. When there is a match:
+       - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
+       - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (sym->st_shndx == SHN_UNDEF) {
+            name = (char *) symtab_section->link->data + sym->st_name;
+            sym_index = find_elf_sym(s1->dynsymtab_section, name);
+            if (sym_index) {
+                esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
+                type = ELFW(ST_TYPE)(esym->st_info);
+                if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
+                    /* Indirect functions shall have STT_FUNC type in executable
+                     * dynsym section. Indeed, a dlsym call following a lazy
+                     * resolution would pick the symbol value from the
+                     * executable dynsym entry which would contain the address
+                     * of the function wanted by the caller of dlsym instead of
+                     * the address of the function that would return that
+                     * address */
+                    int dynindex
+		      = put_elf_sym(s1->dynsym, 0, esym->st_size,
+				    ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
+				    name);
+		    int index = sym - (ElfW(Sym) *) symtab_section->data;
+		    get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+                } else if (type == STT_OBJECT) {
+                    unsigned long offset;
+                    ElfW(Sym) *dynsym;
+                    offset = bss_section->data_offset;
+                    /* XXX: which alignment ? */
+                    offset = (offset + 16 - 1) & -16;
+                    set_elf_sym (s1->symtab, offset, esym->st_size,
+                                 esym->st_info, 0, bss_section->sh_num, name);
+                    index = put_elf_sym(s1->dynsym, offset, esym->st_size,
+                                        esym->st_info, 0, bss_section->sh_num,
+                                        name);
+
+                    /* Ensure R_COPY works for weak symbol aliases */
+                    if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
+                        for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
+                            if ((dynsym->st_value == esym->st_value)
+                                && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
+                                char *dynname = (char *) s1->dynsymtab_section->link->data
+                                                + dynsym->st_name;
+                                put_elf_sym(s1->dynsym, offset, dynsym->st_size,
+                                            dynsym->st_info, 0,
+                                            bss_section->sh_num, dynname);
+                                break;
                             }
                         }
                     }
+
+                    put_elf_reloc(s1->dynsym, bss_section,
+                                  offset, R_COPY, index);
+                    offset += esym->st_size;
+                    bss_section->data_offset = offset;
                 }
             } else {
-                int nb_syms;
-                /* shared library case : we simply export all the global symbols */
-                nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
-                s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
-                for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
-                    sym < sym_end;
-                    sym++) {
-                    if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
-#if defined(TCC_OUTPUT_DLL_WITH_PLT)
-                        if ((ELFW(ST_TYPE)(sym->st_info) == STT_FUNC ||
-                            ELFW(ST_TYPE)(sym->st_info) == STT_GNU_IFUNC)
-                            && sym->st_shndx == SHN_UNDEF) {
-                            int visibility = ELFW(ST_BIND)(sym->st_info);
-                            put_got_entry(s1, R_JMP_SLOT, sym->st_size, 
-                                          ELFW(ST_INFO)(visibility,STT_FUNC),
-                                          sym - (ElfW(Sym) *)symtab_section->data);
-                        }
-                        else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
-                            put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, 
-                                          sym->st_info, 
-                                          sym - (ElfW(Sym) *)symtab_section->data);
-                        }
-                        else
-#endif
-                        {
-                            name = symtab_section->link->data + sym->st_name;
-                            index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
-                                                sym->st_info, 0, 
-                                                sym->st_shndx, name);
-                            s1->symtab_to_dynsym[sym - 
-                                                 (ElfW(Sym) *)symtab_section->data] = 
-                                index;
-                        }
-                    }
+                /* STB_WEAK undefined symbols are accepted */
+                /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
+                if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
+                    !strcmp(name, "_fp_hw")) {
+                } else {
+                    tcc_error_noabort("undefined symbol '%s'", name);
                 }
             }
-
-            build_got_entries(s1);
-        
-            /* add a list of needed dlls */
-            for(i = 0; i < s1->nb_loaded_dlls; i++) {
-                DLLReference *dllref = s1->loaded_dlls[i];
-                if (dllref->level == 0)
-                    put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
-            }
-
-            if (s1->rpath)
-                put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
-
-            /* XXX: currently, since we do not handle PIC code, we
-               must relocate the readonly segments */
-            if (file_type == TCC_OUTPUT_DLL) {
-                if (s1->soname)
-                    put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
-                put_dt(dynamic, DT_TEXTREL, 0);
-            }
-
-            if (s1->symbolic)
-                put_dt(dynamic, DT_SYMBOLIC, 0);
-
-            /* add necessary space for other entries */
-            saved_dynamic_data_offset = dynamic->data_offset;
-            dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
-        } else {
-            /* still need to build got entries in case of static link */
-            build_got_entries(s1);
-        }
-    }
-
-    memset(&ehdr, 0, sizeof(ehdr));
-
-    /* we add a section for symbols */
-    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
-    put_elf_str(strsec, "");
-    
-    /* compute number of sections */
-    shnum = s1->nb_sections;
-
-    /* this array is used to reorder sections in the output file */
-    section_order = tcc_malloc(sizeof(int) * shnum);
-    section_order[0] = 0;
-    sh_order_index = 1;
-    
-    /* compute number of program headers */
-    switch(file_type) {
-    default:
-    case TCC_OUTPUT_OBJ:
-        phnum = 0;
-        break;
-    case TCC_OUTPUT_EXE:
-        if (!s1->static_link)
-            phnum = 4 + HAVE_PHDR;
-        else
-            phnum = 2;
-        break;
-    case TCC_OUTPUT_DLL:
-        phnum = 3;
-        break;
-    }
-
-    /* allocate strings for section names and decide if an unallocated
-       section should be output */
-    /* NOTE: the strsec section comes last, so its size is also
-       correct ! */
+        } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            /* if -rdynamic option, then export all non local symbols */
+            name = (char *) symtab_section->link->data + sym->st_name;
+            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
+                        0, sym->st_shndx, name);
+        }
+    }
+}
+
+/* Bind symbols of libraries: export all non local symbols of executable that
+   are referenced by shared libraries. The reason is that the dynamic loader
+   search symbol first in executable and then in libraries. Therefore a
+   reference to a symbol already defined by a library can still be resolved by
+   a symbol in the executable. */
+static void bind_libs_dynsyms(TCCState *s1)
+{
+    const char *name;
+    int sym_index;
+    ElfW(Sym) *sym, *esym;
+
+    for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
+        name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
+        sym_index = find_elf_sym(symtab_section, name);
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        if (sym_index && sym->st_shndx != SHN_UNDEF
+            && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+                sym->st_info, 0, sym->st_shndx, name);
+        } else if (esym->st_shndx == SHN_UNDEF) {
+            /* weak symbols can stay undefined */
+            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
+                tcc_warning("undefined dynamic symbol '%s'", name);
+        }
+    }
+}
+
+/* Export all non local symbols. This is used by shared libraries so that the
+   non local symbols they define can resolve a reference in another shared
+   library or in the executable. Correspondingly, it allows undefined local
+   symbols to be resolved by other shared libraries or by the executable. */
+static void export_global_syms(TCCState *s1)
+{
+    int dynindex, index;
+    const char *name;
+    ElfW(Sym) *sym;
+
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+	    name = (char *) symtab_section->link->data + sym->st_name;
+	    dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+				   sym->st_info, 0, sym->st_shndx, name);
+	    index = sym - (ElfW(Sym) *) symtab_section->data;
+            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+        }
+    }
+}
+
+/* Allocate strings for section names and decide if an unallocated section
+   should be output.
+   NOTE: the strsec section comes last, so its size is also correct ! */
+static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
+{
+    int i;
+    Section *s;
+    int textrel = 0;
+
+    /* Allocate strings for section names */
     for(i = 1; i < s1->nb_sections; i++) {
         s = s1->sections[i];
-        s->sh_name = put_elf_str(strsec, s->name);
-#if 0 //gr       
-        printf("section: f=%08x t=%08x i=%08x %s %s\n", 
-               s->sh_flags, 
-               s->sh_type, 
-               s->sh_info, 
-               s->name, 
-               s->reloc ? s->reloc->name : "n"
-               ); 
-#endif
         /* when generating a DLL, we include relocations but we may
            patch them */
-        if (file_type == TCC_OUTPUT_DLL && 
-            s->sh_type == SHT_RELX && 
-            !(s->sh_flags & SHF_ALLOC)) {
-            /* //gr: avoid bogus relocs for empty (debug) sections */
-            if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
-                prepare_dynamic_rel(s1, s);
-            else if (s1->do_debug)
-                s->sh_size = s->data_offset;
+        if (file_type == TCC_OUTPUT_DLL &&
+            s->sh_type == SHT_RELX &&
+            !(s->sh_flags & SHF_ALLOC) &&
+            (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
+            prepare_dynamic_rel(s1, s)) {
+                if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
+                    textrel = 1;
         } else if (s1->do_debug ||
-            file_type == TCC_OUTPUT_OBJ || 
+            file_type == TCC_OUTPUT_OBJ ||
             (s->sh_flags & SHF_ALLOC) ||
-            i == (s1->nb_sections - 1)) {
+	    i == (s1->nb_sections - 1)) {
             /* we output all sections if debug or object file */
             s->sh_size = s->data_offset;
         }
-    }
-
-    /* allocate program segment headers */
-    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
-        
-    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+	if (s->sh_size || (s->sh_flags & SHF_ALLOC))
+            s->sh_name = put_elf_str(strsec, s->name);
+    }
+    strsec->sh_size = strsec->data_offset;
+    return textrel;
+}
+
+/* Info to be copied in dynamic section */
+struct dyn_inf {
+    Section *dynamic;
+    Section *dynstr;
+    unsigned long data_offset;
+    addr_t rel_addr;
+    addr_t rel_size;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    addr_t bss_addr;
+    addr_t bss_size;
+#endif
+};
+
+/* Assign sections to segments and decide how are sections laid out when loaded
+   in memory. This function also fills corresponding program headers. */
+static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
+                           Section *interp, Section* strsec,
+                           struct dyn_inf *dyninf, int *sec_order)
+{
+    int i, j, k, file_type, sh_order_index, file_offset;
+    unsigned long s_align;
+    long long tmp;
+    addr_t addr;
+    ElfW(Phdr) *ph;
+    Section *s;
+
+    file_type = s1->output_type;
+    sh_order_index = 1;
+    file_offset = 0;
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
         file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
-    } else {
-        file_offset = 0;
-    }
+    s_align = ELF_PAGE_SIZE;
+    if (s1->section_align)
+        s_align = s1->section_align;
+
     if (phnum > 0) {
-        /* compute section to program header mapping */
-        if (s1->has_text_addr) { 
+        if (s1->has_text_addr) {
             int a_offset, p_offset;
             addr = s1->text_addr;
             /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
                ELF_PAGE_SIZE */
-            a_offset = (int) (addr & (s1->section_align - 1));
-            p_offset = file_offset & (s1->section_align - 1);
-            if (a_offset < p_offset) 
-                a_offset += s1->section_align;
+            a_offset = (int) (addr & (s_align - 1));
+            p_offset = file_offset & (s_align - 1);
+            if (a_offset < p_offset)
+                a_offset += s_align;
             file_offset += (a_offset - p_offset);
         } else {
@@ -1894,18 +1598,19 @@
                 addr = ELF_START_ADDR;
             /* compute address after headers */
-            addr += (file_offset & (s1->section_align - 1));
-        }
-        
+            addr += (file_offset & (s_align - 1));
+        }
+
+        ph = &phdr[0];
+        /* Leave one program headers for the program interpreter and one for
+           the program header table itself if needed. These are done later as
+           they require section layout to be done first. */
+        if (interp)
+            ph += 2;
+
         /* dynamic relocation table information, for .dynamic section */
-        rel_size = 0;
-        rel_addr = 0;
-
+        dyninf->rel_addr = dyninf->rel_size = 0;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-        bss_addr = bss_size = 0;
-#endif
-        /* leave one program header for the program interpreter */
-        ph = &phdr[0];
-        if (interp)
-            ph += 1 + HAVE_PHDR;
+        dyninf->bss_addr = dyninf->bss_size = 0;
+#endif
 
         for(j = 0; j < 2; j++) {
@@ -1915,8 +1620,10 @@
             else
                 ph->p_flags = PF_R | PF_W;
-            ph->p_align = s1->section_align;
-            
-            /* we do the following ordering: interp, symbol tables,
-               relocations, progbits, nobits */
+            ph->p_align = s_align;
+
+            /* Decide the layout of sections loaded in memory. This must
+               be done before program headers are filled since they contain
+               info about the layout. We do the following ordering: interp,
+               symbol tables, relocations, progbits, nobits */
             /* XXX: do faster and simpler sorting */
             for(k = 0; k < 5; k++) {
@@ -1925,9 +1632,9 @@
                     /* compute if section should be included */
                     if (j == 0) {
-                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
                             SHF_ALLOC)
                             continue;
                     } else {
-                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
                             (SHF_ALLOC | SHF_WRITE))
                             continue;
@@ -1951,14 +1658,14 @@
                             continue;
                     }
-                    section_order[sh_order_index++] = i;
+                    sec_order[sh_order_index++] = i;
 
                     /* section matches: we align it and add its size */
                     tmp = addr;
-                    addr = (addr + s->sh_addralign - 1) & 
+                    addr = (addr + s->sh_addralign - 1) &
                         ~(s->sh_addralign - 1);
                     file_offset += (int) ( addr - tmp );
                     s->sh_offset = file_offset;
                     s->sh_addr = addr;
-                    
+
                     /* update program header infos */
                     if (ph->p_offset == 0) {
@@ -1970,16 +1677,16 @@
                     if (s->sh_type == SHT_RELX) {
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) { // rel_size == 0) {
-                            rel_addr = addr;
-			    rel_size += s->sh_size;	// XXX only first rel.
-			}
-                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) { // rel_size == 0) {
-                            bss_addr = addr;
-			    bss_size = s->sh_size;	// XXX only first rel.
-			}
+                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
+                            dyninf->rel_addr = addr;
+                            dyninf->rel_size += s->sh_size; /* XXX only first rel. */
+                        }
+                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
+                            dyninf->bss_addr = addr;
+                            dyninf->bss_size = s->sh_size; /* XXX only first rel. */
+                        }
 #else
-                        if (rel_size == 0)
-                            rel_addr = addr;
-                        rel_size += s->sh_size;
+                        if (dyninf->rel_size == 0)
+                            dyninf->rel_addr = addr;
+                        dyninf->rel_size += s->sh_size;
 #endif
                     }
@@ -1989,4 +1696,13 @@
                 }
             }
+	    if (j == 0) {
+		/* Make the first PT_LOAD segment include the program
+		   headers itself (and the ELF header as well), it'll
+		   come out with same memory use but will make various
+		   tools like binutils strip work better.  */
+		ph->p_offset &= ~(ph->p_align - 1);
+		ph->p_vaddr &= ~(ph->p_align - 1);
+		ph->p_paddr &= ~(ph->p_align - 1);
+	    }
             ph->p_filesz = file_offset - ph->p_offset;
             ph->p_memsz = addr - ph->p_vaddr;
@@ -1996,157 +1712,12 @@
                     /* if in the middle of a page, we duplicate the page in
                        memory so that one copy is RX and the other is RW */
-                    if ((addr & (s1->section_align - 1)) != 0)
-                        addr += s1->section_align;
+                    if ((addr & (s_align - 1)) != 0)
+                        addr += s_align;
                 } else {
-                    addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
-                    file_offset = (file_offset + s1->section_align - 1) &
-                        ~(s1->section_align - 1);
+                    addr = (addr + s_align - 1) & ~(s_align - 1);
+                    file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
                 }
             }
         }
-
-        /* if interpreter, then add corresponing program header */
-        if (interp) {
-            ph = &phdr[0];
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-	    {
-		int len = phnum * sizeof(ElfW(Phdr));
-
-		ph->p_type = PT_PHDR;
-		ph->p_offset = sizeof(ElfW(Ehdr));
-		ph->p_vaddr = interp->sh_addr - len;
-		ph->p_paddr = ph->p_vaddr;
-		ph->p_filesz = ph->p_memsz = len;
-		ph->p_flags = PF_R | PF_X;
-		ph->p_align = 4; // interp->sh_addralign;
-		ph++;
-	    }
-#endif
-
-            ph->p_type = PT_INTERP;
-            ph->p_offset = interp->sh_offset;
-            ph->p_vaddr = interp->sh_addr;
-            ph->p_paddr = ph->p_vaddr;
-            ph->p_filesz = interp->sh_size;
-            ph->p_memsz = interp->sh_size;
-            ph->p_flags = PF_R;
-            ph->p_align = interp->sh_addralign;
-        }
-        
-        /* if dynamic section, then add corresponing program header */
-        if (dynamic) {
-            ElfW(Sym) *sym_end;
-
-            ph = &phdr[phnum - 1];
-            
-            ph->p_type = PT_DYNAMIC;
-            ph->p_offset = dynamic->sh_offset;
-            ph->p_vaddr = dynamic->sh_addr;
-            ph->p_paddr = ph->p_vaddr;
-            ph->p_filesz = dynamic->sh_size;
-            ph->p_memsz = dynamic->sh_size;
-            ph->p_flags = PF_R | PF_W;
-            ph->p_align = dynamic->sh_addralign;
-
-            /* put GOT dynamic section address */
-            put32(s1->got->data, dynamic->sh_addr);
-
-            /* relocate the PLT */
-            if (file_type == TCC_OUTPUT_EXE
-#if defined(TCC_OUTPUT_DLL_WITH_PLT)
-                || file_type == TCC_OUTPUT_DLL
-#endif
-                ) {
-                uint8_t *p, *p_end;
-
-                p = s1->plt->data;
-                p_end = p + s1->plt->data_offset;
-                if (p < p_end) {
-#if defined(TCC_TARGET_I386)
-                    put32(p + 2, get32(p + 2) + s1->got->sh_addr);
-                    put32(p + 8, get32(p + 8) + s1->got->sh_addr);
-                    p += 16;
-                    while (p < p_end) {
-                        put32(p + 2, get32(p + 2) + s1->got->sh_addr);
-                        p += 16;
-                    }
-#elif defined(TCC_TARGET_X86_64)
-                    int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
-                    put32(p + 2, get32(p + 2) + x);
-                    put32(p + 8, get32(p + 8) + x - 6);
-                    p += 16;
-                    while (p < p_end) {
-                        put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
-                        p += 16;
-                    }
-#elif defined(TCC_TARGET_ARM)
-                    int x;
-                    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
-                    p += 16;
-                    while (p < p_end) {
-                        if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
-                            p += 4;
-                        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
-                        p += 16;
-                    }
-#elif defined(TCC_TARGET_C67)
-                    /* XXX: TODO */
-#elif  defined(TCC_TARGET_IL)
-#else
-#error unsupported CPU
-#endif
-                }
-            }
-
-            /* relocate symbols in .dynsym */
-            sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
-            for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; 
-                sym < sym_end;
-                sym++) {
-                if (sym->st_shndx == SHN_UNDEF) {
-                    /* relocate to the PLT if the symbol corresponds
-                       to a PLT entry */
-                    if (sym->st_value)
-                        sym->st_value += s1->plt->sh_addr;
-                } else if (sym->st_shndx < SHN_LORESERVE) {
-                    /* do symbol relocation */
-                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
-                }
-            }
-
-            /* put dynamic section entries */
-            dynamic->data_offset = saved_dynamic_data_offset;
-            put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
-            put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
-            put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
-            put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
-            put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
-#ifdef TCC_TARGET_X86_64
-            put_dt(dynamic, DT_RELA, rel_addr);
-            put_dt(dynamic, DT_RELASZ, rel_size);
-            put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
-#else
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-            put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
-            put_dt(dynamic, DT_PLTRELSZ, rel_size);
-            put_dt(dynamic, DT_JMPREL, rel_addr);
-            put_dt(dynamic, DT_PLTREL, DT_REL);
-            put_dt(dynamic, DT_REL, bss_addr);
-            put_dt(dynamic, DT_RELSZ, bss_size);
-#else
-            put_dt(dynamic, DT_REL, rel_addr);
-            put_dt(dynamic, DT_RELSZ, rel_size);
-            put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
-#endif
-#endif
-            if (s1->do_debug)
-                put_dt(dynamic, DT_DEBUG, 0);
-            put_dt(dynamic, DT_NULL, 0);
-        }
-
-        ehdr.e_phentsize = sizeof(ElfW(Phdr));
-        ehdr.e_phnum = phnum;
-        ehdr.e_phoff = sizeof(ElfW(Ehdr));
     }
 
@@ -2156,7 +1727,7 @@
         if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
             continue;
-        section_order[sh_order_index++] = i;
-        
-        file_offset = (file_offset + s->sh_addralign - 1) & 
+        sec_order[sh_order_index++] = i;
+
+        file_offset = (file_offset + s->sh_addralign - 1) &
             ~(s->sh_addralign - 1);
         s->sh_offset = file_offset;
@@ -2164,44 +1735,251 @@
             file_offset += s->sh_size;
     }
-    
-    /* if building executable or DLL, then relocate each section
-       except the GOT which is already relocated */
-    if (file_type != TCC_OUTPUT_OBJ) {
-        relocate_syms(s1, 0);
-
-        if (s1->nb_errors != 0) {
-        fail:
-            ret = -1;
-            goto the_end;
-        }
-
-        /* relocate sections */
-        /* XXX: ignore sections with allocated relocations ? */
-        for(i = 1; i < s1->nb_sections; i++) {
-            s = s1->sections[i];
-            if (s->reloc && s != s1->got)
-                relocate_section(s1, s);
-        }
-
-        /* relocate relocation entries if the relocation tables are
-           allocated in the executable */
-        for(i = 1; i < s1->nb_sections; i++) {
-            s = s1->sections[i];
-            if ((s->sh_flags & SHF_ALLOC) &&
-                s->sh_type == SHT_RELX) {
-                relocate_rel(s1, s);
-            }
-        }
-
-        /* get entry point address */
-        if (file_type == TCC_OUTPUT_EXE)
-            ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
-        else
-            ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
-    }
-    if (file_type == TCC_OUTPUT_EXE && s1->static_link)
-        fill_got(s1);
-
-    /* write elf file */
+
+    return file_offset;
+}
+
+static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
+                                 Section *dynamic)
+{
+    ElfW(Phdr) *ph;
+
+    /* if interpreter, then add corresponding program header */
+    if (interp) {
+        ph = &phdr[0];
+
+        ph->p_type = PT_PHDR;
+        ph->p_offset = sizeof(ElfW(Ehdr));
+        ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
+        ph->p_vaddr = interp->sh_addr - ph->p_filesz;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_flags = PF_R | PF_X;
+        ph->p_align = 4; /* interp->sh_addralign; */
+        ph++;
+
+        ph->p_type = PT_INTERP;
+        ph->p_offset = interp->sh_offset;
+        ph->p_vaddr = interp->sh_addr;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_filesz = interp->sh_size;
+        ph->p_memsz = interp->sh_size;
+        ph->p_flags = PF_R;
+        ph->p_align = interp->sh_addralign;
+    }
+
+    /* if dynamic section, then add corresponding program header */
+    if (dynamic) {
+        ph = &phdr[phnum - 1];
+
+        ph->p_type = PT_DYNAMIC;
+        ph->p_offset = dynamic->sh_offset;
+        ph->p_vaddr = dynamic->sh_addr;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_filesz = dynamic->sh_size;
+        ph->p_memsz = dynamic->sh_size;
+        ph->p_flags = PF_R | PF_W;
+        ph->p_align = dynamic->sh_addralign;
+    }
+}
+
+/* Fill the dynamic section with tags describing the address and size of
+   sections */
+static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
+{
+    Section *dynamic = dyninf->dynamic;
+
+    /* put dynamic section entries */
+    put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
+    put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
+    put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
+    put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
+    put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
+#if PTR_SIZE == 8
+    put_dt(dynamic, DT_RELA, dyninf->rel_addr);
+    put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
+    put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
+#else
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
+    put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
+    put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
+    put_dt(dynamic, DT_PLTREL, DT_REL);
+    put_dt(dynamic, DT_REL, dyninf->bss_addr);
+    put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
+#else
+    put_dt(dynamic, DT_REL, dyninf->rel_addr);
+    put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
+    put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
+#endif
+#endif
+    if (s1->do_debug)
+        put_dt(dynamic, DT_DEBUG, 0);
+    put_dt(dynamic, DT_NULL, 0);
+}
+
+/* Relocate remaining sections and symbols (that is those not related to
+   dynamic linking) */
+static int final_sections_reloc(TCCState *s1)
+{
+    int i;
+    Section *s;
+
+    relocate_syms(s1, s1->symtab, 0);
+
+    if (s1->nb_errors != 0)
+        return -1;
+
+    /* relocate sections */
+    /* XXX: ignore sections with allocated relocations ? */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
+        if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
+        /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
+        checking is removed */
+#else
+        if (s->reloc && s != s1->got)
+        /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
+#endif
+            relocate_section(s1, s);
+    }
+
+    /* relocate relocation entries if the relocation tables are
+       allocated in the executable */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if ((s->sh_flags & SHF_ALLOC) &&
+            s->sh_type == SHT_RELX) {
+            relocate_rel(s1, s);
+        }
+    }
+    return 0;
+}
+
+/* Create an ELF file on disk.
+   This function handle ELF specific layout requirements */
+static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
+                           int file_offset, int *sec_order)
+{
+    int i, shnum, offset, size, file_type;
+    Section *s;
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) shdr, *sh;
+
+    file_type = s1->output_type;
+    shnum = s1->nb_sections;
+
+    memset(&ehdr, 0, sizeof(ehdr));
+
+    if (phnum > 0) {
+        ehdr.e_phentsize = sizeof(ElfW(Phdr));
+        ehdr.e_phnum = phnum;
+        ehdr.e_phoff = sizeof(ElfW(Ehdr));
+    }
+
+    /* align to 4 */
+    file_offset = (file_offset + 3) & -4;
+
+    /* fill header */
+    ehdr.e_ident[0] = ELFMAG0;
+    ehdr.e_ident[1] = ELFMAG1;
+    ehdr.e_ident[2] = ELFMAG2;
+    ehdr.e_ident[3] = ELFMAG3;
+    ehdr.e_ident[4] = ELFCLASSW;
+    ehdr.e_ident[5] = ELFDATA2LSB;
+    ehdr.e_ident[6] = EV_CURRENT;
+#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
+    /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
+    ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+#ifdef TCC_TARGET_ARM
+#ifdef TCC_ARM_EABI
+    ehdr.e_ident[EI_OSABI] = 0;
+    ehdr.e_flags = EF_ARM_EABI_VER4;
+    if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
+        ehdr.e_flags |= EF_ARM_HASENTRY;
+    if (s1->float_abi == ARM_HARD_FLOAT)
+        ehdr.e_flags |= EF_ARM_VFP_FLOAT;
+    else
+        ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
+#else
+    ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
+#endif
+#endif
+    switch(file_type) {
+    default:
+    case TCC_OUTPUT_EXE:
+        ehdr.e_type = ET_EXEC;
+        ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
+        break;
+    case TCC_OUTPUT_DLL:
+        ehdr.e_type = ET_DYN;
+        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
+        break;
+    case TCC_OUTPUT_OBJ:
+        ehdr.e_type = ET_REL;
+        break;
+    }
+    ehdr.e_machine = EM_TCC_TARGET;
+    ehdr.e_version = EV_CURRENT;
+    ehdr.e_shoff = file_offset;
+    ehdr.e_ehsize = sizeof(ElfW(Ehdr));
+    ehdr.e_shentsize = sizeof(ElfW(Shdr));
+    ehdr.e_shnum = shnum;
+    ehdr.e_shstrndx = shnum - 1;
+
+    fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
+    fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
+    offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+
+    sort_syms(s1, symtab_section);
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[sec_order[i]];
+        if (s->sh_type != SHT_NOBITS) {
+            while (offset < s->sh_offset) {
+                fputc(0, f);
+                offset++;
+            }
+            size = s->sh_size;
+            if (size)
+                fwrite(s->data, 1, size, f);
+            offset += size;
+        }
+    }
+
+    /* output section headers */
+    while (offset < ehdr.e_shoff) {
+        fputc(0, f);
+        offset++;
+    }
+
+    for(i = 0; i < s1->nb_sections; i++) {
+        sh = &shdr;
+        memset(sh, 0, sizeof(ElfW(Shdr)));
+        s = s1->sections[i];
+        if (s) {
+            sh->sh_name = s->sh_name;
+            sh->sh_type = s->sh_type;
+            sh->sh_flags = s->sh_flags;
+            sh->sh_entsize = s->sh_entsize;
+            sh->sh_info = s->sh_info;
+            if (s->link)
+                sh->sh_link = s->link->sh_num;
+            sh->sh_addralign = s->sh_addralign;
+            sh->sh_addr = s->sh_addr;
+            sh->sh_offset = s->sh_offset;
+            sh->sh_size = s->sh_size;
+        }
+        fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
+    }
+}
+
+/* Write an elf, coff or "binary" file */
+static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
+                              ElfW(Phdr) *phdr, int file_offset, int *sec_order)
+{
+    int fd, mode, file_type;
+    FILE *f;
+
+    file_type = s1->output_type;
     if (file_type == TCC_OUTPUT_OBJ)
         mode = 0666;
@@ -2209,8 +1987,8 @@
         mode = 0777;
     unlink(filename);
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
     if (fd < 0) {
         tcc_error_noabort("could not write '%s'", filename);
-        goto fail;
+        return -1;
     }
     f = fdopen(fd, "wb");
@@ -2219,108 +1997,235 @@
 
 #ifdef TCC_TARGET_COFF
-    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
+    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
         tcc_output_coff(s1, f);
-    } else
-#endif
-    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
-        sort_syms(s1, symtab_section);
-        
-        /* align to 4 */
-        file_offset = (file_offset + 3) & -4;
-    
-        /* fill header */
-        ehdr.e_ident[0] = ELFMAG0;
-        ehdr.e_ident[1] = ELFMAG1;
-        ehdr.e_ident[2] = ELFMAG2;
-        ehdr.e_ident[3] = ELFMAG3;
-        ehdr.e_ident[4] = ELFCLASSW;
-        ehdr.e_ident[5] = ELFDATA2LSB;
-        ehdr.e_ident[6] = EV_CURRENT;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-        ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
-#endif
-#ifdef TCC_TARGET_ARM
-#ifdef TCC_ARM_EABI
-        ehdr.e_ident[EI_OSABI] = 0;
-        ehdr.e_flags = 4 << 24;
-#else
-        ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
-#endif
-#endif
-        switch(file_type) {
-        default:
-        case TCC_OUTPUT_EXE:
-            ehdr.e_type = ET_EXEC;
-            break;
-        case TCC_OUTPUT_DLL:
-            ehdr.e_type = ET_DYN;
-            break;
-        case TCC_OUTPUT_OBJ:
-            ehdr.e_type = ET_REL;
-            break;
-        }
-        ehdr.e_machine = EM_TCC_TARGET;
-        ehdr.e_version = EV_CURRENT;
-        ehdr.e_shoff = file_offset;
-        ehdr.e_ehsize = sizeof(ElfW(Ehdr));
-        ehdr.e_shentsize = sizeof(ElfW(Shdr));
-        ehdr.e_shnum = shnum;
-        ehdr.e_shstrndx = shnum - 1;
-        
-        fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
-        fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
-        offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
-
-        for(i=1;i<s1->nb_sections;i++) {
-            s = s1->sections[section_order[i]];
-            if (s->sh_type != SHT_NOBITS) {
-		if (s->sh_type == SHT_DYNSYM)
-		    patch_dynsym_undef(s1, s);
-                while (offset < s->sh_offset) {
-                    fputc(0, f);
-                    offset++;
+    else
+#endif
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
+        tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
+    else
+        tcc_output_binary(s1, f, sec_order);
+    fclose(f);
+
+    return 0;
+}
+
+/* Sort section headers by assigned sh_addr, remove sections
+   that we aren't going to output.  */
+static void tidy_section_headers(TCCState *s1, int *sec_order)
+{
+    int i, nnew, l, *backmap;
+    Section **snew, *s;
+    ElfW(Sym) *sym;
+
+    snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
+    backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
+    for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
+	s = s1->sections[sec_order[i]];
+	if (!i || s->sh_name) {
+	    backmap[sec_order[i]] = nnew;
+	    snew[nnew] = s;
+	    ++nnew;
+	} else {
+	    backmap[sec_order[i]] = 0;
+	    snew[--l] = s;
+	}
+    }
+    for (i = 0; i < nnew; i++) {
+	s = snew[i];
+	if (s) {
+	    s->sh_num = i;
+            if (s->sh_type == SHT_RELX)
+		s->sh_info = backmap[s->sh_info];
+	}
+    }
+
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym))
+	if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+	    sym->st_shndx = backmap[sym->st_shndx];
+    if( !s1->static_link ) {
+        for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
+	    if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+	        sym->st_shndx = backmap[sym->st_shndx];
+    }
+    for (i = 0; i < s1->nb_sections; i++)
+	sec_order[i] = i;
+    tcc_free(s1->sections);
+    s1->sections = snew;
+    s1->nb_sections = nnew;
+    tcc_free(backmap);
+}
+
+/* Output an elf, coff or binary file */
+/* XXX: suppress unneeded sections */
+static int elf_output_file(TCCState *s1, const char *filename)
+{
+    int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
+    struct dyn_inf dyninf = {0};
+    ElfW(Phdr) *phdr;
+    ElfW(Sym) *sym;
+    Section *strsec, *interp, *dynamic, *dynstr;
+    int textrel;
+
+    file_type = s1->output_type;
+    s1->nb_errors = 0;
+    ret = -1;
+    phdr = NULL;
+    sec_order = NULL;
+    interp = dynamic = dynstr = NULL; /* avoid warning */
+    textrel = 0;
+
+    if (file_type != TCC_OUTPUT_OBJ) {
+        /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
+        tcc_add_runtime(s1);
+	resolve_common_syms(s1);
+
+        if (!s1->static_link) {
+            if (file_type == TCC_OUTPUT_EXE) {
+                char *ptr;
+                /* allow override the dynamic loader */
+                const char *elfint = getenv("LD_SO");
+                if (elfint == NULL)
+                    elfint = DEFAULT_ELFINTERP(s1);
+                /* add interpreter section only if executable */
+                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
+                interp->sh_addralign = 1;
+                ptr = section_ptr_add(interp, 1 + strlen(elfint));
+                strcpy(ptr, elfint);
+            }
+
+            /* add dynamic symbol table */
+            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
+                                    ".dynstr",
+                                    ".hash", SHF_ALLOC);
+            dynstr = s1->dynsym->link;
+
+            /* add dynamic section */
+            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
+                                  SHF_ALLOC | SHF_WRITE);
+            dynamic->link = dynstr;
+            dynamic->sh_entsize = sizeof(ElfW(Dyn));
+
+            build_got(s1);
+
+            if (file_type == TCC_OUTPUT_EXE) {
+                bind_exe_dynsyms(s1);
+                if (s1->nb_errors)
+                    goto the_end;
+                bind_libs_dynsyms(s1);
+            } else {
+                /* shared library case: simply export all global symbols */
+                export_global_syms(s1);
+            }
+        }
+        build_got_entries(s1);
+    }
+
+    /* we add a section for symbols */
+    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
+    put_elf_str(strsec, "");
+
+    /* Allocate strings for section names */
+    textrel = alloc_sec_names(s1, file_type, strsec);
+
+    if (dynamic) {
+        /* add a list of needed dlls */
+        for(i = 0; i < s1->nb_loaded_dlls; i++) {
+            DLLReference *dllref = s1->loaded_dlls[i];
+            if (dllref->level == 0)
+                put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
+        }
+
+        if (s1->rpath)
+            put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
+                   put_elf_str(dynstr, s1->rpath));
+
+        if (file_type == TCC_OUTPUT_DLL) {
+            if (s1->soname)
+                put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
+            /* XXX: currently, since we do not handle PIC code, we
+               must relocate the readonly segments */
+            if (textrel)
+                put_dt(dynamic, DT_TEXTREL, 0);
+        }
+
+        if (s1->symbolic)
+            put_dt(dynamic, DT_SYMBOLIC, 0);
+
+        dyninf.dynamic = dynamic;
+        dyninf.dynstr = dynstr;
+        /* remember offset and reserve space for 2nd call below */
+        dyninf.data_offset = dynamic->data_offset;
+        fill_dynamic(s1, &dyninf);
+        dynamic->sh_size = dynamic->data_offset;
+        dynstr->sh_size = dynstr->data_offset;
+    }
+
+    /* compute number of program headers */
+    if (file_type == TCC_OUTPUT_OBJ)
+        phnum = 0;
+    else if (file_type == TCC_OUTPUT_DLL)
+        phnum = 3;
+    else if (s1->static_link)
+        phnum = 2;
+    else
+        phnum = 5;
+
+    /* allocate program segment headers */
+    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
+
+    /* compute number of sections */
+    shnum = s1->nb_sections;
+
+    /* this array is used to reorder sections in the output file */
+    sec_order = tcc_malloc(sizeof(int) * shnum);
+    sec_order[0] = 0;
+
+    /* compute section to program header mapping */
+    file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
+                                  sec_order);
+
+    /* Fill remaining program header and finalize relocation related to dynamic
+       linking. */
+    if (file_type != TCC_OUTPUT_OBJ) {
+        fill_unloadable_phdr(phdr, phnum, interp, dynamic);
+        if (dynamic) {
+            dynamic->data_offset = dyninf.data_offset;
+            fill_dynamic(s1, &dyninf);
+
+            /* put in GOT the dynamic section address and relocate PLT */
+            write32le(s1->got->data, dynamic->sh_addr);
+            if (file_type == TCC_OUTPUT_EXE
+                || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
+                relocate_plt(s1);
+
+            /* relocate symbols in .dynsym now that final addresses are known */
+            for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
+                if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
+                    /* do symbol relocation */
+                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
                 }
-                size = s->sh_size;
-                fwrite(s->data, 1, size, f);
-                offset += size;
-            }
-        }
-
-        /* output section headers */
-        while (offset < ehdr.e_shoff) {
-            fputc(0, f);
-            offset++;
-        }
-    
-        for(i=0;i<s1->nb_sections;i++) {
-            sh = &shdr;
-            memset(sh, 0, sizeof(ElfW(Shdr)));
-            s = s1->sections[i];
-            if (s) {
-                sh->sh_name = s->sh_name;
-                sh->sh_type = s->sh_type;
-                sh->sh_flags = s->sh_flags;
-                sh->sh_entsize = s->sh_entsize;
-                sh->sh_info = s->sh_info;
-                if (s->link)
-                    sh->sh_link = s->link->sh_num;
-                sh->sh_addralign = s->sh_addralign;
-                sh->sh_addr = s->sh_addr;
-                sh->sh_offset = s->sh_offset;
-                sh->sh_size = s->sh_size;
-            }
-            fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
-        }
-    } else {
-        tcc_output_binary(s1, f, section_order);
-    }
-    fclose(f);
-
-    ret = 0;
+            }
+        }
+
+        /* if building executable or DLL, then relocate each section
+           except the GOT which is already relocated */
+        ret = final_sections_reloc(s1);
+        if (ret)
+            goto the_end;
+	tidy_section_headers(s1, sec_order);
+
+        /* Perform relocation to GOT or PLT entries */
+        if (file_type == TCC_OUTPUT_EXE && s1->static_link)
+            fill_got(s1);
+        else if (s1->got)
+            fill_local_got_entries(s1);
+    }
+
+    /* Create the ELF file with name 'filename' */
+    ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
+    s1->nb_sections = shnum;
  the_end:
-    tcc_free(s1->symtab_to_dynsym);
-    tcc_free(section_order);
+    tcc_free(sec_order);
     tcc_free(phdr);
-    tcc_free(s1->sym_attrs);
     return ret;
 }
@@ -2334,7 +2239,5 @@
     } else
 #endif
-    {
         ret = elf_output_file(s, filename);
-    }
     return ret;
 }
@@ -2357,12 +2260,31 @@
 } SectionMergeInfo;
 
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
+{
+    int size = read(fd, h, sizeof *h);
+    if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
+        if (h->e_type == ET_REL)
+            return AFF_BINTYPE_REL;
+        if (h->e_type == ET_DYN)
+            return AFF_BINTYPE_DYN;
+    } else if (size >= 8) {
+        if (0 == memcmp(h, ARMAG, 8))
+            return AFF_BINTYPE_AR;
+#ifdef TCC_TARGET_COFF
+        if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
+            return AFF_BINTYPE_C67;
+#endif
+    }
+    return 0;
+}
+
 /* load an object file and merge it with current files */
 /* XXX: handle correctly stab (debug) info */
-ST_FUNC int tcc_load_object_file(TCCState *s1, 
+ST_FUNC int tcc_load_object_file(TCCState *s1,
                                 int fd, unsigned long file_offset)
-{ 
+{
     ElfW(Ehdr) ehdr;
     ElfW(Shdr) *shdr, *sh;
-    int size, i, j, offset, offseti, nb_syms, sym_index, ret;
+    int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
     unsigned char *strsec, *strtab;
     int *old_to_new_syms;
@@ -2370,5 +2292,5 @@
     SectionMergeInfo *sm_table, *sm;
     ElfW(Sym) *sym, *symtab;
-    ElfW_Rel *rel, *rel_end;
+    ElfW_Rel *rel;
     Section *s;
 
@@ -2378,13 +2300,6 @@
     stab_index = stabstr_index = 0;
 
-    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
-        goto fail1;
-    if (ehdr.e_ident[0] != ELFMAG0 ||
-        ehdr.e_ident[1] != ELFMAG1 ||
-        ehdr.e_ident[2] != ELFMAG2 ||
-        ehdr.e_ident[3] != ELFMAG3)
-        goto fail1;
-    /* test if object file */
-    if (ehdr.e_type != ET_REL)
+    lseek(fd, file_offset, SEEK_SET);
+    if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
         goto fail1;
     /* test CPU specific stuff */
@@ -2396,8 +2311,8 @@
     }
     /* read sections */
-    shdr = load_data(fd, file_offset + ehdr.e_shoff, 
+    shdr = load_data(fd, file_offset + ehdr.e_shoff,
                      sizeof(ElfW(Shdr)) * ehdr.e_shnum);
     sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
-    
+
     /* load section names */
     sh = &shdr[ehdr.e_shstrndx];
@@ -2409,4 +2324,5 @@
     strtab = NULL;
     nb_syms = 0;
+    seencompressed = 0;
     for(i = 1; i < ehdr.e_shnum; i++) {
         sh = &shdr[i];
@@ -2426,6 +2342,8 @@
             strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
         }
-    }
-        
+	if (sh->sh_flags & SHF_COMPRESSED)
+	    seencompressed = 1;
+    }
+
     /* now examine each section and try to merge its content with the
        ones in memory */
@@ -2435,12 +2353,12 @@
             continue;
         sh = &shdr[i];
-        sh_name = strsec + sh->sh_name;
+        sh_name = (char *) strsec + sh->sh_name;
         /* ignore sections types we do not handle */
         if (sh->sh_type != SHT_PROGBITS &&
-            sh->sh_type != SHT_RELX && 
+            sh->sh_type != SHT_RELX &&
 #ifdef TCC_ARM_EABI
             sh->sh_type != SHT_ARM_EXIDX &&
 #endif
-            sh->sh_type != SHT_NOBITS && 
+            sh->sh_type != SHT_NOBITS &&
             sh->sh_type != SHT_PREINIT_ARRAY &&
             sh->sh_type != SHT_INIT_ARRAY &&
@@ -2449,4 +2367,10 @@
             )
             continue;
+	if (seencompressed
+	    && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
+		|| (sh->sh_type == SHT_RELX
+		    && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
+			        ".debug_", sizeof(".debug_")-1))))
+	  continue;
         if (sh->sh_addralign < 1)
             sh->sh_addralign = 1;
@@ -2455,5 +2379,5 @@
             s = s1->sections[j];
             if (!strcmp(s->name, sh_name)) {
-                if (!strncmp(sh_name, ".gnu.linkonce", 
+                if (!strncmp(sh_name, ".gnu.linkonce",
                              sizeof(".gnu.linkonce") - 1)) {
                     /* if a 'linkonce' section is already present, we
@@ -2469,5 +2393,5 @@
         }
         /* not found: create new section */
-        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
+        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
         /* take as much info as possible from the section. sh_link and
            sh_info will be updated later */
@@ -2514,5 +2438,5 @@
     }
 
-    /* //gr relocate stab strings */
+    /* gr relocate stab strings */
     if (stab_index && stabstr_index) {
         Stab_Sym *a, *b;
@@ -2522,5 +2446,5 @@
         b = (Stab_Sym *)(s->data + s->data_offset);
         o = sm_table[stabstr_index].offset;
-        while (a < b) 
+        while (a < b)
             a->n_strx += o, a++;
     }
@@ -2556,5 +2480,5 @@
                    correct relocations */
                 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
-                    name = strtab + sym->st_name;
+                    name = (char *) strtab + sym->st_name;
                     sym_index = find_elf_sym(symtab_section, name);
                     if (sym_index)
@@ -2572,7 +2496,7 @@
         }
         /* add symbol */
-        name = strtab + sym->st_name;
-        sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 
-                                sym->st_info, sym->st_other, 
+        name = (char *) strtab + sym->st_name;
+        sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
+                                sym->st_info, sym->st_other,
                                 sym->st_shndx, name);
         old_to_new_syms[i] = sym_index;
@@ -2590,8 +2514,5 @@
             /* take relocation offset information */
             offseti = sm_table[sh->sh_info].offset;
-            rel_end = (ElfW_Rel *)(s->data + s->data_offset);
-            for(rel = (ElfW_Rel *)(s->data + offset);
-                rel < rel_end;
-                rel++) {
+            for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
                 int type;
                 unsigned sym_index;
@@ -2624,8 +2545,8 @@
                    instructions. Other case of instructions referencing a PLT
                    entry require to add a Thumb stub before the PLT entry to
-                   switch to ARM mode. We set bit 0 of the got offset of a
-                   symbol to indicate such a case. */
+                   switch to ARM mode. We set bit plt_thumb_stub of the
+                   attribute of a symbol to indicate such a case. */
                 if (type == R_ARM_THM_JUMP24)
-                    alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
+                    get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
 #endif
             }
@@ -2635,5 +2556,5 @@
         }
     }
-    
+
     ret = 0;
  the_end:
@@ -2662,8 +2583,15 @@
 }
 
+static long get_be64(const uint8_t *b)
+{
+  long long ret = get_be32(b);
+  ret = (ret << 32) | (unsigned)get_be32(b+4);
+  return (long)ret;
+}
+
 /* load only the objects which resolve undefined symbols */
-static int tcc_load_alacarte(TCCState *s1, int fd, int size)
-{
-    int i, bound, nsyms, sym_index, off, ret;
+static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
+{
+    long i, bound, nsyms, sym_index, off, ret;
     uint8_t *data;
     const char *ar_names, *p;
@@ -2674,7 +2602,7 @@
     if (read(fd, data, size) != size)
         goto fail;
-    nsyms = get_be32(data);
-    ar_index = data + 4;
-    ar_names = ar_index + nsyms * 4;
+    nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
+    ar_index = data + entrysize;
+    ar_names = (char *) ar_index + nsyms * entrysize;
 
     do {
@@ -2685,10 +2613,9 @@
                 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
                 if(sym->st_shndx == SHN_UNDEF) {
-                    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
-#if 0
-                    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
-#endif
+                    off = (entrysize == 4
+			   ? get_be32(ar_index + i * 4)
+			   : get_be64(ar_index + i * 8))
+			  + sizeof(ArchiveHeader);
                     ++bound;
-                    lseek(fd, off, SEEK_SET);
                     if(tcc_load_object_file(s1, fd, off) < 0) {
                     fail:
@@ -2718,5 +2645,5 @@
     /* skip magic which was already checked */
     read(fd, magic, sizeof(magic));
-    
+
     for(;;) {
         len = read(fd, &hdr, sizeof(hdr));
@@ -2736,5 +2663,4 @@
         }
         ar_name[i + 1] = '\0';
-        //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
         file_offset = lseek(fd, 0, SEEK_CUR);
         /* align to even */
@@ -2743,13 +2669,14 @@
             /* coff symbol table : we handle it */
             if(s1->alacarte_link)
-                return tcc_load_alacarte(s1, fd, size);
-        } else if (!strcmp(ar_name, "//") ||
-                   !strcmp(ar_name, "__.SYMDEF") ||
-                   !strcmp(ar_name, "__.SYMDEF/") ||
-                   !strcmp(ar_name, "ARFILENAMES/")) {
-            /* skip symbol table or archive names */
+                return tcc_load_alacarte(s1, fd, size, 4);
+	} else if (!strcmp(ar_name, "/SYM64/")) {
+            if(s1->alacarte_link)
+                return tcc_load_alacarte(s1, fd, size, 8);
         } else {
-            if (tcc_load_object_file(s1, fd, file_offset) < 0)
-                return -1;
+            ElfW(Ehdr) ehdr;
+            if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
+                if (tcc_load_object_file(s1, fd, file_offset) < 0)
+                    return -1;
+            }
         }
         lseek(fd, file_offset + size, SEEK_SET);
@@ -2763,5 +2690,5 @@
    the generated ELF file) */
 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
-{ 
+{
     ElfW(Ehdr) ehdr;
     ElfW(Shdr) *shdr, *sh, *sh1;
@@ -2772,5 +2699,5 @@
     const char *name, *soname;
     DLLReference *dllref;
-    
+
     read(fd, &ehdr, sizeof(ehdr));
 
@@ -2807,11 +2734,11 @@
         }
     }
-    
+
     /* compute the real library name */
     soname = tcc_basename(filename);
-        
+
     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
         if (dt->d_tag == DT_SONAME) {
-            soname = dynstr + dt->d_un.d_val;
+            soname = (char *) dynstr + dt->d_un.d_val;
         }
     }
@@ -2828,6 +2755,4 @@
         }
     }
-    
-    //    printf("loading dll '%s'\n", soname);
 
     /* add the dll and its level */
@@ -2835,5 +2760,5 @@
     dllref->level = level;
     strcpy(dllref->name, soname);
-    dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
 
     /* add dynamic symbols in dynsym_section */
@@ -2842,6 +2767,6 @@
         if (sym_bind == STB_LOCAL)
             continue;
-        name = dynstr + sym->st_name;
-        add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
+        name = (char *) dynstr + sym->st_name;
+        set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
                     sym->st_info, sym->st_other, sym->st_shndx, name);
     }
@@ -2851,5 +2776,5 @@
         switch(dt->d_tag) {
         case DT_NEEDED:
-            name = dynstr + dt->d_un.d_val;
+            name = (char *) dynstr + dt->d_un.d_val;
             for(j = 0; j < s1->nb_loaded_dlls; j++) {
                 dllref = s1->loaded_dlls[j];
@@ -2906,4 +2831,9 @@
         }
         break;
+    case '\\':
+        ch = handle_eob();
+        if (ch != '\\')
+            goto redo;
+        /* fall through */
     /* case 'a' ... 'z': */
     case 'a':
@@ -2961,5 +2891,4 @@
        case 'Z':
     case '_':
-    case '\\':
     case '.':
     case '$':
@@ -2989,9 +2918,4 @@
         break;
     }
-#if 0
-    printf("tok=%c %d\n", c, c);
-    if (c == LD_TOK_NAME)
-        printf("  name=%s\n", name);
-#endif
     return c;
 }
@@ -2999,10 +2923,11 @@
 static int ld_add_file(TCCState *s1, const char filename[])
 {
-    int ret;
-
-    ret = tcc_add_file_internal(s1, filename, 0);
-    if (ret)
-        ret = tcc_add_dll(s1, filename, 0);
-    return ret;
+    if (filename[0] == '/') {
+        if (CONFIG_SYSROOT[0] == '\0'
+            && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
+            return 0;
+        filename = tcc_basename(filename);
+    }
+    return tcc_add_dll(s1, filename, 0);
 }
 
@@ -3066,7 +2991,7 @@
                 if (group) {
                     /* Add the filename *and* the libname to avoid future conversions */
-                    dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
+                    dynarray_add(&libs, &nblibs, tcc_strdup(filename));
                     if (libname[0] != '\0')
-                        dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
+                        dynarray_add(&libs, &nblibs, tcc_strdup(libname));
                 }
             }
@@ -3097,6 +3022,5 @@
     char filename[1024];
     int t, ret;
-    
-    ch = file->buf_ptr[0];
+
     ch = handle_eob();
     for(;;) {
@@ -3132,3 +3056,3 @@
     return 0;
 }
-#endif /* ndef TCC_TARGET_PE */
+#endif /* !TCC_TARGET_PE */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccgen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c	(revision 331)
@@ -31,18 +31,4 @@
 ST_DATA int rsym, anon_sym, ind, loc;
 
-ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
-ST_DATA Section *cur_text_section; /* current section where function code is generated */
-#ifdef CONFIG_TCC_ASM
-ST_DATA Section *last_text_section; /* to handle .previous asm directive */
-#endif
-#ifdef CONFIG_TCC_BCHECK
-/* bound check related sections */
-ST_DATA Section *bounds_section; /* contains global data bound description */
-ST_DATA Section *lbounds_section; /* contains local data bound description */
-#endif
-/* symbol sections */
-ST_DATA Section *symtab_section, *strtab_section;
-/* debug sections */
-ST_DATA Section *stab_section, *stabstr_section;
 ST_DATA Sym *sym_free_first;
 ST_DATA void **sym_pools;
@@ -51,37 +37,66 @@
 ST_DATA Sym *global_stack;
 ST_DATA Sym *local_stack;
-ST_DATA Sym *scope_stack_bottom;
 ST_DATA Sym *define_stack;
 ST_DATA Sym *global_label_stack;
 ST_DATA Sym *local_label_stack;
-
-ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop;
+static int local_scope;
+static int in_sizeof;
+static int section_sym;
+
+ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
+ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
+ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
+
+ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
 
 ST_DATA int const_wanted; /* true if constant wanted */
-ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
+ST_DATA int nocode_wanted; /* no code generation wanted */
+#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
+#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
 ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
 ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
 ST_DATA int func_vc;
 ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
-ST_DATA char *funcname;
-
-ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
+
+ST_DATA struct switch_t {
+    struct case_t {
+        int64_t v1, v2;
+	int sym;
+    } **p; int n; /* list of case ranges */
+    int def_sym; /* default symbol */
+} *cur_switch; /* current switch */
 
 /* ------------------------------------------------------------------------- */
+
 static void gen_cast(CType *type);
+static void gen_cast_s(int t);
 static inline CType *pointed_type(CType *type);
 static int is_compatible_types(CType *type1, CType *type2);
 static int parse_btype(CType *type, AttributeDef *ad);
-static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
 static void parse_expr_type(CType *type);
+static void init_putv(CType *type, Section *sec, unsigned long c);
 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
-static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr);
-static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, char *asm_label, int scope);
-static int decl0(int l, int is_for_loop_init);
+static void block(int *bsym, int *csym, int is_expr);
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
+static void decl(int l);
+static int decl0(int l, int is_for_loop_init, Sym *);
 static void expr_eq(void);
-static void unary_type(CType *type);
 static void vla_runtime_type_size(CType *type, int *a);
-static int is_compatible_parameter_types(CType *type1, CType *type2);
-static void expr_type(CType *type);
+static void vla_sp_restore(void);
+static void vla_sp_restore_root(void);
+static int is_compatible_unqualified_types(CType *type1, CType *type2);
+static inline int64_t expr_const64(void);
+static void vpush64(int ty, unsigned long long v);
+static void vpush(CType *type);
+static int gvtst(int inv, int t);
+static void gen_inline_functions(TCCState *s);
+static void skip_or_save_block(TokenString **str);
+static void gv_dup(void);
 
 ST_INLN int is_float(int t)
@@ -89,5 +104,5 @@
     int bt;
     bt = t & VT_BTYPE;
-    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
+    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
 }
 
@@ -97,7 +112,14 @@
 ST_FUNC int ieee_finite(double d)
 {
-    int *p = (int *)&d;
+    int p[4];
+    memcpy(p, &d, sizeof(double));
     return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
 }
+
+/* compiling intel long double natively */
+#if (defined __i386__ || defined __x86_64__) \
+    && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+# define TCC_IS_NATIVE_387
+#endif
 
 ST_FUNC void test_lvalue(void)
@@ -106,4 +128,327 @@
         expect("lvalue");
 }
+
+ST_FUNC void check_vstack(void)
+{
+    if (pvtop != vtop)
+        tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
+}
+
+/* ------------------------------------------------------------------------- */
+/* vstack debugging aid */
+
+#if 0
+void pv (const char *lbl, int a, int b)
+{
+    int i;
+    for (i = a; i < a + b; ++i) {
+        SValue *p = &vtop[-i];
+        printf("%s vtop[-%d] : type.t:%04x  r:%04x  r2:%04x  c.i:%d\n",
+            lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
+    }
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* start of translation unit info */
+ST_FUNC void tcc_debug_start(TCCState *s1)
+{
+    if (s1->do_debug) {
+        char buf[512];
+
+        /* file info: full path + filename */
+        section_sym = put_elf_sym(symtab_section, 0, 0,
+                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
+                                  text_section->sh_num, NULL);
+        getcwd(buf, sizeof(buf));
+#ifdef _WIN32
+        normalize_slashes(buf);
+#endif
+        pstrcat(buf, sizeof(buf), "/");
+        put_stabs_r(buf, N_SO, 0, 0,
+                    text_section->data_offset, text_section, section_sym);
+        put_stabs_r(file->filename, N_SO, 0, 0,
+                    text_section->data_offset, text_section, section_sym);
+        last_ind = 0;
+        last_line_num = 0;
+    }
+
+    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
+       symbols can be safely used */
+    put_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
+                SHN_ABS, file->filename);
+}
+
+/* put end of translation unit info */
+ST_FUNC void tcc_debug_end(TCCState *s1)
+{
+    if (!s1->do_debug)
+        return;
+    put_stabs_r(NULL, N_SO, 0, 0,
+        text_section->data_offset, text_section, section_sym);
+
+}
+
+/* generate line number info */
+ST_FUNC void tcc_debug_line(TCCState *s1)
+{
+    if (!s1->do_debug)
+        return;
+    if ((last_line_num != file->line_num || last_ind != ind)) {
+        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
+        last_ind = ind;
+        last_line_num = file->line_num;
+    }
+}
+
+/* put function symbol */
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
+{
+    char buf[512];
+
+    if (!s1->do_debug)
+        return;
+
+    /* stabs info */
+    /* XXX: we put here a dummy type */
+    snprintf(buf, sizeof(buf), "%s:%c1",
+             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
+    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
+                cur_text_section, sym->c);
+    /* //gr gdb wants a line at the function */
+    put_stabn(N_SLINE, 0, file->line_num, 0);
+
+    last_ind = 0;
+    last_line_num = 0;
+}
+
+/* put function size */
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
+{
+    if (!s1->do_debug)
+        return;
+    put_stabn(N_FUN, 0, 0, size);
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC int tccgen_compile(TCCState *s1)
+{
+    cur_text_section = NULL;
+    funcname = "";
+    anon_sym = SYM_FIRST_ANOM;
+    section_sym = 0;
+    const_wanted = 0;
+    nocode_wanted = 0x80000000;
+
+    /* define some often used types */
+    int_type.t = VT_INT;
+    char_pointer_type.t = VT_BYTE;
+    mk_pointer(&char_pointer_type);
+#if PTR_SIZE == 4
+    size_type.t = VT_INT | VT_UNSIGNED;
+    ptrdiff_type.t = VT_INT;
+#elif LONG_SIZE == 4
+    size_type.t = VT_LLONG | VT_UNSIGNED;
+    ptrdiff_type.t = VT_LLONG;
+#else
+    size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
+    ptrdiff_type.t = VT_LONG | VT_LLONG;
+#endif
+    func_old_type.t = VT_FUNC;
+    func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
+    func_old_type.ref->f.func_call = FUNC_CDECL;
+    func_old_type.ref->f.func_type = FUNC_OLD;
+
+    tcc_debug_start(s1);
+
+#ifdef TCC_TARGET_ARM
+    arm_init(s1);
+#endif
+
+#ifdef INC_DEBUG
+    printf("%s: **** new file\n", file->filename);
+#endif
+
+    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
+    next();
+    decl(VT_CONST);
+    gen_inline_functions(s1);
+    check_vstack();
+    /* end of translation unit info */
+    tcc_debug_end(s1);
+    return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC ElfSym *elfsym(Sym *s)
+{
+  if (!s || !s->c)
+    return NULL;
+  return &((ElfSym *)symtab_section->data)[s->c];
+}
+
+/* apply storage attributes to Elf symbol */
+ST_FUNC void update_storage(Sym *sym)
+{
+    ElfSym *esym;
+    int sym_bind, old_sym_bind;
+
+    esym = elfsym(sym);
+    if (!esym)
+        return;
+
+    if (sym->a.visibility)
+        esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+            | sym->a.visibility;
+
+    if (sym->type.t & VT_STATIC)
+        sym_bind = STB_LOCAL;
+    else if (sym->a.weak)
+        sym_bind = STB_WEAK;
+    else
+        sym_bind = STB_GLOBAL;
+    old_sym_bind = ELFW(ST_BIND)(esym->st_info);
+    if (sym_bind != old_sym_bind) {
+        esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
+    }
+
+#ifdef TCC_TARGET_PE
+    if (sym->a.dllimport)
+        esym->st_other |= ST_PE_IMPORT;
+    if (sym->a.dllexport)
+        esym->st_other |= ST_PE_EXPORT;
+#endif
+
+#if 0
+    printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
+        get_tok_str(sym->v, NULL),
+        sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
+        sym->a.visibility,
+        sym->a.dllexport,
+        sym->a.dllimport
+        );
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+/* update sym->c so that it points to an external symbol in section
+   'section' with value 'value' */
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
+                            addr_t value, unsigned long size,
+                            int can_add_underscore)
+{
+    int sym_type, sym_bind, info, other, t;
+    ElfSym *esym;
+    const char *name;
+    char buf1[256];
+#ifdef CONFIG_TCC_BCHECK
+    char buf[32];
+#endif
+
+    if (!sym->c) {
+        name = get_tok_str(sym->v, NULL);
+#ifdef CONFIG_TCC_BCHECK
+        if (tcc_state->do_bounds_check) {
+            /* XXX: avoid doing that for statics ? */
+            /* if bound checking is activated, we change some function
+               names by adding the "__bound" prefix */
+            switch(sym->v) {
+#ifdef TCC_TARGET_PE
+            /* XXX: we rely only on malloc hooks */
+            case TOK_malloc:
+            case TOK_free:
+            case TOK_realloc:
+            case TOK_memalign:
+            case TOK_calloc:
+#endif
+            case TOK_memcpy:
+            case TOK_memmove:
+            case TOK_memset:
+            case TOK_strlen:
+            case TOK_strcpy:
+            case TOK_alloca:
+                strcpy(buf, "__bound_");
+                strcat(buf, name);
+                name = buf;
+                break;
+            }
+        }
+#endif
+        t = sym->type.t;
+        if ((t & VT_BTYPE) == VT_FUNC) {
+            sym_type = STT_FUNC;
+        } else if ((t & VT_BTYPE) == VT_VOID) {
+            sym_type = STT_NOTYPE;
+        } else {
+            sym_type = STT_OBJECT;
+        }
+        if (t & VT_STATIC)
+            sym_bind = STB_LOCAL;
+        else
+            sym_bind = STB_GLOBAL;
+        other = 0;
+#ifdef TCC_TARGET_PE
+        if (sym_type == STT_FUNC && sym->type.ref) {
+            Sym *ref = sym->type.ref;
+            if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
+                sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
+                name = buf1;
+                other |= ST_PE_STDCALL;
+                can_add_underscore = 0;
+            }
+        }
+#endif
+        if (tcc_state->leading_underscore && can_add_underscore) {
+            buf1[0] = '_';
+            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
+            name = buf1;
+        }
+        if (sym->asm_label)
+            name = get_tok_str(sym->asm_label, NULL);
+        info = ELFW(ST_INFO)(sym_bind, sym_type);
+        sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
+    } else {
+        esym = elfsym(sym);
+        esym->st_value = value;
+        esym->st_size = size;
+        esym->st_shndx = sh_num;
+    }
+    update_storage(sym);
+}
+
+ST_FUNC void put_extern_sym(Sym *sym, Section *section,
+                           addr_t value, unsigned long size)
+{
+    int sh_num = section ? section->sh_num : SHN_UNDEF;
+    put_extern_sym2(sym, sh_num, value, size, 1);
+}
+
+/* add a new relocation entry to symbol 'sym' in section 's' */
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
+                     addr_t addend)
+{
+    int c = 0;
+
+    if (nocode_wanted && s == cur_text_section)
+        return;
+
+    if (sym) {
+        if (0 == sym->c)
+            put_extern_sym(sym, NULL, 0, 0);
+        c = sym->c;
+    }
+
+    /* now we can add ELF relocation info */
+    put_elf_reloca(symtab_section, s, offset, type, c, addend);
+}
+
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
+{
+    greloca(s, sym, offset, type, 0);
+}
+#endif
 
 /* ------------------------------------------------------------------------- */
@@ -131,4 +476,5 @@
 {
     Sym *sym;
+#ifndef SYM_DEBUG
     sym = sym_free_first;
     if (!sym)
@@ -136,34 +482,30 @@
     sym_free_first = sym->next;
     return sym;
+#else
+    sym = tcc_malloc(sizeof(Sym));
+    return sym;
+#endif
 }
 
 ST_INLN void sym_free(Sym *sym)
 {
+#ifndef SYM_DEBUG
     sym->next = sym_free_first;
-    tcc_free(sym->asm_label);
     sym_free_first = sym;
+#else
+    tcc_free(sym);
+#endif
 }
 
 /* push, without hashing */
-ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
 {
     Sym *s;
-    if (ps == &local_stack) {
-        for (s = *ps; s && s != scope_stack_bottom; s = s->prev)
-            if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM && s->v == v)
-                tcc_error("incompatible types for redefinition of '%s'",
-                          get_tok_str(v, NULL));
-    }
-    s = *ps;
+
     s = sym_malloc();
-    s->asm_label = NULL;
+    memset(s, 0, sizeof *s);
     s->v = v;
     s->type.t = t;
-    s->type.ref = NULL;
-#ifdef _WIN64
-    s->d = NULL;
-#endif
     s->c = c;
-    s->next = NULL;
     /* add in stack */
     s->prev = *ps;
@@ -179,4 +521,6 @@
         if (s->v == v)
             return s;
+        else if (s->v == -1)
+            return NULL;
         s = s->prev;
     }
@@ -226,4 +570,8 @@
         s->prev_tok = *ps;
         *ps = s;
+        s->sym_scope = local_scope;
+        if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
+            tcc_error("redeclaration of '%s'",
+                get_tok_str(v & ~SYM_STRUCT, NULL));
     }
     return s;
@@ -240,7 +588,7 @@
         /* modify the top most local identifier, so that
            sym_identifier will point to 's' when popped */
-        while (*ps != NULL)
+        while (*ps != NULL && (*ps)->sym_scope)
             ps = &(*ps)->prev_tok;
-        s->prev_tok = NULL;
+        s->prev_tok = *ps;
         *ps = s;
     }
@@ -248,6 +596,7 @@
 }
 
-/* pop symbols until top reaches 'b' */
-ST_FUNC void sym_pop(Sym **ptop, Sym *b)
+/* pop symbols until top reaches 'b'.  If KEEP is non-zero don't really
+   pop them yet from the list, but do remove them from the token array.  */
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
 {
     Sym *s, *ss, **ps;
@@ -269,33 +618,14 @@
             *ps = s->prev_tok;
         }
-        sym_free(s);
+	if (!keep)
+	    sym_free(s);
         s = ss;
     }
-    *ptop = b;
-}
-
-static void weaken_symbol(Sym *sym)
-{
-    sym->type.t |= VT_WEAK;
-    if (sym->c > 0) {
-        int esym_type;
-        ElfW(Sym) *esym;
-        
-        esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
-        esym_type = ELFW(ST_TYPE)(esym->st_info);
-        esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
-    }
+    if (!keep)
+	*ptop = b;
 }
 
 /* ------------------------------------------------------------------------- */
 
-ST_FUNC void swap(int *p, int *q)
-{
-    int t;
-    t = *p;
-    *p = *q;
-    *q = t;
-}
-
 static void vsetc(CType *type, int r, CValue *vc)
 {
@@ -303,13 +633,24 @@
 
     if (vtop >= vstack + (VSTACK_SIZE - 1))
-        tcc_error("memory full");
+        tcc_error("memory full (vstack)");
     /* cannot let cpu flags if other instruction are generated. Also
        avoid leaving VT_JMP anywhere except on the top of the stack
-       because it would complicate the code generator. */
-    if (vtop >= vstack) {
+       because it would complicate the code generator.
+
+       Don't do this when nocode_wanted.  vtop might come from
+       !nocode_wanted regions (see 88_codeopt.c) and transforming
+       it to a register without actually generating code is wrong
+       as their value might still be used for real.  All values
+       we push under nocode_wanted will eventually be popped
+       again, so that the VT_CMP/VT_JMP value will be in vtop
+       when code is unsuppressed again.
+
+       Same logic below in vswap(); */
+    if (vtop >= vstack && !nocode_wanted) {
         v = vtop->r & VT_VALMASK;
         if (v == VT_CMP || (v & ~1) == VT_JMP)
             gv(RC_INT);
     }
+
     vtop++;
     vtop->type = *type;
@@ -317,11 +658,43 @@
     vtop->r2 = VT_CONST;
     vtop->c = *vc;
+    vtop->sym = NULL;
+}
+
+ST_FUNC void vswap(void)
+{
+    SValue tmp;
+    /* cannot vswap cpu flags. See comment at vsetc() above */
+    if (vtop >= vstack && !nocode_wanted) {
+        int v = vtop->r & VT_VALMASK;
+        if (v == VT_CMP || (v & ~1) == VT_JMP)
+            gv(RC_INT);
+    }
+    tmp = vtop[0];
+    vtop[0] = vtop[-1];
+    vtop[-1] = tmp;
+}
+
+/* pop stack value */
+ST_FUNC void vpop(void)
+{
+    int v;
+    v = vtop->r & VT_VALMASK;
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+    /* for x86, we need to pop the FP stack */
+    if (v == TREG_ST0) {
+        o(0xd8dd); /* fstp %st(0) */
+    } else
+#endif
+    if (v == VT_JMP || v == VT_JMPI) {
+        /* need to put correct jump if && or || without test */
+        gsym(vtop->c.i);
+    }
+    vtop--;
 }
 
 /* push constant of type "type" with useless value */
-void vpush(CType *type)
-{
-    CValue cval;
-    vsetc(type, VT_CONST, &cval);
+ST_FUNC void vpush(CType *type)
+{
+    vset(type, VT_CONST, 0);
 }
 
@@ -335,16 +708,13 @@
 
 /* push a pointer sized constant */
-static void vpushs(long long v)
+static void vpushs(addr_t v)
 {
   CValue cval;
-  if (PTR_SIZE == 4)
-    cval.i = (int)v;
-  else
-    cval.ull = v;
+  cval.i = v;
   vsetc(&size_type, VT_CONST, &cval);
 }
 
 /* push arbitrary 64bit constant */
-void vpush64(int ty, unsigned long long v)
+ST_FUNC void vpush64(int ty, unsigned long long v)
 {
     CValue cval;
@@ -352,5 +722,5 @@
     ctype.t = ty;
     ctype.ref = NULL;
-    cval.ull = v;
+    cval.i = v;
     vsetc(&ctype, VT_CONST, &cval);
 }
@@ -360,4 +730,78 @@
 {
     vpush64(VT_LLONG, v);
+}
+
+ST_FUNC void vset(CType *type, int r, int v)
+{
+    CValue cval;
+
+    cval.i = v;
+    vsetc(type, r, &cval);
+}
+
+static void vseti(int r, int v)
+{
+    CType type;
+    type.t = VT_INT;
+    type.ref = NULL;
+    vset(&type, r, v);
+}
+
+ST_FUNC void vpushv(SValue *v)
+{
+    if (vtop >= vstack + (VSTACK_SIZE - 1))
+        tcc_error("memory full (vstack)");
+    vtop++;
+    *vtop = *v;
+}
+
+static void vdup(void)
+{
+    vpushv(vtop);
+}
+
+/* rotate n first stack elements to the bottom
+   I1 ... In -> I2 ... In I1 [top is right]
+*/
+ST_FUNC void vrotb(int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = vtop[-n + 1];
+    for(i=-n+1;i!=0;i++)
+        vtop[i] = vtop[i+1];
+    vtop[0] = tmp;
+}
+
+/* rotate the n elements before entry e towards the top
+   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
+ */
+ST_FUNC void vrote(SValue *e, int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = *e;
+    for(i = 0;i < n - 1; i++)
+        e[-i] = e[-i - 1];
+    e[-n + 1] = tmp;
+}
+
+/* rotate n first stack elements to the top
+   I1 ... In -> In I1 ... I(n-1)  [top is right]
+ */
+ST_FUNC void vrott(int n)
+{
+    vrote(vtop, n);
+}
+
+/* push a symbol value of TYPE */
+static inline void vpushsym(CType *type, Sym *sym)
+{
+    CValue cval;
+    cval.i = 0;
+    vsetc(type, VT_CONST | VT_SYM, &cval);
+    vtop->sym = sym;
 }
 
@@ -379,9 +823,5 @@
 static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
 {
-    CValue cval;
-
-    cval.ul = 0;
-    vsetc(type, VT_CONST | VT_SYM, &cval);
-    vtop->sym = get_sym_ref(type, sec, offset, size);
+    vpushsym(type, get_sym_ref(type, sec, offset, size));  
 }
 
@@ -397,28 +837,108 @@
         s->type.ref = type->ref;
         s->r = r | VT_CONST | VT_SYM;
+    } else if (IS_ASM_SYM(s)) {
+        s->type.t = type->t | (s->type.t & VT_EXTERN);
+        s->type.ref = type->ref;
+        update_storage(s);
     }
     return s;
 }
 
-/* define a new external reference to a symbol 'v' with alternate asm
-   name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there
-   is no alternate name (most cases) */
-static Sym *external_sym(int v, CType *type, int r, char *asm_label)
+/* Merge some type attributes.  */
+static void patch_type(Sym *sym, CType *type)
+{
+    if (!(type->t & VT_EXTERN)) {
+        if (!(sym->type.t & VT_EXTERN))
+            tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
+        sym->type.t &= ~VT_EXTERN;
+    }
+
+    if (IS_ASM_SYM(sym)) {
+        /* stay static if both are static */
+        sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
+        sym->type.ref = type->ref;
+    }
+
+    if (!is_compatible_types(&sym->type, type)) {
+        tcc_error("incompatible types for redefinition of '%s'",
+                  get_tok_str(sym->v, NULL));
+
+    } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
+        int static_proto = sym->type.t & VT_STATIC;
+        /* warn if static follows non-static function declaration */
+        if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
+            tcc_warning("static storage ignored for redefinition of '%s'",
+                get_tok_str(sym->v, NULL));
+
+        if (0 == (type->t & VT_EXTERN)) {
+            /* put complete type, use static from prototype */
+            sym->type.t = (type->t & ~VT_STATIC) | static_proto;
+            if (type->t & VT_INLINE)
+                sym->type.t = type->t;
+            sym->type.ref = type->ref;
+        }
+
+    } else {
+        if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
+            /* set array size if it was omitted in extern declaration */
+            if (sym->type.ref->c < 0)
+                sym->type.ref->c = type->ref->c;
+            else if (sym->type.ref->c != type->ref->c)
+                tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
+        }
+        if ((type->t ^ sym->type.t) & VT_STATIC)
+            tcc_warning("storage mismatch for redefinition of '%s'",
+                get_tok_str(sym->v, NULL));
+    }
+}
+
+
+/* Merge some storage attributes.  */
+static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
+{
+    if (type)
+        patch_type(sym, type);
+
+#ifdef TCC_TARGET_PE
+    if (sym->a.dllimport != ad->a.dllimport)
+        tcc_error("incompatible dll linkage for redefinition of '%s'",
+            get_tok_str(sym->v, NULL));
+    sym->a.dllexport |= ad->a.dllexport;
+#endif
+    sym->a.weak |= ad->a.weak;
+    if (ad->a.visibility) {
+        int vis = sym->a.visibility;
+        int vis2 = ad->a.visibility;
+        if (vis == STV_DEFAULT)
+            vis = vis2;
+        else if (vis2 != STV_DEFAULT)
+            vis = (vis < vis2) ? vis : vis2;
+        sym->a.visibility = vis;
+    }
+    if (ad->a.aligned)
+        sym->a.aligned = ad->a.aligned;
+    if (ad->asm_label)
+        sym->asm_label = ad->asm_label;
+    update_storage(sym);
+}
+
+/* define a new external reference to a symbol 'v' */
+static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
 {
     Sym *s;
-
     s = sym_find(v);
     if (!s) {
         /* push forward reference */
         s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
-        s->asm_label = asm_label;
         s->type.t |= VT_EXTERN;
-    } else if (s->type.ref == func_old_type.ref) {
-        s->type.ref = type->ref;
-        s->r = r | VT_CONST | VT_SYM;
-        s->type.t |= VT_EXTERN;
-    } else if (!is_compatible_types(&s->type, type)) {
-        tcc_error("incompatible types for redefinition of '%s'", 
-              get_tok_str(v, NULL));
+        s->a = ad->a;
+        s->sym_scope = 0;
+    } else {
+        if (s->type.ref == func_old_type.ref) {
+            s->type.ref = type->ref;
+            s->r = r | VT_CONST | VT_SYM;
+            s->type.t |= VT_EXTERN;
+        }
+        patch_storage(s, ad, type);
     }
     return s;
@@ -428,61 +948,13 @@
 ST_FUNC void vpush_global_sym(CType *type, int v)
 {
-    Sym *sym;
-    CValue cval;
-
-    sym = external_global_sym(v, type, 0);
-    cval.ul = 0;
-    vsetc(type, VT_CONST | VT_SYM, &cval);
-    vtop->sym = sym;
-}
-
-ST_FUNC void vset(CType *type, int r, int v)
-{
-    CValue cval;
-
-    cval.i = v;
-    vsetc(type, r, &cval);
-}
-
-static void vseti(int r, int v)
-{
-    CType type;
-    type.t = VT_INT;
-    type.ref = 0;
-    vset(&type, r, v);
-}
-
-ST_FUNC void vswap(void)
-{
-    SValue tmp;
-    /* cannot let cpu flags if other instruction are generated. Also
-       avoid leaving VT_JMP anywhere except on the top of the stack
-       because it would complicate the code generator. */
-    if (vtop >= vstack) {
-        int v = vtop->r & VT_VALMASK;
-        if (v == VT_CMP || (v & ~1) == VT_JMP)
-            gv(RC_INT);
-    }
-    tmp = vtop[0];
-    vtop[0] = vtop[-1];
-    vtop[-1] = tmp;
-
-/* XXX: +2% overall speed possible with optimized memswap
- *
- *  memswap(&vtop[0], &vtop[1], sizeof *vtop);
- */
-}
-
-ST_FUNC void vpushv(SValue *v)
-{
-    if (vtop >= vstack + (VSTACK_SIZE - 1))
-        tcc_error("memory full");
-    vtop++;
-    *vtop = *v;
-}
-
-static void vdup(void)
-{
-    vpushv(vtop);
+    vpushsym(type, external_global_sym(v, type, 0));
+}
+
+/* save registers up to (vtop - n) stack entry */
+ST_FUNC void save_regs(int n)
+{
+    SValue *p, *p1;
+    for(p = vstack, p1 = vtop - n; p <= p1; p++)
+        save_reg(p->r);
 }
 
@@ -490,12 +962,24 @@
 ST_FUNC void save_reg(int r)
 {
+    save_reg_upstack(r, 0);
+}
+
+/* save r to the memory stack, and mark it as being free,
+   if seen up to (vtop - n) stack entry */
+ST_FUNC void save_reg_upstack(int r, int n)
+{
     int l, saved, size, align;
-    SValue *p, sv;
+    SValue *p, *p1, sv;
     CType *type;
+
+    if ((r &= VT_VALMASK) >= VT_CONST)
+        return;
+    if (nocode_wanted)
+        return;
 
     /* modify all stack values */
     saved = 0;
     l = 0;
-    for(p=vstack;p<=vtop;p++) {
+    for(p = vstack, p1 = vtop - n; p <= p1; p++) {
         if ((p->r & VT_VALMASK) == r ||
             ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
@@ -508,5 +992,5 @@
                 if ((p->r & VT_LVAL) ||
                     (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
-#ifdef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
                     type = &char_pointer_type;
 #else
@@ -517,5 +1001,5 @@
                 sv.type.t = type->t;
                 sv.r = VT_LOCAL | VT_LVAL;
-                sv.c.ul = loc;
+                sv.c.i = loc;
                 store(r, &sv);
 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
@@ -525,8 +1009,8 @@
                 }
 #endif
-#ifndef TCC_TARGET_X86_64
+#if PTR_SIZE == 4
                 /* special long long case */
                 if ((type->t & VT_BTYPE) == VT_LLONG) {
-                    sv.c.ul += 4;
+                    sv.c.i += 4;
                     store(p->r2, &sv);
                 }
@@ -539,5 +1023,5 @@
                 /* also clear the bounded flag because the
                    relocation address of the function was stored in
-                   p->c.ul */
+                   p->c.i */
                 p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
             } else {
@@ -545,5 +1029,5 @@
             }
             p->r2 = VT_CONST;
-            p->c.ul = l;
+            p->c.i = l;
         }
     }
@@ -584,4 +1068,6 @@
     for(r=0;r<NB_REGS;r++) {
         if (reg_classes[r] & rc) {
+            if (nocode_wanted)
+                return r;
             for(p=vstack;p<=vtop;p++) {
                 if ((p->r & VT_VALMASK) == r ||
@@ -613,21 +1099,7 @@
 }
 
-/* save registers up to (vtop - n) stack entry */
-ST_FUNC void save_regs(int n)
-{
-    int r;
-    SValue *p, *p1;
-    p1 = vtop - n;
-    for(p = vstack;p <= p1; p++) {
-        r = p->r & VT_VALMASK;
-        if (r < VT_CONST) {
-            save_reg(r);
-        }
-    }
-}
-
-/* move register 's' to 'r', and flush previous value of r to memory
+/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
    if needed */
-static void move_reg(int r, int s)
+static void move_reg(int r, int s, int t)
 {
     SValue sv;
@@ -635,7 +1107,8 @@
     if (r != s) {
         save_reg(r);
-        sv.type.t = VT_INT;
+        sv.type.t = t;
+        sv.type.ref = NULL;
         sv.r = s;
-        sv.c.ul = 0;
+        sv.c.i = 0;
         load(r, &sv);
     }
@@ -643,8 +1116,6 @@
 
 /* get address of vtop (vtop MUST BE an lvalue) */
-static void gaddrof(void)
-{
-    if (vtop->r & VT_REF)
-        gv(RC_INT);
+ST_FUNC void gaddrof(void)
+{
     vtop->r &= ~VT_LVAL;
     /* tricky: if saved lvalue, then we can go back to lvalue */
@@ -670,5 +1141,5 @@
             /* must save type because we must set it to int to get pointer */
             type1 = vtop->type;
-            vtop->type.t = VT_INT;
+            vtop->type.t = VT_PTR;
             gaddrof();
             vpushi(0);
@@ -683,4 +1154,98 @@
 #endif
 
+static void incr_bf_adr(int o)
+{
+    vtop->type = char_pointer_type;
+    gaddrof();
+    vpushi(o);
+    gen_op('+');
+    vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
+        | (VT_BYTE|VT_UNSIGNED);
+    vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+        | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
+}
+
+/* single-byte load mode for packed or otherwise unaligned bitfields */
+static void load_packed_bf(CType *type, int bit_pos, int bit_size)
+{
+    int n, o, bits;
+    save_reg_upstack(vtop->r, 1);
+    vpush64(type->t & VT_BTYPE, 0); // B X
+    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+    do {
+        vswap(); // X B
+        incr_bf_adr(o);
+        vdup(); // X B B
+        n = 8 - bit_pos;
+        if (n > bit_size)
+            n = bit_size;
+        if (bit_pos)
+            vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
+        if (n < 8)
+            vpushi((1 << n) - 1), gen_op('&');
+        gen_cast(type);
+        if (bits)
+            vpushi(bits), gen_op(TOK_SHL);
+        vrotb(3); // B Y X
+        gen_op('|'); // B X
+        bits += n, bit_size -= n, o = 1;
+    } while (bit_size);
+    vswap(), vpop();
+    if (!(type->t & VT_UNSIGNED)) {
+        n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
+        vpushi(n), gen_op(TOK_SHL);
+        vpushi(n), gen_op(TOK_SAR);
+    }
+}
+
+/* single-byte store mode for packed or otherwise unaligned bitfields */
+static void store_packed_bf(int bit_pos, int bit_size)
+{
+    int bits, n, o, m, c;
+
+    c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    vswap(); // X B
+    save_reg_upstack(vtop->r, 1);
+    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+    do {
+        incr_bf_adr(o); // X B
+        vswap(); //B X
+        c ? vdup() : gv_dup(); // B V X
+        vrott(3); // X B V
+        if (bits)
+            vpushi(bits), gen_op(TOK_SHR);
+        if (bit_pos)
+            vpushi(bit_pos), gen_op(TOK_SHL);
+        n = 8 - bit_pos;
+        if (n > bit_size)
+            n = bit_size;
+        if (n < 8) {
+            m = ((1 << n) - 1) << bit_pos;
+            vpushi(m), gen_op('&'); // X B V1
+            vpushv(vtop-1); // X B V1 B
+            vpushi(m & 0x80 ? ~m & 0x7f : ~m);
+            gen_op('&'); // X B V1 B1
+            gen_op('|'); // X B V2
+        }
+        vdup(), vtop[-1] = vtop[-2]; // X B B V2
+        vstore(), vpop(); // X B
+        bits += n, bit_size -= n, bit_pos = 0, o = 1;
+    } while (bit_size);
+    vpop(), vpop();
+}
+
+static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
+{
+    int t;
+    if (0 == sv->type.ref)
+        return 0;
+    t = sv->type.ref->auxtype;
+    if (t != -1 && t != VT_STRUCT) {
+        sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
+        sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
+    }
+    return t;
+}
+
 /* store vtop a register belonging to class 'rc'. lvalues are
    converted to values. Cannot be used if cannot be converted to
@@ -688,75 +1253,55 @@
 ST_FUNC int gv(int rc)
 {
-    int r, bit_pos, bit_size, size, align, i;
-#ifndef TCC_TARGET_X86_64
-    int rc2;
-#endif
+    int r, bit_pos, bit_size, size, align, rc2;
 
     /* NOTE: get_reg can modify vstack[] */
     if (vtop->type.t & VT_BITFIELD) {
         CType type;
-        int bits = 32;
-        bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
-        bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
+
+        bit_pos = BIT_POS(vtop->type.t);
+        bit_size = BIT_SIZE(vtop->type.t);
         /* remove bit field info to avoid loops */
-        vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
-        /* cast to int to propagate signedness in following ops */
-        if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
-            type.t = VT_LLONG;
-            bits = 64;
-        } else
-            type.t = VT_INT;
-        if((vtop->type.t & VT_UNSIGNED) ||
-           (vtop->type.t & VT_BTYPE) == VT_BOOL)
+        vtop->type.t &= ~VT_STRUCT_MASK;
+
+        type.ref = NULL;
+        type.t = vtop->type.t & VT_UNSIGNED;
+        if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
             type.t |= VT_UNSIGNED;
-        gen_cast(&type);
-        /* generate shifts */
-        vpushi(bits - (bit_pos + bit_size));
-        gen_op(TOK_SHL);
-        vpushi(bits - bit_size);
-        /* NOTE: transformed to SHR if unsigned */
-        gen_op(TOK_SAR);
+
+        r = adjust_bf(vtop, bit_pos, bit_size);
+
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+            type.t |= VT_LLONG;
+        else
+            type.t |= VT_INT;
+
+        if (r == VT_STRUCT) {
+            load_packed_bf(&type, bit_pos, bit_size);
+        } else {
+            int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
+            /* cast to int to propagate signedness in following ops */
+            gen_cast(&type);
+            /* generate shifts */
+            vpushi(bits - (bit_pos + bit_size));
+            gen_op(TOK_SHL);
+            vpushi(bits - bit_size);
+            /* NOTE: transformed to SHR if unsigned */
+            gen_op(TOK_SAR);
+        }
         r = gv(rc);
     } else {
         if (is_float(vtop->type.t) && 
             (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
-            Sym *sym;
-            int *ptr;
             unsigned long offset;
-#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
-            CValue check;
-#endif
-            
-            /* XXX: unify with initializers handling ? */
             /* CPUs usually cannot use float constants, so we store them
                generically in data segment */
             size = type_size(&vtop->type, &align);
-            offset = (data_section->data_offset + align - 1) & -align;
-            data_section->data_offset = offset;
-            /* XXX: not portable yet */
-#if defined(__i386__) || defined(__x86_64__)
-            /* Zero pad x87 tenbyte long doubles */
-            if (size == LDOUBLE_SIZE) {
-                vtop->c.tab[2] &= 0xffff;
-#if LDOUBLE_SIZE == 16
-                vtop->c.tab[3] = 0;
-#endif
-            }
-#endif
-            ptr = section_ptr_add(data_section, size);
-            size = size >> 2;
-#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
-            check.d = 1;
-            if(check.tab[0])
-                for(i=0;i<size;i++)
-                    ptr[i] = vtop->c.tab[size-1-i];
-            else
-#endif
-            for(i=0;i<size;i++)
-                ptr[i] = vtop->c.tab[i];
-            sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
-            vtop->r |= VT_LVAL | VT_SYM;
-            vtop->sym = sym;
-            vtop->c.ul = 0;
+            if (NODATA_WANTED)
+                size = 0, align = 1;
+            offset = section_add(data_section, size, align);
+            vpush_ref(&vtop->type, data_section, offset, size);
+	    vswap();
+	    init_putv(&vtop->type, data_section, offset);
+	    vtop->r |= VT_LVAL;
         }
 #ifdef CONFIG_TCC_BCHECK
@@ -766,8 +1311,12 @@
 
         r = vtop->r & VT_VALMASK;
-#ifndef TCC_TARGET_X86_64
-        rc2 = RC_INT;
+        rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
+#ifndef TCC_TARGET_ARM64
         if (rc == RC_IRET)
             rc2 = RC_LRET;
+#ifdef TCC_TARGET_X86_64
+        else if (rc == RC_FRET)
+            rc2 = RC_QRET;
+#endif
 #endif
         /* need to reload if:
@@ -778,5 +1327,8 @@
          || (vtop->r & VT_LVAL)
          || !(reg_classes[r] & rc)
-#ifndef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
+         || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
+         || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
+#else
          || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
 #endif
@@ -784,34 +1336,49 @@
         {
             r = get_reg(rc);
-#ifndef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
+            if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
+                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
-                int r2;
+                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
                 unsigned long long ll;
+#endif
+                int r2, original_type;
+                original_type = vtop->type.t;
                 /* two register type load : expand to two words
                    temporarily */
+#if PTR_SIZE == 4
                 if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
                     /* load constant */
-                    ll = vtop->c.ull;
-                    vtop->c.ui = ll; /* first word */
+                    ll = vtop->c.i;
+                    vtop->c.i = ll; /* first word */
                     load(r, vtop);
                     vtop->r = r; /* save register value */
                     vpushi(ll >> 32); /* second word */
-                } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
-                           (vtop->r & VT_LVAL)) {
+                } else
+#endif
+                if (vtop->r & VT_LVAL) {
                     /* We do not want to modifier the long long
                        pointer here, so the safest (and less
                        efficient) is to save all the other registers
                        in the stack. XXX: totally inefficient. */
+               #if 0
                     save_regs(1);
+               #else
+                    /* lvalue_save: save only if used further down the stack */
+                    save_reg_upstack(vtop->r, 1);
+               #endif
                     /* load from memory */
+                    vtop->type.t = load_type;
                     load(r, vtop);
                     vdup();
                     vtop[-1].r = r; /* save register value */
                     /* increment pointer to get second word */
-                    vtop->type.t = VT_INT;
+                    vtop->type.t = addr_type;
                     gaddrof();
-                    vpushi(4);
+                    vpushi(load_size);
                     gen_op('+');
                     vtop->r |= VT_LVAL;
+                    vtop->type.t = load_type;
                 } else {
                     /* move registers */
@@ -828,7 +1395,6 @@
                 /* write second register */
                 vtop->r2 = r2;
-            } else
-#endif
-            if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
+                vtop->type.t = original_type;
+            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
                 int t1, t;
                 /* lvalue of scalar type : need to use lvalue type
@@ -894,4 +1460,5 @@
 }
 
+#ifndef TCC_TARGET_ARM64
 /* wrapper around RC_FRET to return a register by type */
 static int rc_fret(int t)
@@ -904,4 +1471,5 @@
     return RC_FRET;
 }
+#endif
 
 /* wrapper around REG_FRET to return a register by type */
@@ -916,18 +1484,26 @@
 }
 
-/* expand long long on stack in two int registers */
+#if PTR_SIZE == 4
+/* expand 64bit on stack in two ints */
 static void lexpand(void)
 {
-    int u;
-
-    u = vtop->type.t & VT_UNSIGNED;
-    gv(RC_INT);
-    vdup();
-    vtop[0].r = vtop[-1].r2;
-    vtop[0].r2 = VT_CONST;
-    vtop[-1].r2 = VT_CONST;
-    vtop[0].type.t = VT_INT | u;
-    vtop[-1].type.t = VT_INT | u;
-}
+    int u, v;
+    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
+    v = vtop->r & (VT_VALMASK | VT_LVAL);
+    if (v == VT_CONST) {
+        vdup();
+        vtop[0].c.i >>= 32;
+    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+        vdup();
+        vtop[0].c.i += 4;
+    } else {
+        gv(RC_INT);
+        vdup();
+        vtop[0].r = vtop[-1].r2;
+        vtop[0].r2 = vtop[-1].r2 = VT_CONST;
+    }
+    vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
+}
+#endif
 
 #ifdef TCC_TARGET_ARM
@@ -937,5 +1513,5 @@
     int u,v;
 
-    u = vtop->type.t & VT_UNSIGNED;
+    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
     vdup();
     vtop->r2 = VT_CONST;
@@ -943,9 +1519,9 @@
     v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
     if (v == VT_CONST) {
-      vtop[-1].c.ui = vtop->c.ull;
-      vtop->c.ui = vtop->c.ull >> 32;
+      vtop[-1].c.i = vtop->c.i;
+      vtop->c.i = vtop->c.i >> 32;
       vtop->r = VT_CONST;
     } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
-      vtop->c.ui += 4;
+      vtop->c.i += 4;
       vtop->r = vtop[-1].r;
     } else if (v > VT_CONST) {
@@ -959,4 +1535,5 @@
 #endif
 
+#if PTR_SIZE == 4
 /* build a long long from two ints */
 static void lbuild(int t)
@@ -967,58 +1544,5 @@
     vpop();
 }
-
-/* rotate n first stack elements to the bottom 
-   I1 ... In -> I2 ... In I1 [top is right]
-*/
-ST_FUNC void vrotb(int n)
-{
-    int i;
-    SValue tmp;
-
-    tmp = vtop[-n + 1];
-    for(i=-n+1;i!=0;i++)
-        vtop[i] = vtop[i+1];
-    vtop[0] = tmp;
-}
-
-/* rotate the n elements before entry e towards the top
-   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
- */
-ST_FUNC void vrote(SValue *e, int n)
-{
-    int i;
-    SValue tmp;
-
-    tmp = *e;
-    for(i = 0;i < n - 1; i++)
-        e[-i] = e[-i - 1];
-    e[-n + 1] = tmp;
-}
-
-/* rotate n first stack elements to the top
-   I1 ... In -> In I1 ... I(n-1)  [top is right]
- */
-ST_FUNC void vrott(int n)
-{
-    vrote(vtop, n);
-}
-
-/* pop stack value */
-ST_FUNC void vpop(void)
-{
-    int v;
-    v = vtop->r & VT_VALMASK;
-#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
-    /* for x86, we need to pop the FP stack */
-    if (v == TREG_ST0 && !nocode_wanted) {
-        o(0xd8dd); /* fstp %st(0) */
-    } else
-#endif
-    if (v == VT_JMP || v == VT_JMPI) {
-        /* need to put correct jump if && or || without test */
-        gsym(vtop->c.ul);
-    }
-    vtop--;
-}
+#endif
 
 /* convert stack entry to register and duplicate its value in another
@@ -1030,5 +1554,10 @@
 
     t = vtop->type.t;
+#if PTR_SIZE == 4
     if ((t & VT_BTYPE) == VT_LLONG) {
+        if (t & VT_BITFIELD) {
+            gv(RC_INT);
+            t = vtop->type.t;
+        }
         lexpand();
         gv_dup();
@@ -1044,5 +1573,7 @@
         lbuild(t);
         vswap();
-    } else {
+    } else
+#endif
+    {
         /* duplicate value */
         rc = RC_INT;
@@ -1060,5 +1591,5 @@
         r1 = get_reg(rc);
         sv.r = r;
-        sv.c.ul = 0;
+        sv.c.i = 0;
         load(r1, &sv); /* move r to r1 */
         vdup();
@@ -1069,5 +1600,25 @@
 }
 
-#ifndef TCC_TARGET_X86_64
+/* Generate value test
+ *
+ * Generate a test for any value (jump, comparison and integers) */
+ST_FUNC int gvtst(int inv, int t)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
+        vpushi(0);
+        gen_op(TOK_NE);
+    }
+    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+        /* constant jmp optimization */
+        if ((vtop->c.i != 0) != inv)
+            t = gjmp(t);
+        vtop--;
+        return t;
+    }
+    return gtst(inv, t);
+}
+
+#if PTR_SIZE == 4
 /* generate CPU independent (unsigned) long long operations */
 static void gen_opl(int op)
@@ -1112,4 +1663,5 @@
     case '+':
     case '-':
+        //pv("gen_opl A",0,2);
         t = vtop->type.t;
         vswap();
@@ -1126,4 +1678,5 @@
         vswap();
         /* stack: H1 H2 L1 L2 */
+        //pv("gen_opl B",0,4);
         if (op == '*') {
             vpushv(vtop - 1);
@@ -1181,5 +1734,5 @@
             /* constant: simpler */
             /* NOTE: all comments are for SHL. the other cases are
-               done by swaping words */
+               done by swapping words */
             vpop();
             if (op != TOK_SHL)
@@ -1266,25 +1819,13 @@
         b = 0;
         gen_op(op1);
-        if (op1 != TOK_NE) {
-            a = gtst(1, 0);
-        }
-        if (op != TOK_EQ) {
-            /* generate non equal test */
-            /* XXX: NOT PORTABLE yet */
-            if (a == 0) {
-                b = gtst(0, 0);
-            } else {
-#if defined(TCC_TARGET_I386)
-                b = psym(0x850f, 0);
-#elif defined(TCC_TARGET_ARM)
-                b = ind;
-                o(0x1A000000 | encbranch(ind, 0, 1));
-#elif defined(TCC_TARGET_C67)
-                tcc_error("not implemented");
-#elif defined(TCC_TARGET_IL)
-                tcc_error("not implemented");
-#else
-#error not supported
-#endif
+        if (op == TOK_NE) {
+            b = gvtst(0, 0);
+        } else {
+            a = gvtst(1, 0);
+            if (op != TOK_EQ) {
+                /* generate non equal test */
+                vpushi(TOK_NE);
+                vtop->r = VT_CMP;
+                b = gvtst(0, 0);
             }
         }
@@ -1300,5 +1841,5 @@
             op1 = TOK_UGE;
         gen_op(op1);
-        a = gtst(1, a);
+        a = gvtst(1, a);
         gsym(b);
         vseti(VT_JMPI, a);
@@ -1308,35 +1849,36 @@
 #endif
 
+static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
+{
+    uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
+    return (a ^ b) >> 63 ? -x : x;
+}
+
+static int gen_opic_lt(uint64_t a, uint64_t b)
+{
+    return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
+}
+
 /* handle integer constant optimizations and various machine
    independent opt */
 static void gen_opic(int op)
 {
-    int c1, c2, t1, t2, n;
-    SValue *v1, *v2;
-    long long l1, l2;
-    typedef unsigned long long U;
-
-    v1 = vtop - 1;
-    v2 = vtop;
-    t1 = v1->type.t & VT_BTYPE;
-    t2 = v2->type.t & VT_BTYPE;
-
-    if (t1 == VT_LLONG)
-        l1 = v1->c.ll;
-    else if (v1->type.t & VT_UNSIGNED)
-        l1 = v1->c.ui;
-    else
-        l1 = v1->c.i;
-
-    if (t2 == VT_LLONG)
-        l2 = v2->c.ll;
-    else if (v2->type.t & VT_UNSIGNED)
-        l2 = v2->c.ui;
-    else
-        l2 = v2->c.i;
-
-    /* currently, we cannot do computations with forward symbols */
-    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
-    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    SValue *v1 = vtop - 1;
+    SValue *v2 = vtop;
+    int t1 = v1->type.t & VT_BTYPE;
+    int t2 = v2->type.t & VT_BTYPE;
+    int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    uint64_t l1 = c1 ? v1->c.i : 0;
+    uint64_t l2 = c2 ? v2->c.i : 0;
+    int shm = (t1 == VT_LLONG) ? 63 : 31;
+
+    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+        l1 = ((uint32_t)l1 |
+              (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+    if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
+        l2 = ((uint32_t)l2 |
+              (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
+
     if (c1 && c2) {
         switch(op) {
@@ -1360,24 +1902,26 @@
             }
             switch(op) {
-            default: l1 /= l2; break;
-            case '%': l1 %= l2; break;
-            case TOK_UDIV: l1 = (U)l1 / l2; break;
-            case TOK_UMOD: l1 = (U)l1 % l2; break;
+            default: l1 = gen_opic_sdiv(l1, l2); break;
+            case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
+            case TOK_UDIV: l1 = l1 / l2; break;
+            case TOK_UMOD: l1 = l1 % l2; break;
             }
             break;
-        case TOK_SHL: l1 <<= l2; break;
-        case TOK_SHR: l1 = (U)l1 >> l2; break;
-        case TOK_SAR: l1 >>= l2; break;
+        case TOK_SHL: l1 <<= (l2 & shm); break;
+        case TOK_SHR: l1 >>= (l2 & shm); break;
+        case TOK_SAR:
+            l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
+            break;
             /* tests */
-        case TOK_ULT: l1 = (U)l1 < (U)l2; break;
-        case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
+        case TOK_ULT: l1 = l1 < l2; break;
+        case TOK_UGE: l1 = l1 >= l2; break;
         case TOK_EQ: l1 = l1 == l2; break;
         case TOK_NE: l1 = l1 != l2; break;
-        case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
-        case TOK_UGT: l1 = (U)l1 > (U)l2; break;
-        case TOK_LT: l1 = l1 < l2; break;
-        case TOK_GE: l1 = l1 >= l2; break;
-        case TOK_LE: l1 = l1 <= l2; break;
-        case TOK_GT: l1 = l1 > l2; break;
+        case TOK_ULE: l1 = l1 <= l2; break;
+        case TOK_UGT: l1 = l1 > l2; break;
+        case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
+        case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
+        case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
+        case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
             /* logical */
         case TOK_LAND: l1 = l1 && l2; break;
@@ -1386,5 +1930,8 @@
             goto general_case;
         }
-        v1->c.ll = l1;
+	if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+	    l1 = ((uint32_t)l1 |
+		(v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+        v1->c.i = l1;
         vtop--;
     } else {
@@ -1396,24 +1943,39 @@
             l2 = l1; //l = l1, l1 = l2, l2 = l;
         }
-        /* Filter out NOP operations like x*1, x-0, x&-1... */
-        if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
-                     op == TOK_PDIV) && 
-                    l2 == 1) ||
-                   ((op == '+' || op == '-' || op == '|' || op == '^' || 
-                     op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
-                    l2 == 0) ||
-                   (op == '&' && 
-                    l2 == -1))) {
-            /* nothing to do */
+        if (!const_wanted &&
+            c1 && ((l1 == 0 &&
+                    (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
+                   (l1 == -1 && op == TOK_SAR))) {
+            /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
+            vtop--;
+        } else if (!const_wanted &&
+                   c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
+                          (op == '|' &&
+                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
+                          (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
+            /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
+            if (l2 == 1)
+                vtop->c.i = 0;
+            vswap();
+            vtop--;
+        } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
+                          op == TOK_PDIV) &&
+                           l2 == 1) ||
+                          ((op == '+' || op == '-' || op == '|' || op == '^' ||
+                            op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
+                           l2 == 0) ||
+                          (op == '&' &&
+                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
+            /* filter out NOP operations like x*1, x-0, x&-1... */
             vtop--;
         } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
             /* try to use shifts instead of muls or divs */
             if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
-                n = -1;
+                int n = -1;
                 while (l2) {
                     l2 >>= 1;
                     n++;
                 }
-                vtop->c.ll = n;
+                vtop->c.i = n;
                 if (op == '*')
                     op = TOK_SHL;
@@ -1430,17 +1992,19 @@
             if (op == '-')
                 l2 = -l2;
+	    l2 += vtop[-1].c.i;
+	    /* The backends can't always deal with addends to symbols
+	       larger than +-1<<31.  Don't construct such.  */
+	    if ((int)l2 != l2)
+	        goto general_case;
             vtop--;
-            vtop->c.ll += l2;
+            vtop->c.i = l2;
         } else {
         general_case:
-            if (!nocode_wanted) {
                 /* call low level op generator */
-                if (t1 == VT_LLONG || t2 == VT_LLONG) 
+                if (t1 == VT_LLONG || t2 == VT_LLONG ||
+                    (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
                     gen_opl(op);
                 else
                     gen_opi(op);
-            } else {
-                vtop--;
-            }
         }
     }
@@ -1452,4 +2016,8 @@
     int c1, c2;
     SValue *v1, *v2;
+#if defined _MSC_VER && defined _AMD64_
+    /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
+    volatile
+#endif
     long double f1, f2;
 
@@ -1503,9 +2071,5 @@
     } else {
     general_case:
-        if (!nocode_wanted) {
-            gen_opf(op);
-        } else {
-            vtop--;
-        }
+        gen_opf(op);
     }
 }
@@ -1527,7 +2091,8 @@
     if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
         return 0;
-    return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
-        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) ||
-	((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0);
+    return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
+        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
+        ((p->type.t & VT_BTYPE) == VT_PTR &&
+         (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
 }
 
@@ -1538,5 +2103,5 @@
 }
 
-/* check types for comparison or substraction of pointers */
+/* check types for comparison or subtraction of pointers */
 static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
 {
@@ -1575,6 +2140,6 @@
     tmp_type1 = *type1;
     tmp_type2 = *type2;
-    tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
-    tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
     if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
         /* gcc-like error if '-' is used */
@@ -1592,4 +2157,5 @@
     CType type1;
 
+redo:
     t1 = vtop[-1].type.t;
     t2 = vtop[0].type.t;
@@ -1597,11 +2163,25 @@
     bt2 = t2 & VT_BTYPE;
         
-    if (bt1 == VT_PTR || bt2 == VT_PTR) {
+    if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+        tcc_error("operation on a struct");
+    } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+	if (bt2 == VT_FUNC) {
+	    mk_pointer(&vtop->type);
+	    gaddrof();
+	}
+	if (bt1 == VT_FUNC) {
+	    vswap();
+	    mk_pointer(&vtop->type);
+	    gaddrof();
+	    vswap();
+	}
+	goto redo;
+    } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
         /* at least one operand is a pointer */
-        /* relationnal op: must be both pointers */
+        /* relational op: must be both pointers */
         if (op >= TOK_ULT && op <= TOK_LOR) {
             check_comparison_pointer_types(vtop - 1, vtop, op);
             /* pointers are handled are unsigned */
-#ifdef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
             t = VT_LLONG | VT_UNSIGNED;
 #else
@@ -1623,10 +2203,5 @@
             vrott(3);
             gen_opic(op);
-            /* set to integer type */
-#ifdef TCC_TARGET_X86_64
-            vtop->type.t = VT_LLONG;
-#else
-            vtop->type.t = VT_INT; 
-#endif
+            vtop->type.t = ptrdiff_type.t;
             vswap();
             gen_op(TOK_PDIV);
@@ -1638,6 +2213,11 @@
             if (bt2 == VT_PTR) {
                 vswap();
-                swap(&t1, &t2);
-            }
+                t = t1, t1 = t2, t2 = t;
+            }
+#if PTR_SIZE == 4
+            if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
+                /* XXX: truncate here because gen_opl can't handle ptr + long long */
+                gen_cast_s(VT_INT);
+#endif
             type1 = vtop[-1].type;
             type1.t &= ~VT_ARRAY;
@@ -1648,5 +2228,5 @@
                 if (u < 0)
                     tcc_error("unknown array element size");
-#ifdef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
                 vpushll(u);
 #else
@@ -1656,5 +2236,20 @@
             }
             gen_op('*');
-#ifdef CONFIG_TCC_BCHECK
+#if 0
+/* #ifdef CONFIG_TCC_BCHECK
+    The main reason to removing this code:
+	#include <stdio.h>
+	int main ()
+	{
+	    int v[10];
+	    int i = 10;
+	    int j = 9;
+	    fprintf(stderr, "v+i-j  = %p\n", v+i-j);
+	    fprintf(stderr, "v+(i-j)  = %p\n", v+(i-j));
+	}
+    When this code is on. then the output looks like 
+	v+i-j = 0xfffffffe
+	v+(i-j) = 0xbff84000
+    */
             /* if evaluating constant expression, no code should be
                generated, so no bound check */
@@ -1692,23 +2287,26 @@
     } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
         t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
-        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (t | VT_UNSIGNED))
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
           t |= VT_UNSIGNED;
+        t |= (VT_LONG & t1);
         goto std_op;
     } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
         /* cast to biggest op */
-        t = VT_LLONG;
+        t = VT_LLONG | VT_LONG;
+        if (bt1 == VT_LLONG)
+            t &= t1;
+        if (bt2 == VT_LLONG)
+            t &= t2;
         /* convert to unsigned if it does not fit in a long long */
-        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
-            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
             t |= VT_UNSIGNED;
         goto std_op;
-    } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
-        tcc_error("comparison of struct");
     } else {
         /* integer operations */
-        t = VT_INT;
+        t = VT_INT | (VT_LONG & (t1 | t2));
         /* convert to unsigned if it does not fit in an integer */
-        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
-            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
             t |= VT_UNSIGNED;
     std_op:
@@ -1733,4 +2331,5 @@
         vswap();
         type1.t = t;
+        type1.ref = NULL;
         gen_cast(&type1);
         vswap();
@@ -1745,5 +2344,5 @@
             gen_opic(op);
         if (op >= TOK_ULT && op <= TOK_GT) {
-            /* relationnal op: the result is an int */
+            /* relational op: the result is an int */
             vtop->type.t = VT_INT;
         } else {
@@ -1751,4 +2350,7 @@
         }
     }
+    // Make sure that we have converted to an rvalue:
+    if (vtop->r & VT_LVAL)
+        gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
 }
 
@@ -1757,4 +2359,7 @@
 static void gen_cvt_itof1(int t)
 {
+#ifdef TCC_TARGET_ARM64
+    gen_cvt_itof(t);
+#else
     if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
         (VT_LLONG | VT_UNSIGNED)) {
@@ -1775,4 +2380,5 @@
         gen_cvt_itof(t);
     }
+#endif
 }
 #endif
@@ -1781,4 +2387,7 @@
 static void gen_cvt_ftoi1(int t)
 {
+#ifdef TCC_TARGET_ARM64
+    gen_cvt_ftoi(t);
+#else
     int st;
 
@@ -1802,4 +2411,5 @@
         gen_cvt_ftoi(t);
     }
+#endif
 }
 
@@ -1808,4 +2418,9 @@
 {
     int bits, dbt;
+
+    /* cannot cast static initializers */
+    if (STATIC_DATA_WANTED)
+	return;
+
     dbt = t & VT_BTYPE;
     /* XXX: add optimization if lvalue : just change type and offset */
@@ -1818,5 +2433,8 @@
         gen_op('&');
     } else {
-        bits = 32 - bits;
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+            bits = 64 - bits;
+        else
+            bits = 32 - bits;
         vpushi(bits);
         gen_op(TOK_SHL);
@@ -1831,4 +2449,12 @@
 
 /* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
+static void gen_cast_s(int t)
+{
+    CType type;
+    type.t = t;
+    type.ref = NULL;
+    gen_cast(&type);
+}
+
 static void gen_cast(CType *type)
 {
@@ -1856,4 +2482,7 @@
         c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
         p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
+#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
+        c &= dbt != VT_LDOUBLE;
+#endif
         if (c) {
             /* constant case: we can do it now */
@@ -1866,13 +2495,13 @@
             if (df) {
                 if ((sbt & VT_BTYPE) == VT_LLONG) {
-                    if (sbt & VT_UNSIGNED)
-                        vtop->c.ld = vtop->c.ull;
+                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
+                        vtop->c.ld = vtop->c.i;
                     else
-                        vtop->c.ld = vtop->c.ll;
+                        vtop->c.ld = -(long double)-vtop->c.i;
                 } else if(!sf) {
-                    if (sbt & VT_UNSIGNED)
-                        vtop->c.ld = vtop->c.ui;
+                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
+                        vtop->c.ld = (uint32_t)vtop->c.i;
                     else
-                        vtop->c.ld = vtop->c.i;
+                        vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
                 }
 
@@ -1882,36 +2511,37 @@
                     vtop->c.d = (double)vtop->c.ld;
             } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
-                vtop->c.ull = (unsigned long long)vtop->c.ld;
+                vtop->c.i = vtop->c.ld;
             } else if (sf && dbt == VT_BOOL) {
                 vtop->c.i = (vtop->c.ld != 0);
             } else {
                 if(sf)
-                    vtop->c.ll = (long long)vtop->c.ld;
+                    vtop->c.i = vtop->c.ld;
                 else if (sbt == (VT_LLONG|VT_UNSIGNED))
-                    vtop->c.ll = vtop->c.ull;
+                    ;
                 else if (sbt & VT_UNSIGNED)
-                    vtop->c.ll = vtop->c.ui;
-#ifdef TCC_TARGET_X86_64
+                    vtop->c.i = (uint32_t)vtop->c.i;
+#if PTR_SIZE == 8
                 else if (sbt == VT_PTR)
                     ;
 #endif
                 else if (sbt != VT_LLONG)
-                    vtop->c.ll = vtop->c.i;
+                    vtop->c.i = ((uint32_t)vtop->c.i |
+                                  -(vtop->c.i & 0x80000000));
 
                 if (dbt == (VT_LLONG|VT_UNSIGNED))
-                    vtop->c.ull = vtop->c.ll;
+                    ;
                 else if (dbt == VT_BOOL)
-                    vtop->c.i = (vtop->c.ll != 0);
+                    vtop->c.i = (vtop->c.i != 0);
+#if PTR_SIZE == 8
+                else if (dbt == VT_PTR)
+                    ;
+#endif
                 else if (dbt != VT_LLONG) {
-                    int s = 0;
-                    if ((dbt & VT_BTYPE) == VT_BYTE)
-                        s = 24;
-                    else if ((dbt & VT_BTYPE) == VT_SHORT)
-                        s = 16;
-
-                    if(dbt & VT_UNSIGNED)
-                        vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
-                    else
-                        vtop->c.i = ((int)vtop->c.ll << s) >> s;
+                    uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
+                                  (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
+                                  0xffffffff);
+                    vtop->c.i &= m;
+                    if (!(dbt & VT_UNSIGNED))
+                        vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
                 }
             }
@@ -1919,5 +2549,5 @@
             vtop->r = VT_CONST;
             vtop->c.i = 1;
-        } else if (!nocode_wanted) {
+        } else {
             /* non constant case: generate code */
             if (sf && df) {
@@ -1945,5 +2575,5 @@
                     }
                 }
-#ifndef TCC_TARGET_X86_64
+#if PTR_SIZE == 4
             } else if ((dbt & VT_BTYPE) == VT_LLONG) {
                 if ((sbt & VT_BTYPE) != VT_LLONG) {
@@ -1959,5 +2589,5 @@
                             /* cast from pointer to int before we apply
                                shift operation, which pointers don't support*/
-                            gen_cast(&int_type);
+                            gen_cast_s(VT_INT);
                         }
                         gv_dup();
@@ -1977,9 +2607,16 @@
                     (sbt & VT_BTYPE) != VT_FUNC) {
                     /* need to convert from 32bit to 64bit */
-                    int r = gv(RC_INT);
+                    gv(RC_INT);
                     if (sbt != (VT_INT | VT_UNSIGNED)) {
+#if defined(TCC_TARGET_ARM64)
+                        gen_cvt_sxtw();
+#elif defined(TCC_TARGET_X86_64)
+                        int r = gv(RC_INT);
                         /* x86_64 specific: movslq */
                         o(0x6348);
                         o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
+#else
+#error
+#endif
                     }
                 }
@@ -1996,7 +2633,8 @@
                 }
                 force_charshort_cast(dbt);
+#if PTR_SIZE == 4
             } else if ((dbt & VT_BTYPE) == VT_INT) {
                 /* scalar to int */
-                if (sbt == VT_LLONG) {
+                if ((sbt & VT_BTYPE) == VT_LLONG) {
                     /* from long long: just take low order word */
                     lexpand();
@@ -2006,4 +2644,5 @@
                    the lvalue already contains the real type size (see
                    VT_LVAL_xxx constants) */
+#endif
             }
         }
@@ -2044,4 +2683,6 @@
             return PTR_SIZE;
         }
+    } else if (IS_ENUM(type->t) && type->ref->c == -1) {
+        return -1; /* incomplete enum */
     } else if (bt == VT_LDOUBLE) {
         *a = LDOUBLE_ALIGN;
@@ -2064,5 +2705,5 @@
 #endif
         return 8;
-    } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
+    } else if (bt == VT_INT || bt == VT_FLOAT) {
         *a = 4;
         return 4;
@@ -2070,4 +2711,7 @@
         *a = 2;
         return 2;
+    } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
+        *a = 8;
+        return 16;
     } else {
         /* char, void, function, _Bool */
@@ -2082,4 +2726,5 @@
 {
     if (type->t & VT_VLA) {
+        type_size(&type->ref->type, a);
         vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
     } else {
@@ -2088,4 +2733,16 @@
 }
 
+static void vla_sp_restore(void) {
+    if (vlas_in_scope) {
+        gen_vla_sp_restore(vla_sp_loc);
+    }
+}
+
+static void vla_sp_restore_root(void) {
+    if (vlas_in_scope) {
+        gen_vla_sp_restore(vla_sp_root_loc);
+    }
+}
+
 /* return the pointed type of t */
 static inline CType *pointed_type(CType *type)
@@ -2099,5 +2756,5 @@
     Sym *s;
     s = sym_push(SYM_FIELD, type, 0, -1);
-    type->t = VT_PTR | (type->t & ~VT_TYPE);
+    type->t = VT_PTR | (type->t & VT_STORAGE);
     type->ref = s;
 }
@@ -2113,15 +2770,15 @@
         return 0;
     /* check func_call */
-    if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
+    if (s1->f.func_call != s2->f.func_call)
         return 0;
     /* XXX: not complete */
-    if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
+    if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
         return 1;
-    if (s1->c != s2->c)
+    if (s1->f.func_type != s2->f.func_type)
         return 0;
     while (s1 != NULL) {
         if (s2 == NULL)
             return 0;
-        if (!is_compatible_parameter_types(&s1->type, &s2->type))
+        if (!is_compatible_unqualified_types(&s1->type, &s2->type))
             return 0;
         s1 = s1->next;
@@ -2148,4 +2805,10 @@
         t1 &= ~(VT_CONSTANT | VT_VOLATILE);
         t2 &= ~(VT_CONSTANT | VT_VOLATILE);
+    }
+
+    /* Default Vs explicit signedness only matters for char */
+    if ((t1 & VT_BTYPE) != VT_BYTE) {
+        t1 &= ~VT_DEFSIGN;
+        t2 &= ~VT_DEFSIGN;
     }
     /* XXX: bitfields ? */
@@ -2177,5 +2840,5 @@
 /* return true if type1 and type2 are the same (ignoring qualifiers).
 */
-static int is_compatible_parameter_types(CType *type1, CType *type2)
+static int is_compatible_unqualified_types(CType *type1, CType *type2)
 {
     return compare_types(type1,type2,1);
@@ -2194,13 +2857,31 @@
     const char *tstr;
 
-    t = type->t & VT_TYPE;
+    t = type->t;
     bt = t & VT_BTYPE;
     buf[0] = '\0';
+
+    if (t & VT_EXTERN)
+        pstrcat(buf, buf_size, "extern ");
+    if (t & VT_STATIC)
+        pstrcat(buf, buf_size, "static ");
+    if (t & VT_TYPEDEF)
+        pstrcat(buf, buf_size, "typedef ");
+    if (t & VT_INLINE)
+        pstrcat(buf, buf_size, "inline ");
+    if (t & VT_VOLATILE)
+        pstrcat(buf, buf_size, "volatile ");
     if (t & VT_CONSTANT)
         pstrcat(buf, buf_size, "const ");
-    if (t & VT_VOLATILE)
-        pstrcat(buf, buf_size, "volatile ");
-    if (t & VT_UNSIGNED)
-        pstrcat(buf, buf_size, "unsigned ");
+
+    if (((t & VT_DEFSIGN) && bt == VT_BYTE)
+        || ((t & VT_UNSIGNED)
+            && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
+            && !IS_ENUM(t)
+            ))
+        pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
+
+    buf_size -= strlen(buf);
+    buf += strlen(buf);
+
     switch(bt) {
     case VT_VOID:
@@ -2218,11 +2899,14 @@
     case VT_INT:
         tstr = "int";
-        goto add_tstr;
-    case VT_LONG:
-        tstr = "long";
-        goto add_tstr;
+        goto maybe_long;
     case VT_LLONG:
         tstr = "long long";
-        goto add_tstr;
+    maybe_long:
+        if (t & VT_LONG)
+            tstr = "long";
+        if (!IS_ENUM(t))
+            goto add_tstr;
+        tstr = "enum ";
+        goto tstruct;
     case VT_FLOAT:
         tstr = "float";
@@ -2236,10 +2920,9 @@
         pstrcat(buf, buf_size, tstr);
         break;
-    case VT_ENUM:
     case VT_STRUCT:
-        if (bt == VT_STRUCT)
-            tstr = "struct ";
-        else
-            tstr = "enum ";
+        tstr = "struct ";
+        if (IS_UNION(t))
+            tstr = "union ";
+    tstruct:
         pstrcat(buf, buf_size, tstr);
         v = type->ref->v & ~SYM_STRUCT;
@@ -2265,5 +2948,14 @@
     case VT_PTR:
         s = type->ref;
+        if (t & VT_ARRAY) {
+            snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
+            type_to_str(buf, buf_size, &s->type, buf1);
+            goto no_var;
+        }
         pstrcpy(buf1, sizeof(buf1), "*");
+        if (t & VT_CONSTANT)
+            pstrcat(buf1, buf_size, "const ");
+        if (t & VT_VOLATILE)
+            pstrcat(buf1, buf_size, "volatile ");
         if (varstr)
             pstrcat(buf1, sizeof(buf1), varstr);
@@ -2282,5 +2974,5 @@
 static void gen_assign_cast(CType *dt)
 {
-    CType *st, *type1, *type2, tmp_type1, tmp_type2;
+    CType *st, *type1, *type2;
     char buf1[256], buf2[256];
     int dbt, sbt;
@@ -2289,6 +2981,18 @@
     dbt = dt->t & VT_BTYPE;
     sbt = st->t & VT_BTYPE;
-    if (sbt == VT_VOID)
-        tcc_error("Cannot assign void value");
+    if (sbt == VT_VOID || dbt == VT_VOID) {
+	if (sbt == VT_VOID && dbt == VT_VOID)
+	    ; /*
+	      It is Ok if both are void
+	      A test program:
+	        void func1() {}
+		void func2() {
+		  return func1();
+		}
+	      gcc accepts this program
+	      */
+	else
+    	    tcc_error("cannot cast from/to void");
+    }
     if (dt->t & VT_CONSTANT)
         tcc_warning("assignment of read-only location");
@@ -2305,5 +3009,5 @@
         }
         type1 = pointed_type(dt);
-        /* a function is implicitely a function pointer */
+        /* a function is implicitly a function pointer */
         if (sbt == VT_FUNC) {
             if ((type1->t & VT_BTYPE) != VT_VOID &&
@@ -2319,11 +3023,16 @@
             /* void * can match anything */
         } else {
-            /* exact type match, except for unsigned */
-            tmp_type1 = *type1;
-            tmp_type2 = *type2;
-            tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
-            tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
-            if (!is_compatible_types(&tmp_type1, &tmp_type2))
-                tcc_warning("assignment from incompatible pointer type");
+            //printf("types %08x %08x\n", type1->t, type2->t);
+            /* exact type match, except for qualifiers */
+            if (!is_compatible_unqualified_types(type1, type2)) {
+		/* Like GCC don't warn by default for merely changes
+		   in pointer target signedness.  Do warn for different
+		   base types, though, in particular for unsigned enums
+		   and signed int targets.  */
+		if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
+                    || IS_ENUM(type1->t) || IS_ENUM(type2->t)
+                    )
+		    tcc_warning("assignment from incompatible pointer type");
+	    }
         }
         /* check const and volatile */
@@ -2338,13 +3047,12 @@
         if (sbt == VT_PTR || sbt == VT_FUNC) {
             tcc_warning("assignment makes integer from pointer without a cast");
+        } else if (sbt == VT_STRUCT) {
+            goto case_VT_STRUCT;
         }
         /* XXX: more tests */
         break;
     case VT_STRUCT:
-        tmp_type1 = *dt;
-        tmp_type2 = *st;
-        tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
-        tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
-        if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
+    case_VT_STRUCT:
+        if (!is_compatible_unqualified_types(dt, st)) {
         error:
             type_to_str(buf1, sizeof(buf1), st, NULL);
@@ -2371,5 +3079,5 @@
         /* optimize char/short casts */
         delayed_cast = VT_MUSTCAST;
-        vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
+        vtop->type.t = ft & VT_TYPE;
         /* XXX: factorize */
         if (ft & VT_CONSTANT)
@@ -2385,5 +3093,4 @@
         /* structure assignment : generate memcpy */
         /* XXX: optimize if small size */
-        if (!nocode_wanted) {
             size = type_size(&vtop->type, &align);
 
@@ -2401,5 +3108,6 @@
             else
 #endif
-            vpush_global_sym(&func_old_type, TOK_memcpy);
+            /* Use memmove, rather than memcpy, as dest and src may be same: */
+            vpush_global_sym(&func_old_type, TOK_memmove);
 
             vswap();
@@ -2411,66 +3119,66 @@
             vpushi(size);
             gfunc_call(3);
-        } else {
-            vswap();
-            vpop();
-        }
+
         /* leave source on stack */
     } else if (ft & VT_BITFIELD) {
         /* bitfield store handling */
-        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
-        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
+
+        /* save lvalue as expression result (example: s.b = s.a = n;) */
+        vdup(), vtop[-1] = vtop[-2];
+
+        bit_pos = BIT_POS(ft);
+        bit_size = BIT_SIZE(ft);
         /* remove bit field info to avoid loops */
-        vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
-
-        /* duplicate source into other register */
-        gv_dup();
-        vswap();
-        vrott(3);
-
-        if((ft & VT_BTYPE) == VT_BOOL) {
+        vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
+
+        if ((ft & VT_BTYPE) == VT_BOOL) {
             gen_cast(&vtop[-1].type);
             vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
         }
 
-        /* duplicate destination */
-        vdup();
-        vtop[-1] = vtop[-2];
-
-        /* mask and shift source */
-        if((ft & VT_BTYPE) != VT_BOOL) {
-            if((ft & VT_BTYPE) == VT_LLONG) {
-                vpushll((1ULL << bit_size) - 1ULL);
-            } else {
-                vpushi((1 << bit_size) - 1);
-            }
+        r = adjust_bf(vtop - 1, bit_pos, bit_size);
+        if (r == VT_STRUCT) {
+            gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
+            store_packed_bf(bit_pos, bit_size);
+        } else {
+            unsigned long long mask = (1ULL << bit_size) - 1;
+            if ((ft & VT_BTYPE) != VT_BOOL) {
+                /* mask source */
+                if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
+                    vpushll(mask);
+                else
+                    vpushi((unsigned)mask);
+                gen_op('&');
+            }
+            /* shift source */
+            vpushi(bit_pos);
+            gen_op(TOK_SHL);
+            vswap();
+            /* duplicate destination */
+            vdup();
+            vrott(3);
+            /* load destination, mask and or with source */
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+                vpushll(~(mask << bit_pos));
+            else
+                vpushi(~((unsigned)mask << bit_pos));
             gen_op('&');
-        }
-        vpushi(bit_pos);
-        gen_op(TOK_SHL);
-        /* load destination, mask and or with source */
-        vswap();
-        if((ft & VT_BTYPE) == VT_LLONG) {
-            vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
-        } else {
-            vpushi(~(((1 << bit_size) - 1) << bit_pos));
-        }
-        gen_op('&');
-        gen_op('|');
-        /* store result */
-        vstore();
-
-        /* pop off shifted source from "duplicate source..." above */
-        vpop();
-
+            gen_op('|');
+            /* store result */
+            vstore();
+            /* ... and discard */
+            vpop();
+        }
+    } else if (dbt == VT_VOID) {
+        --vtop;
     } else {
 #ifdef CONFIG_TCC_BCHECK
-        /* bound check case */
-        if (vtop[-1].r & VT_MUSTBOUND) {
-            vswap();
-            gbound();
-            vswap();
-        }
-#endif
-        if (!nocode_wanted) {
+            /* bound check case */
+            if (vtop[-1].r & VT_MUSTBOUND) {
+                vswap();
+                gbound();
+                vswap();
+            }
+#endif
             rc = RC_INT;
             if (is_float(ft)) {
@@ -2479,4 +3187,6 @@
                 if ((ft & VT_BTYPE) == VT_LDOUBLE) {
                     rc = RC_ST0;
+                } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
+                    rc = RC_FRET;
                 }
 #endif
@@ -2487,5 +3197,5 @@
                 SValue sv;
                 t = get_reg(RC_INT);
-#ifdef TCC_TARGET_X86_64
+#if PTR_SIZE == 8
                 sv.type.t = VT_PTR;
 #else
@@ -2493,25 +3203,33 @@
 #endif
                 sv.r = VT_LOCAL | VT_LVAL;
-                sv.c.ul = vtop[-1].c.ul;
+                sv.c.i = vtop[-1].c.i;
                 load(t, &sv);
                 vtop[-1].r = t | VT_LVAL;
             }
-            store(r, vtop - 1);
-#ifndef TCC_TARGET_X86_64
-            /* two word case handling : store second register at word + 4 */
+            /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
+#if PTR_SIZE == 8
+            if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
+                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
             if ((ft & VT_BTYPE) == VT_LLONG) {
+                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
+#endif
+                vtop[-1].type.t = load_type;
+                store(r, vtop - 1);
                 vswap();
                 /* convert to int to increment easily */
-                vtop->type.t = VT_INT;
+                vtop->type.t = addr_type;
                 gaddrof();
-                vpushi(4);
+                vpushi(load_size);
                 gen_op('+');
                 vtop->r |= VT_LVAL;
                 vswap();
+                vtop[-1].type.t = load_type;
                 /* XXX: it works because r2 is spilled last ! */
                 store(vtop->r2, vtop - 1);
-            }
-#endif
-        }
+            } else {
+                store(r, vtop - 1);
+            }
+
         vswap();
         vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
@@ -2538,17 +3256,45 @@
 }
 
-/* Parse GNUC __attribute__ extension. Currently, the following
-   extensions are recognized:
-   - aligned(n) : set data/function alignment.
-   - packed : force data alignment to 1
-   - section(x) : generate data/code in this section.
-   - unused : currently ignored, but may be used someday.
-   - regparm(n) : pass function parameters in registers (i386 only)
- */
+ST_FUNC void parse_mult_str (CString *astr, const char *msg)
+{
+    /* read the string */
+    if (tok != TOK_STR)
+        expect(msg);
+    cstr_new(astr);
+    while (tok == TOK_STR) {
+        /* XXX: add \0 handling too ? */
+        cstr_cat(astr, tokc.str.data, -1);
+        next();
+    }
+    cstr_ccat(astr, '\0');
+}
+
+/* If I is >= 1 and a power of two, returns log2(i)+1.
+   If I is 0 returns 0.  */
+static int exact_log2p1(int i)
+{
+  int ret;
+  if (!i)
+    return 0;
+  for (ret = 1; i >= 1 << 8; ret += 8)
+    i >>= 8;
+  if (i >= 1 << 4)
+    ret += 4, i >>= 4;
+  if (i >= 1 << 2)
+    ret += 2, i >>= 2;
+  if (i >= 1 << 1)
+    ret++;
+  return ret;
+}
+
+/* Parse __attribute__((...)) GNUC extension. */
 static void parse_attribute(AttributeDef *ad)
 {
     int t, n;
+    CString astr;
     
-    while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
+redo:
+    if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
+        return;
     next();
     skip('(');
@@ -2563,19 +3309,35 @@
         case TOK_SECTION2:
             skip('(');
-            if (tok != TOK_STR)
-                expect("section name");
-            ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
-            next();
+	    parse_mult_str(&astr, "section name");
+            ad->section = find_section(tcc_state, (char *)astr.data);
             skip(')');
+	    cstr_free(&astr);
             break;
         case TOK_ALIAS1:
         case TOK_ALIAS2:
             skip('(');
-            if (tok != TOK_STR)
-                expect("alias(\"target\")");
+	    parse_mult_str(&astr, "alias(\"target\")");
             ad->alias_target = /* save string as token, for later */
-              tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
-            next();
+              tok_alloc((char*)astr.data, astr.size-1)->tok;
             skip(')');
+	    cstr_free(&astr);
+            break;
+	case TOK_VISIBILITY1:
+	case TOK_VISIBILITY2:
+            skip('(');
+	    parse_mult_str(&astr,
+			   "visibility(\"default|hidden|internal|protected\")");
+	    if (!strcmp (astr.data, "default"))
+	        ad->a.visibility = STV_DEFAULT;
+	    else if (!strcmp (astr.data, "hidden"))
+	        ad->a.visibility = STV_HIDDEN;
+	    else if (!strcmp (astr.data, "internal"))
+	        ad->a.visibility = STV_INTERNAL;
+	    else if (!strcmp (astr.data, "protected"))
+	        ad->a.visibility = STV_PROTECTED;
+	    else
+                expect("visibility(\"default|hidden|internal|protected\")");
+            skip(')');
+	    cstr_free(&astr);
             break;
         case TOK_ALIGNED1:
@@ -2590,13 +3352,15 @@
                 n = MAX_ALIGN;
             }
-            ad->aligned = n;
+            ad->a.aligned = exact_log2p1(n);
+	    if (n != 1 << (ad->a.aligned - 1))
+	      tcc_error("alignment of %d is larger than implemented", n);
             break;
         case TOK_PACKED1:
         case TOK_PACKED2:
-            ad->packed = 1;
+            ad->a.packed = 1;
             break;
         case TOK_WEAK1:
         case TOK_WEAK2:
-            ad->weak = 1;
+            ad->a.weak = 1;
             break;
         case TOK_UNUSED1:
@@ -2613,10 +3377,10 @@
         case TOK_CDECL2:
         case TOK_CDECL3:
-            ad->func_call = FUNC_CDECL;
+            ad->f.func_call = FUNC_CDECL;
             break;
         case TOK_STDCALL1:
         case TOK_STDCALL2:
         case TOK_STDCALL3:
-            ad->func_call = FUNC_STDCALL;
+            ad->f.func_call = FUNC_STDCALL;
             break;
 #ifdef TCC_TARGET_I386
@@ -2630,5 +3394,5 @@
                 n = 0;
             if (n > 0)
-                ad->func_call = FUNC_FASTCALL1 + n - 1;
+                ad->f.func_call = FUNC_FASTCALL1 + n - 1;
             skip(')');
             break;
@@ -2636,5 +3400,5 @@
         case TOK_FASTCALL2:
         case TOK_FASTCALL3:
-            ad->func_call = FUNC_FASTCALLW;
+            ad->f.func_call = FUNC_FASTCALLW;
             break;            
 #endif
@@ -2643,11 +3407,15 @@
             switch(tok) {
                 case TOK_MODE_DI:
-                    ad->mode = VT_LLONG + 1;
+                    ad->attr_mode = VT_LLONG + 1;
+                    break;
+                case TOK_MODE_QI:
+                    ad->attr_mode = VT_BYTE + 1;
                     break;
                 case TOK_MODE_HI:
-                    ad->mode = VT_SHORT + 1;
+                    ad->attr_mode = VT_SHORT + 1;
                     break;
                 case TOK_MODE_SI:
-                    ad->mode = VT_INT + 1;
+                case TOK_MODE_word:
+                    ad->attr_mode = VT_INT + 1;
                     break;
                 default:
@@ -2659,8 +3427,8 @@
             break;
         case TOK_DLLEXPORT:
-            ad->func_export = 1;
+            ad->a.dllexport = 1;
             break;
         case TOK_DLLIMPORT:
-            ad->func_import = 1;
+            ad->a.dllimport = 1;
             break;
         default:
@@ -2686,18 +3454,322 @@
     skip(')');
     skip(')');
-    }
-}
-
-/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
+    goto redo;
+}
+
+static Sym * find_field (CType *type, int v)
+{
+    Sym *s = type->ref;
+    v |= SYM_FIELD;
+    while ((s = s->next) != NULL) {
+	if ((s->v & SYM_FIELD) &&
+	    (s->type.t & VT_BTYPE) == VT_STRUCT &&
+	    (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+	    Sym *ret = find_field (&s->type, v);
+	    if (ret)
+	        return ret;
+	}
+	if (s->v == v)
+	  break;
+    }
+    return s;
+}
+
+static void struct_add_offset (Sym *s, int offset)
+{
+    while ((s = s->next) != NULL) {
+	if ((s->v & SYM_FIELD) &&
+	    (s->type.t & VT_BTYPE) == VT_STRUCT &&
+	    (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+	    struct_add_offset(s->type.ref, offset);
+	} else
+	  s->c += offset;
+    }
+}
+
+static void struct_layout(CType *type, AttributeDef *ad)
+{
+    int size, align, maxalign, offset, c, bit_pos, bit_size;
+    int packed, a, bt, prevbt, prev_bit_size;
+    int pcc = !tcc_state->ms_bitfields;
+    int pragma_pack = *tcc_state->pack_stack_ptr;
+    Sym *f;
+
+    maxalign = 1;
+    offset = 0;
+    c = 0;
+    bit_pos = 0;
+    prevbt = VT_STRUCT; /* make it never match */
+    prev_bit_size = 0;
+
+//#define BF_DEBUG
+
+    for (f = type->ref->next; f; f = f->next) {
+        if (f->type.t & VT_BITFIELD)
+            bit_size = BIT_SIZE(f->type.t);
+        else
+            bit_size = -1;
+        size = type_size(&f->type, &align);
+        a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
+        packed = 0;
+
+        if (pcc && bit_size == 0) {
+            /* in pcc mode, packing does not affect zero-width bitfields */
+
+        } else {
+            /* in pcc mode, attribute packed overrides if set. */
+            if (pcc && (f->a.packed || ad->a.packed))
+                align = packed = 1;
+
+            /* pragma pack overrides align if lesser and packs bitfields always */
+            if (pragma_pack) {
+                packed = 1;
+                if (pragma_pack < align)
+                    align = pragma_pack;
+                /* in pcc mode pragma pack also overrides individual align */
+                if (pcc && pragma_pack < a)
+                    a = 0;
+            }
+        }
+        /* some individual align was specified */
+        if (a)
+            align = a;
+
+        if (type->ref->type.t == VT_UNION) {
+	    if (pcc && bit_size >= 0)
+	        size = (bit_size + 7) >> 3;
+	    offset = 0;
+	    if (size > c)
+	        c = size;
+
+	} else if (bit_size < 0) {
+            if (pcc)
+                c += (bit_pos + 7) >> 3;
+	    c = (c + align - 1) & -align;
+	    offset = c;
+	    if (size > 0)
+	        c += size;
+	    bit_pos = 0;
+	    prevbt = VT_STRUCT;
+	    prev_bit_size = 0;
+
+	} else {
+	    /* A bit-field.  Layout is more complicated.  There are two
+	       options: PCC (GCC) compatible and MS compatible */
+            if (pcc) {
+		/* In PCC layout a bit-field is placed adjacent to the
+                   preceding bit-fields, except if:
+                   - it has zero-width
+                   - an individual alignment was given
+                   - it would overflow its base type container and
+                     there is no packing */
+                if (bit_size == 0) {
+            new_field:
+		    c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
+		    bit_pos = 0;
+                } else if (f->a.aligned) {
+                    goto new_field;
+                } else if (!packed) {
+                    int a8 = align * 8;
+	            int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
+                    if (ofs > size / align)
+                        goto new_field;
+                }
+
+                /* in pcc mode, long long bitfields have type int if they fit */
+                if (size == 8 && bit_size <= 32)
+                    f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
+
+                while (bit_pos >= align * 8)
+                    c += align, bit_pos -= align * 8;
+                offset = c;
+
+		/* In PCC layout named bit-fields influence the alignment
+		   of the containing struct using the base types alignment,
+		   except for packed fields (which here have correct align).  */
+		if (f->v & SYM_FIRST_ANOM
+                    // && bit_size // ??? gcc on ARM/rpi does that
+                    )
+		    align = 1;
+
+	    } else {
+		bt = f->type.t & VT_BTYPE;
+		if ((bit_pos + bit_size > size * 8)
+                    || (bit_size > 0) == (bt != prevbt)
+                    ) {
+		    c = (c + align - 1) & -align;
+		    offset = c;
+		    bit_pos = 0;
+		    /* In MS bitfield mode a bit-field run always uses
+		       at least as many bits as the underlying type.
+		       To start a new run it's also required that this
+		       or the last bit-field had non-zero width.  */
+		    if (bit_size || prev_bit_size)
+		        c += size;
+		}
+		/* In MS layout the records alignment is normally
+		   influenced by the field, except for a zero-width
+		   field at the start of a run (but by further zero-width
+		   fields it is again).  */
+		if (bit_size == 0 && prevbt != bt)
+		    align = 1;
+		prevbt = bt;
+                prev_bit_size = bit_size;
+	    }
+
+	    f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+		        | (bit_pos << VT_STRUCT_SHIFT);
+	    bit_pos += bit_size;
+	}
+	if (align > maxalign)
+	    maxalign = align;
+
+#ifdef BF_DEBUG
+	printf("set field %s offset %-2d size %-2d align %-2d",
+	       get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
+	if (f->type.t & VT_BITFIELD) {
+	    printf(" pos %-2d bits %-2d",
+                    BIT_POS(f->type.t),
+                    BIT_SIZE(f->type.t)
+                    );
+	}
+	printf("\n");
+#endif
+
+	if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
+	    Sym *ass;
+	    /* An anonymous struct/union.  Adjust member offsets
+	       to reflect the real offset of our containing struct.
+	       Also set the offset of this anon member inside
+	       the outer struct to be zero.  Via this it
+	       works when accessing the field offset directly
+	       (from base object), as well as when recursing
+	       members in initializer handling.  */
+	    int v2 = f->type.ref->v;
+	    if (!(v2 & SYM_FIELD) &&
+		(v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+		Sym **pps;
+		/* This happens only with MS extensions.  The
+		   anon member has a named struct type, so it
+		   potentially is shared with other references.
+		   We need to unshare members so we can modify
+		   them.  */
+		ass = f->type.ref;
+		f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
+				       &f->type.ref->type, 0,
+				       f->type.ref->c);
+		pps = &f->type.ref->next;
+		while ((ass = ass->next) != NULL) {
+		    *pps = sym_push(ass->v, &ass->type, 0, ass->c);
+		    pps = &((*pps)->next);
+		}
+		*pps = NULL;
+	    }
+	    struct_add_offset(f->type.ref, offset);
+	    f->c = 0;
+	} else {
+	    f->c = offset;
+	}
+
+	f->r = 0;
+    }
+
+    if (pcc)
+        c += (bit_pos + 7) >> 3;
+
+    /* store size and alignment */
+    a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
+    if (a < maxalign)
+        a = maxalign;
+    type->ref->r = a;
+    if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
+        /* can happen if individual align for some member was given.  In
+           this case MSVC ignores maxalign when aligning the size */
+        a = pragma_pack;
+        if (a < bt)
+            a = bt;
+    }
+    c = (c + a - 1) & -a;
+    type->ref->c = c;
+
+#ifdef BF_DEBUG
+    printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
+#endif
+
+    /* check whether we can access bitfields by their type */
+    for (f = type->ref->next; f; f = f->next) {
+        int s, px, cx, c0;
+        CType t;
+
+        if (0 == (f->type.t & VT_BITFIELD))
+            continue;
+        f->type.ref = f;
+        f->auxtype = -1;
+        bit_size = BIT_SIZE(f->type.t);
+        if (bit_size == 0)
+            continue;
+        bit_pos = BIT_POS(f->type.t);
+        size = type_size(&f->type, &align);
+        if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
+            continue;
+
+        /* try to access the field using a different type */
+        c0 = -1, s = align = 1;
+        for (;;) {
+            px = f->c * 8 + bit_pos;
+            cx = (px >> 3) & -align;
+            px = px - (cx << 3);
+            if (c0 == cx)
+                break;
+            s = (px + bit_size + 7) >> 3;
+            if (s > 4) {
+                t.t = VT_LLONG;
+            } else if (s > 2) {
+                t.t = VT_INT;
+            } else if (s > 1) {
+                t.t = VT_SHORT;
+            } else {
+                t.t = VT_BYTE;
+            }
+            s = type_size(&t, &align);
+            c0 = cx;
+        }
+
+        if (px + bit_size <= s * 8 && cx + s <= c) {
+            /* update offset and bit position */
+            f->c = cx;
+            bit_pos = px;
+	    f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+		        | (bit_pos << VT_STRUCT_SHIFT);
+            if (s != size)
+                f->auxtype = t.t;
+#ifdef BF_DEBUG
+            printf("FIX field %s offset %-2d size %-2d align %-2d "
+                "pos %-2d bits %-2d\n",
+                get_tok_str(f->v & ~SYM_FIELD, NULL),
+                cx, s, align, px, bit_size);
+#endif
+        } else {
+            /* fall back to load/store single-byte wise */
+            f->auxtype = VT_STRUCT;
+#ifdef BF_DEBUG
+            printf("FIX field %s : load byte-wise\n",
+                 get_tok_str(f->v & ~SYM_FIELD, NULL));
+#endif
+        }
+    }
+}
+
+/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
 static void struct_decl(CType *type, int u)
 {
-    int a, v, size, align, maxalign, c, offset;
-    int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
-    Sym *s, *ss, *ass, **ps;
-    AttributeDef ad;
+    int v, c, size, align, flexible;
+    int bit_size, bsize, bt;
+    Sym *s, *ss, **ps;
+    AttributeDef ad, ad1;
     CType type1, btype;
 
-    a = tok; /* save decl type */
+    memset(&ad, 0, sizeof ad);
     next();
+    parse_attribute(&ad);
     if (tok != '{') {
         v = tok;
@@ -2707,21 +3779,24 @@
             expect("struct/union/enum name");
         s = struct_find(v);
-        if (s) {
-            if (s->type.t != a)
-                tcc_error("invalid type");
-            goto do_decl;
+        if (s && (s->sym_scope == local_scope || tok != '{')) {
+            if (u == s->type.t)
+                goto do_decl;
+            if (u == VT_ENUM && IS_ENUM(s->type.t))
+                goto do_decl;
+            tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
         }
     } else {
         v = anon_sym++;
     }
-    type1.t = a;
+    /* Record the original enum/struct/union token.  */
+    type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
+    type1.ref = NULL;
     /* we put an undefined size for struct/union */
     s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
     s->r = 0; /* default alignment is zero as gcc */
-    /* put struct/union/enum name in type */
- do_decl:
-    type->t = u;
+do_decl:
+    type->t = s->type.t;
     type->ref = s;
-    
+
     if (tok == '{') {
         next();
@@ -2729,23 +3804,36 @@
             tcc_error("struct/union/enum already defined");
         /* cannot be empty */
-        c = 0;
         /* non empty enums are not allowed */
-        if (a == TOK_ENUM) {
+        ps = &s->next;
+        if (u == VT_ENUM) {
+            long long ll = 0, pl = 0, nl = 0;
+	    CType t;
+            t.ref = s;
+            /* enum symbols have static storage */
+            t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
             for(;;) {
                 v = tok;
                 if (v < TOK_UIDENT)
                     expect("identifier");
+                ss = sym_find(v);
+                if (ss && !local_stack)
+                    tcc_error("redefinition of enumerator '%s'",
+                              get_tok_str(v, NULL));
                 next();
                 if (tok == '=') {
                     next();
-                    c = expr_const();
+		    ll = expr_const64();
                 }
-                /* enum symbols have static storage */
-                ss = sym_push(v, &int_type, VT_CONST, c);
-                ss->type.t |= VT_STATIC;
+                ss = sym_push(v, &t, VT_CONST, 0);
+                ss->enum_val = ll;
+                *ps = ss, ps = &ss->next;
+                if (ll < nl)
+                    nl = ll;
+                if (ll > pl)
+                    pl = ll;
                 if (tok != ',')
                     break;
                 next();
-                c++;
+                ll++;
                 /* NOTE: we accept a trailing comma */
                 if (tok == '}')
@@ -2753,22 +3841,65 @@
             }
             skip('}');
+            /* set integral type of the enum */
+            t.t = VT_INT;
+            if (nl >= 0) {
+                if (pl != (unsigned)pl)
+                    t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+                t.t |= VT_UNSIGNED;
+            } else if (pl != (int)pl || nl != (int)nl)
+                t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+            s->type.t = type->t = t.t | VT_ENUM;
+            s->c = 0;
+            /* set type for enum members */
+            for (ss = s->next; ss; ss = ss->next) {
+                ll = ss->enum_val;
+                if (ll == (int)ll) /* default is int if it fits */
+                    continue;
+                if (t.t & VT_UNSIGNED) {
+                    ss->type.t |= VT_UNSIGNED;
+                    if (ll == (unsigned)ll)
+                        continue;
+                }
+                ss->type.t = (ss->type.t & ~VT_BTYPE)
+                    | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+            }
         } else {
-            maxalign = 1;
-            ps = &s->next;
-            prevbt = VT_INT;
-            bit_pos = 0;
-            offset = 0;
+            c = 0;
+            flexible = 0;
             while (tok != '}') {
-                parse_btype(&btype, &ad);
+                if (!parse_btype(&btype, &ad1)) {
+		    skip(';');
+		    continue;
+		}
                 while (1) {
+		    if (flexible)
+		        tcc_error("flexible array member '%s' not at the end of struct",
+                              get_tok_str(v, NULL));
                     bit_size = -1;
                     v = 0;
                     type1 = btype;
                     if (tok != ':') {
-                        type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
-                        if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
-                            expect("identifier");
+			if (tok != ';')
+                            type_decl(&type1, &ad1, &v, TYPE_DIRECT);
+                        if (v == 0) {
+                    	    if ((type1.t & VT_BTYPE) != VT_STRUCT)
+                        	expect("identifier");
+                    	    else {
+				int v = btype.ref->v;
+				if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+				    if (tcc_state->ms_extensions == 0)
+                        		expect("identifier");
+				}
+                    	    }
+                        }
+                        if (type_size(&type1, &align) < 0) {
+			    if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
+			        flexible = 1;
+			    else
+			        tcc_error("field '%s' has incomplete type",
+                                      get_tok_str(v, NULL));
+                        }
                         if ((type1.t & VT_BTYPE) == VT_FUNC ||
-                            (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
+                            (type1.t & VT_STORAGE))
                             tcc_error("invalid type for '%s'", 
                                   get_tok_str(v, NULL));
@@ -2784,16 +3915,7 @@
                             tcc_error("zero width for bit-field '%s'", 
                                   get_tok_str(v, NULL));
+			parse_attribute(&ad1);
                     }
                     size = type_size(&type1, &align);
-                    if (ad.aligned) {
-                        if (align < ad.aligned)
-                            align = ad.aligned;
-                    } else if (ad.packed) {
-                        align = 1;
-                    } else if (*tcc_state->pack_stack_ptr) {
-                        if (align > *tcc_state->pack_stack_ptr)
-                            align = *tcc_state->pack_stack_ptr;
-                    }
-                    lbit_pos = 0;
                     if (bit_size >= 0) {
                         bt = type1.t & VT_BTYPE;
@@ -2802,5 +3924,4 @@
                             bt != VT_SHORT &&
                             bt != VT_BOOL &&
-                            bt != VT_ENUM &&
                             bt != VT_LLONG)
                             tcc_error("bitfields must have scalar type");
@@ -2809,67 +3930,31 @@
                             tcc_error("width of '%s' exceeds its type",
                                   get_tok_str(v, NULL));
-                        } else if (bit_size == bsize) {
+                        } else if (bit_size == bsize
+                                    && !ad.a.packed && !ad1.a.packed) {
                             /* no need for bit fields */
-                            bit_pos = 0;
-                        } else if (bit_size == 0) {
-                            /* XXX: what to do if only padding in a
-                               structure ? */
-                            /* zero size: means to pad */
-                            bit_pos = 0;
+                            ;
+                        } else if (bit_size == 64) {
+                            tcc_error("field width 64 not implemented");
                         } else {
-                            /* we do not have enough room ?
-                               did the type change?
-                               is it a union? */
-                            if ((bit_pos + bit_size) > bsize ||
-                                bt != prevbt || a == TOK_UNION)
-                                bit_pos = 0;
-                            lbit_pos = bit_pos;
-                            /* XXX: handle LSB first */
-                            type1.t |= VT_BITFIELD | 
-                                (bit_pos << VT_STRUCT_SHIFT) |
-                                (bit_size << (VT_STRUCT_SHIFT + 6));
-                            bit_pos += bit_size;
+                            type1.t = (type1.t & ~VT_STRUCT_MASK)
+                                | VT_BITFIELD
+                                | (bit_size << (VT_STRUCT_SHIFT + 6));
                         }
-                        prevbt = bt;
-                    } else {
-                        bit_pos = 0;
                     }
                     if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
-                        /* add new memory data only if starting
-                           bit field */
-                        if (lbit_pos == 0) {
-                            if (a == TOK_STRUCT) {
-                                c = (c + align - 1) & -align;
-                                offset = c;
-                                if (size > 0)
-                                    c += size;
-                            } else {
-                                offset = 0;
-                                if (size > c)
-                                    c = size;
-                            }
-                            if (align > maxalign)
-                                maxalign = align;
-                        }
-#if 0
-                        printf("add field %s offset=%d", 
-                               get_tok_str(v, NULL), offset);
-                        if (type1.t & VT_BITFIELD) {
-                            printf(" pos=%d size=%d", 
-                                   (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
-                                   (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
-                        }
-                        printf("\n");
-#endif
+                        /* Remember we've seen a real field to check
+			   for placement of flexible array member. */
+			c = 1;
                     }
-                    if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
-                        ass = type1.ref;
-                        while ((ass = ass->next) != NULL) {
-                           ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
-                           *ps = ss;
-                           ps = &ss->next;
-                        }
-                    } else if (v) {
-                        ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
+		    /* If member is a struct or bit-field, enforce
+		       placing into the struct (as anonymous).  */
+                    if (v == 0 &&
+			((type1.t & VT_BTYPE) == VT_STRUCT ||
+			 bit_size >= 0)) {
+		        v = anon_sym++;
+		    }
+                    if (v) {
+                        ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
+                        ss->a = ad1.a;
                         *ps = ss;
                         ps = &ss->next;
@@ -2882,9 +3967,31 @@
             }
             skip('}');
-            /* store size and alignment */
-            s->c = (c + maxalign - 1) & -maxalign; 
-            s->r = maxalign;
-        }
-    }
+	    parse_attribute(&ad);
+	    struct_layout(type, &ad);
+        }
+    }
+}
+
+static void sym_to_attr(AttributeDef *ad, Sym *s)
+{
+    if (s->a.aligned && 0 == ad->a.aligned)
+        ad->a.aligned = s->a.aligned;
+    if (s->f.func_call && 0 == ad->f.func_call)
+        ad->f.func_call = s->f.func_call;
+    if (s->f.func_type && 0 == ad->f.func_type)
+        ad->f.func_type = s->f.func_type;
+    if (s->a.packed)
+        ad->a.packed = 1;
+}
+
+/* Add type qualifiers to a type. If the type is an array then the qualifiers
+   are added to the element type, copied because it could be a typedef. */
+static void parse_btype_qualify(CType *type, int qualifiers)
+{
+    while (type->t & VT_ARRAY) {
+        type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
+        type = &type->ref->type;
+    }
+    type->t |= qualifiers;
 }
 
@@ -2894,5 +4001,5 @@
 static int parse_btype(CType *type, AttributeDef *ad)
 {
-    int t, u, type_found, typespec_found, typedef_found;
+    int t, u, bt, st, type_found, typespec_found, g;
     Sym *s;
     CType type1;
@@ -2901,6 +4008,8 @@
     type_found = 0;
     typespec_found = 0;
-    typedef_found = 0;
-    t = 0;
+    t = VT_INT;
+    bt = st = -1;
+    type->ref = NULL;
+
     while(1) {
         switch(tok) {
@@ -2916,7 +4025,15 @@
             next();
         basic_type1:
-            if ((t & VT_BTYPE) != 0)
-                tcc_error("too many basic types");
-            t |= u;
+            if (u == VT_SHORT || u == VT_LONG) {
+                if (st != -1 || (bt != -1 && bt != VT_INT))
+                    tmbt: tcc_error("too many basic types");
+                st = u;
+            } else {
+                if (bt != -1 || (st != -1 && u != VT_INT))
+                    goto tmbt;
+                bt = u;
+            }
+            if (u != VT_INT)
+                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
             typespec_found = 1;
             break;
@@ -2928,20 +4045,24 @@
             goto basic_type;
         case TOK_INT:
-            next();
-            typespec_found = 1;
-            break;
+            u = VT_INT;
+            goto basic_type;
         case TOK_LONG:
-            next();
             if ((t & VT_BTYPE) == VT_DOUBLE) {
-#ifndef TCC_TARGET_PE
-                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
-#endif
-            } else if ((t & VT_BTYPE) == VT_LONG) {
-                t = (t & ~VT_BTYPE) | VT_LLONG;
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
+            } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
             } else {
                 u = VT_LONG;
-                goto basic_type1;
-            }
+                goto basic_type;
+            }
+            next();
             break;
+#ifdef TCC_TARGET_ARM64
+        case TOK_UINT128:
+            /* GCC's __uint128_t appears in some Linux header files. Make it a
+               synonym for long double to get the size and alignment right. */
+            u = VT_LDOUBLE;
+            goto basic_type;
+#endif
         case TOK_BOOL:
             u = VT_BOOL;
@@ -2951,15 +4072,11 @@
             goto basic_type;
         case TOK_DOUBLE:
-            next();
-            if ((t & VT_BTYPE) == VT_LONG) {
-#ifdef TCC_TARGET_PE
-                t = (t & ~VT_BTYPE) | VT_DOUBLE;
-#else
-                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
-#endif
+            if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
             } else {
                 u = VT_DOUBLE;
-                goto basic_type1;
-            }
+                goto basic_type;
+            }
+            next();
             break;
         case TOK_ENUM:
@@ -2970,6 +4087,8 @@
             goto basic_type1;
         case TOK_STRUCT:
+            struct_decl(&type1, VT_STRUCT);
+            goto basic_type2;
         case TOK_UNION:
-            struct_decl(&type1, VT_STRUCT);
+            struct_decl(&type1, VT_UNION);
             goto basic_type2;
 
@@ -2978,5 +4097,7 @@
         case TOK_CONST2:
         case TOK_CONST3:
-            t |= VT_CONSTANT;
+            type->t = t;
+            parse_btype_qualify(type, VT_CONSTANT);
+            t = type->t;
             next();
             break;
@@ -2984,5 +4105,7 @@
         case TOK_VOLATILE2:
         case TOK_VOLATILE3:
-            t |= VT_VOLATILE;
+            type->t = t;
+            parse_btype_qualify(type, VT_VOLATILE);
+            t = type->t;
             next();
             break;
@@ -2990,7 +4113,9 @@
         case TOK_SIGNED2:
         case TOK_SIGNED3:
+            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
+                tcc_error("signed and unsigned modifier");
+            t |= VT_DEFSIGN;
+            next();
             typespec_found = 1;
-            t |= VT_SIGNED;
-            next();
             break;
         case TOK_REGISTER:
@@ -3002,5 +4127,7 @@
             break;
         case TOK_UNSIGNED:
-            t |= VT_UNSIGNED;
+            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
+                tcc_error("signed and unsigned modifier");
+            t |= VT_DEFSIGN | VT_UNSIGNED;
             next();
             typespec_found = 1;
@@ -3009,13 +4136,16 @@
             /* storage */
         case TOK_EXTERN:
-            t |= VT_EXTERN;
-            next();
-            break;
+            g = VT_EXTERN;
+            goto storage;
         case TOK_STATIC:
-            t |= VT_STATIC;
-            next();
-            break;
+            g = VT_STATIC;
+            goto storage;
         case TOK_TYPEDEF:
-            t |= VT_TYPEDEF;
+            g = VT_TYPEDEF;
+            goto storage;
+       storage:
+            if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
+                tcc_error("multiple storage classes");
+            t |= g;
             next();
             break;
@@ -3031,7 +4161,7 @@
         case TOK_ATTRIBUTE2:
             parse_attribute(ad);
-            if (ad->mode) {
-                u = ad->mode -1;
-                t = (t & ~VT_BTYPE) | u;
+            if (ad->attr_mode) {
+                u = ad->attr_mode -1;
+                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
             }
             break;
@@ -3044,24 +4174,25 @@
             /* remove all storage modifiers except typedef */
             type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
+	    if (type1.ref)
+                sym_to_attr(ad, type1.ref);
             goto basic_type2;
         default:
-            if (typespec_found || typedef_found)
+            if (typespec_found)
                 goto the_end;
             s = sym_find(tok);
             if (!s || !(s->type.t & VT_TYPEDEF))
                 goto the_end;
-            typedef_found = 1;
-            t |= (s->type.t & ~VT_TYPEDEF);
+            t &= ~(VT_BTYPE|VT_LONG);
+            u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
+            type->t = (s->type.t & ~VT_TYPEDEF) | u;
             type->ref = s->type.ref;
-            if (s->r) {
-                /* get attributes from typedef */
-                if (0 == ad->aligned)
-                    ad->aligned = FUNC_ALIGN(s->r);
-                if (0 == ad->func_call)
-                    ad->func_call = FUNC_CALL(s->r);
-                ad->packed |= FUNC_PACKED(s->r);
-            }
+            if (t)
+                parse_btype_qualify(type, t);
+            t = type->t;
+            /* get attributes from typedef */
+            sym_to_attr(ad, s);
             next();
             typespec_found = 1;
+            st = bt = -2;
             break;
         }
@@ -3069,18 +4200,15 @@
     }
 the_end:
-    if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
-        tcc_error("signed and unsigned modifier");
     if (tcc_state->char_is_unsigned) {
-        if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
+        if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
             t |= VT_UNSIGNED;
     }
-    t &= ~VT_SIGNED;
-
-    /* long is never used as type */
-    if ((t & VT_BTYPE) == VT_LONG)
-#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
-        t = (t & ~VT_BTYPE) | VT_INT;
-#else
-        t = (t & ~VT_BTYPE) | VT_LLONG;
+    /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
+    bt = t & (VT_BTYPE|VT_LONG);
+    if (bt == VT_LONG)
+        t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
+#ifdef TCC_TARGET_PE
+    if (bt == VT_LDOUBLE)
+        t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
 #endif
     type->t = t;
@@ -3105,29 +4233,25 @@
 {
     skip('(');
-    /* read the string */
-    if (tok != TOK_STR)
-        expect("string constant");
-    cstr_new(astr);
-    while (tok == TOK_STR) {
-        /* XXX: add \0 handling too ? */
-        cstr_cat(astr, tokc.cstr->data);
-        next();
-    }
-    cstr_ccat(astr, '\0');
-}
-
-/* Parse an asm label and return the label
- * Don't forget to free the CString in the caller! */
-static void asm_label_instr(CString *astr)
-{
+    parse_mult_str(astr, "string constant");
+}
+
+/* Parse an asm label and return the token */
+static int asm_label_instr(void)
+{
+    int v;
+    CString astr;
+
     next();
-    parse_asm_str(astr);
+    parse_asm_str(&astr);
     skip(')');
 #ifdef ASM_DEBUG
-    printf("asm_alias: \"%s\"\n", (char *)astr->data);
-#endif
-}
-
-static void post_type(CType *type, AttributeDef *ad)
+    printf("asm_alias: \"%s\"\n", (char *)astr.data);
+#endif
+    v = tok_alloc(astr.data, astr.size - 1)->tok;
+    cstr_free(&astr);
+    return v;
+}
+
+static int post_type(CType *type, AttributeDef *ad, int storage, int td)
 {
     int n, l, t1, arg_size, align;
@@ -3137,23 +4261,23 @@
 
     if (tok == '(') {
-        /* function declaration */
+        /* function type, or recursive declarator (return if so) */
         next();
-        l = 0;
+	if (td && !(td & TYPE_ABSTRACT))
+	  return 0;
+	if (tok == ')')
+	  l = 0;
+	else if (parse_btype(&pt, &ad1))
+	  l = FUNC_NEW;
+	else if (td)
+	  return 0;
+	else
+	  l = FUNC_OLD;
         first = NULL;
         plast = &first;
         arg_size = 0;
-        if (tok != ')') {
+        if (l) {
             for(;;) {
                 /* read param name and compute offset */
                 if (l != FUNC_OLD) {
-                    if (!parse_btype(&pt, &ad1)) {
-                        if (l) {
-                            tcc_error("invalid type");
-                        } else {
-                            l = FUNC_OLD;
-                            goto old_proto;
-                        }
-                    }
-                    l = FUNC_NEW;
                     if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
                         break;
@@ -3163,9 +4287,8 @@
                     arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
                 } else {
-                old_proto:
                     n = tok;
                     if (n < TOK_UIDENT)
                         expect("identifier");
-                    pt.t = VT_INT;
+                    pt.t = VT_VOID; /* invalid type */
                     next();
                 }
@@ -3182,8 +4305,9 @@
                     break;
                 }
-            }
-        }
-        /* if no parameters, then old type prototype */
-        if (l == 0)
+		if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
+		    tcc_error("invalid type");
+            }
+        } else
+            /* if no parameters, then old type prototype */
             l = FUNC_OLD;
         skip(')');
@@ -3197,13 +4321,17 @@
             next();
             skip(']'); /* only handle simple "[]" */
-            type->t |= VT_PTR;
+            mk_pointer(type);
         }
         /* we push a anonymous symbol which will contain the function prototype */
-        ad->func_args = arg_size;
-        s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
+        ad->f.func_args = arg_size;
+        ad->f.func_type = l;
+        s = sym_push(SYM_FIELD, type, 0, 0);
+        s->a = ad->a;
+        s->f = ad->f;
         s->next = first;
         type->t = VT_FUNC;
         type->ref = s;
     } else if (tok == '[') {
+	int saved_nocode_wanted = nocode_wanted;
         /* array definition */
         next();
@@ -3213,7 +4341,14 @@
         t1 = 0;
         if (tok != ']') {
-            if (!local_stack || nocode_wanted)
-                 vpushi(expr_const());
-            else gexpr();
+            if (!local_stack || (storage & VT_STATIC))
+                vpushi(expr_const());
+            else {
+		/* VLAs (which can only happen with local_stack && !VT_STATIC)
+		   length must always be evaluated, even under nocode_wanted,
+		   so that its size slot is initialized (e.g. under sizeof
+		   or typeof).  */
+		nocode_wanted = 0;
+		gexpr();
+	    }
             if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
                 n = vtop->c.i;
@@ -3228,5 +4363,7 @@
         skip(']');
         /* parse next post type */
-        post_type(type, ad);
+        post_type(type, ad, storage, 0);
+        if (type->t == VT_FUNC)
+            tcc_error("declaration of an array of functions");
         t1 |= type->t & VT_VLA;
         
@@ -3238,5 +4375,5 @@
             vla_runtime_type_size(type, &align);
             gen_op('*');
-            vset(&int_type, VT_LOCAL|VT_LVAL, loc);
+            vset(&int_type, VT_LOCAL|VT_LVAL, n);
             vswap();
             vstore();
@@ -3244,4 +4381,5 @@
         if (n != -1)
             vpop();
+	nocode_wanted = saved_nocode_wanted;
                 
         /* we push an anonymous symbol which will contain the array
@@ -3251,17 +4389,23 @@
         type->ref = s;
     }
-}
-
-/* Parse a type declaration (except basic type), and return the type
+    return 1;
+}
+
+/* Parse a type declarator (except basic type), and return the type
    in 'type'. 'td' is a bitmask indicating which kind of type decl is
    expected. 'type' should contain the basic type. 'ad' is the
    attribute definition of the basic type. It can be modified by
-   type_decl(). 
- */
-static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
-{
-    Sym *s;
-    CType type1, *type2;
+   type_decl().  If this (possibly abstract) declarator is a pointer chain
+   it returns the innermost pointed to type (equals *type, but is a different
+   pointer), otherwise returns type itself, that's used for recursive calls.  */
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
+{
+    CType *post, *ret;
     int qualifiers, storage;
+
+    /* recursive type, remove storage bits first, apply them later again */
+    storage = type->t & VT_STORAGE;
+    type->t &= ~VT_STORAGE;
+    post = ret = type;
 
     while (tok == '*') {
@@ -3284,61 +4428,42 @@
         case TOK_RESTRICT3:
             goto redo;
+	/* XXX: clarify attribute handling */
+	case TOK_ATTRIBUTE1:
+	case TOK_ATTRIBUTE2:
+	    parse_attribute(ad);
+	    break;
         }
         mk_pointer(type);
         type->t |= qualifiers;
-    }
-    
-    /* XXX: clarify attribute handling */
-    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
-        parse_attribute(ad);
-
-    /* recursive type */
-    /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
-    type1.t = 0; /* XXX: same as int */
+	if (ret == type)
+	    /* innermost pointed to type is the one for the first derivation */
+	    ret = pointed_type(type);
+    }
+
     if (tok == '(') {
-        next();
-        /* XXX: this is not correct to modify 'ad' at this point, but
-           the syntax is not clear */
-        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
-            parse_attribute(ad);
-        type_decl(&type1, ad, v, td);
-        skip(')');
+	/* This is possibly a parameter type list for abstract declarators
+	   ('int ()'), use post_type for testing this.  */
+	if (!post_type(type, ad, 0, td)) {
+	    /* It's not, so it's a nested declarator, and the post operations
+	       apply to the innermost pointed to type (if any).  */
+	    /* XXX: this is not correct to modify 'ad' at this point, but
+	       the syntax is not clear */
+	    parse_attribute(ad);
+	    post = type_decl(type, ad, v, td);
+	    skip(')');
+	}
+    } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
+	/* type identifier */
+	*v = tok;
+	next();
     } else {
-        /* type identifier */
-        if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
-            *v = tok;
-            next();
-        } else {
-            if (!(td & TYPE_ABSTRACT))
-                expect("identifier");
-            *v = 0;
-        }
-    }
-    storage = type->t & VT_STORAGE;
-    type->t &= ~VT_STORAGE;
-    if (storage & VT_STATIC) {
-        int saved_nocode_wanted = nocode_wanted;
-        nocode_wanted = 1;
-        post_type(type, ad);
-        nocode_wanted = saved_nocode_wanted;
-    } else
-        post_type(type, ad);
+	if (!(td & TYPE_ABSTRACT))
+	  expect("identifier");
+	*v = 0;
+    }
+    post_type(post, ad, storage, 0);
+    parse_attribute(ad);
     type->t |= storage;
-    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
-        parse_attribute(ad);
-    
-    if (!type1.t)
-        return;
-    /* append type at the end of type1 */
-    type2 = &type1;
-    for(;;) {
-        s = type2->ref;
-        type2 = &s->type;
-        if (!type2->t) {
-            *type2 = *type;
-            break;
-        }
-    }
-    *type = type1;
+    return ret;
 }
 
@@ -3368,5 +4493,5 @@
         expect("pointer");
     }
-    if ((vtop->r & VT_LVAL) && !nocode_wanted)
+    if (vtop->r & VT_LVAL)
         gv(RC_INT);
     vtop->type = *pointed_type(&vtop->type);
@@ -3389,10 +4514,13 @@
     CType type;
 
-    func_type = func->c;
+    func_type = func->f.func_type;
     if (func_type == FUNC_OLD ||
         (func_type == FUNC_ELLIPSIS && arg == NULL)) {
         /* default casting : only need to convert float to double */
         if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
-            type.t = VT_DOUBLE;
+            gen_cast_s(VT_DOUBLE);
+        } else if (vtop->type.t & VT_BITFIELD) {
+            type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+	    type.ref = vtop->type.ref;
             gen_cast(&type);
         }
@@ -3406,4 +4534,14 @@
 }
 
+/* parse an expression and return its type without any side effect. */
+static void expr_type(CType *type, void (*expr_fn)(void))
+{
+    nocode_wanted++;
+    expr_fn();
+    *type = vtop->type;
+    vpop();
+    nocode_wanted--;
+}
+
 /* parse an expression of the form '(type)' or '(expr)' and return its
    type */
@@ -3417,5 +4555,5 @@
         type_decl(type, &ad, &n, TYPE_ABSTRACT);
     } else {
-        expr_type(type);
+        expr_type(type, gexpr);
     }
     skip(')');
@@ -3433,10 +4571,23 @@
 }
 
-static void vpush_tokc(int t)
-{
-    CType type;
-    type.t = t;
-    type.ref = 0;
-    vsetc(&type, VT_CONST, &tokc);
+static void parse_builtin_params(int nc, const char *args)
+{
+    char c, sep = '(';
+    CType t;
+    if (nc)
+        nocode_wanted++;
+    next();
+    while ((c = *args++)) {
+	skip(sep);
+	sep = ',';
+	switch (c) {
+	    case 'e': expr_eq(); continue;
+	    case 't': parse_type(&t); vpush(&t); continue;
+	    default: tcc_error("internal error"); break;
+	}
+    }
+    skip(')');
+    if (nc)
+        nocode_wanted--;
 }
 
@@ -3447,8 +4598,8 @@
     Sym *s;
     AttributeDef ad;
-    static int in_sizeof = 0;
 
     sizeof_caller = in_sizeof;
     in_sizeof = 0;
+    type.ref = NULL;
     /* XXX: GCC 2.95.3 does not generate a table although it should be
        better here */
@@ -3458,34 +4609,41 @@
         next();
         goto tok_next;
+    case TOK_LCHAR:
+#ifdef TCC_TARGET_PE
+        t = VT_SHORT|VT_UNSIGNED;
+        goto push_tokc;
+#endif
     case TOK_CINT:
     case TOK_CCHAR: 
-    case TOK_LCHAR:
-        vpushi(tokc.i);
+	t = VT_INT;
+ push_tokc:
+	type.t = t;
+	vsetc(&type, VT_CONST, &tokc);
         next();
         break;
     case TOK_CUINT:
-        vpush_tokc(VT_INT | VT_UNSIGNED);
-        next();
-        break;
+        t = VT_INT | VT_UNSIGNED;
+        goto push_tokc;
     case TOK_CLLONG:
-        vpush_tokc(VT_LLONG);
-        next();
-        break;
+        t = VT_LLONG;
+	goto push_tokc;
     case TOK_CULLONG:
-        vpush_tokc(VT_LLONG | VT_UNSIGNED);
-        next();
-        break;
+        t = VT_LLONG | VT_UNSIGNED;
+	goto push_tokc;
     case TOK_CFLOAT:
-        vpush_tokc(VT_FLOAT);
-        next();
-        break;
+        t = VT_FLOAT;
+	goto push_tokc;
     case TOK_CDOUBLE:
-        vpush_tokc(VT_DOUBLE);
-        next();
-        break;
+        t = VT_DOUBLE;
+	goto push_tokc;
     case TOK_CLDOUBLE:
-        vpush_tokc(VT_LDOUBLE);
-        next();
-        break;
+        t = VT_LDOUBLE;
+	goto push_tokc;
+    case TOK_CLONG:
+        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
+	goto push_tokc;
+    case TOK_CULONG:
+        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
+	goto push_tokc;
     case TOK___FUNCTION__:
         if (!gnu_ext)
@@ -3504,6 +4662,8 @@
             type.ref->c = len;
             vpush_ref(&type, data_section, data_section->data_offset, len);
-            ptr = section_ptr_add(data_section, len);
-            memcpy(ptr, funcname, len);
+            if (!NODATA_WANTED) {
+                ptr = section_ptr_add(data_section, len);
+                memcpy(ptr, funcname, len);
+            }
             next();
         }
@@ -3519,4 +4679,6 @@
         /* string parsing */
         t = VT_BYTE;
+        if (tcc_state->char_is_unsigned)
+            t = VT_BYTE | VT_UNSIGNED;
     str_init:
         if (tcc_state->warn_write_strings)
@@ -3526,5 +4688,5 @@
         type.t |= VT_ARRAY;
         memset(&ad, 0, sizeof(AttributeDef));
-        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, NULL, 0);
+        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
         break;
     case '(':
@@ -3545,5 +4707,5 @@
                     r |= lvalue_type(type.t);
                 memset(&ad, 0, sizeof(AttributeDef));
-                decl_initializer_alloc(&type, &ad, r, 1, 0, NULL, 0);
+                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
             } else {
                 if (sizeof_caller) {
@@ -3555,9 +4717,16 @@
             }
         } else if (tok == '{') {
+	    int saved_nocode_wanted = nocode_wanted;
+            if (const_wanted)
+                tcc_error("expected constant");
             /* save all registers */
-            save_regs(0); 
+            save_regs(0);
             /* statement expression : we do not accept break/continue
-               inside as GCC does */
-            block(NULL, NULL, NULL, NULL, 0, 1);
+               inside as GCC does.  We do retain the nocode_wanted state,
+	       as statement expressions can't ever be entered from the
+	       outside, so any reactivation of code emission (from labels
+	       or loop heads) can be disabled again after the end of it. */
+            block(NULL, NULL, 1);
+	    nocode_wanted = saved_nocode_wanted;
             skip(')');
         } else {
@@ -3580,5 +4749,5 @@
         /* arrays can also be used although they are not lvalues */
         if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
-            !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
+            !(vtop->type.t & VT_ARRAY))
             test_lvalue();
         mk_pointer(&vtop->type);
@@ -3589,13 +4758,11 @@
         unary();
         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-            CType boolean;
-            boolean.t = VT_BOOL;
-            gen_cast(&boolean);
+            gen_cast_s(VT_BOOL);
             vtop->c.i = !vtop->c.i;
         } else if ((vtop->r & VT_VALMASK) == VT_CMP)
-            vtop->c.i = vtop->c.i ^ 1;
+            vtop->c.i ^= 1;
         else {
             save_regs(1);
-            vseti(VT_JMP, gtst(1, 0));
+            vseti(VT_JMP, gvtst(1, 0));
         }
         break;
@@ -3608,10 +4775,14 @@
     case '+':
         next();
-        /* in order to force cast, we add zero */
         unary();
         if ((vtop->type.t & VT_BTYPE) == VT_PTR)
             tcc_error("pointer not accepted for unary plus");
-        vpushi(0);
-        gen_op('+');
+        /* In order to force cast, we add zero, except for floating point
+	   where we really need an noop (otherwise -0.0 will be transformed
+	   into +0.0).  */
+	if (!is_float(vtop->type.t)) {
+	    vpushi(0);
+	    gen_op('+');
+	}
         break;
     case TOK_SIZEOF:
@@ -3621,6 +4792,9 @@
         next();
         in_sizeof++;
-        unary_type(&type); // Perform a in_sizeof = 0;
+        expr_type(&type, unary); /* Perform a in_sizeof = 0; */
+        s = vtop[1].sym; /* hack: accessing previous vtop */
         size = type_size(&type, &align);
+        if (s && s->a.aligned)
+            align = 1 << (s->a.aligned - 1);
         if (t == TOK_SIZEOF) {
             if (!(type.t & VT_VLA)) {
@@ -3637,43 +4811,64 @@
         break;
 
+    case TOK_builtin_expect:
+	/* __builtin_expect is a no-op for now */
+	parse_builtin_params(0, "ee");
+	vpop();
+        break;
     case TOK_builtin_types_compatible_p:
+	parse_builtin_params(0, "tt");
+	vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+	vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+	n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
+	vtop -= 2;
+	vpushi(n);
+        break;
+    case TOK_builtin_choose_expr:
+	{
+	    int64_t c;
+	    next();
+	    skip('(');
+	    c = expr_const64();
+	    skip(',');
+	    if (!c) {
+		nocode_wanted++;
+	    }
+	    expr_eq();
+	    if (!c) {
+		vpop();
+		nocode_wanted--;
+	    }
+	    skip(',');
+	    if (c) {
+		nocode_wanted++;
+	    }
+	    expr_eq();
+	    if (c) {
+		vpop();
+		nocode_wanted--;
+	    }
+	    skip(')');
+	}
+        break;
+    case TOK_builtin_constant_p:
+	parse_builtin_params(1, "e");
+	n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+	vtop--;
+	vpushi(n);
+        break;
+    case TOK_builtin_frame_address:
+    case TOK_builtin_return_address:
         {
-            CType type1, type2;
+            int tok1 = tok;
+            int level;
             next();
             skip('(');
-            parse_type(&type1);
-            skip(',');
-            parse_type(&type2);
-            skip(')');
-            type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
-            type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
-            vpushi(is_compatible_types(&type1, &type2));
-        }
-        break;
-    case TOK_builtin_constant_p:
-        {
-            int saved_nocode_wanted, res;
-            next();
-            skip('(');
-            saved_nocode_wanted = nocode_wanted;
-            nocode_wanted = 1;
-            gexpr();
-            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
-            vpop();
-            nocode_wanted = saved_nocode_wanted;
-            skip(')');
-            vpushi(res);
-        }
-        break;
-    case TOK_builtin_frame_address:
-        {
-            int level;
-            CType type;
-            next();
-            skip('(');
-            if (tok != TOK_CINT || tokc.i < 0) {
-                tcc_error("__builtin_frame_address only takes positive integers");
-            }
-            level = tokc.i;
+            if (tok != TOK_CINT) {
+                tcc_error("%s only takes positive integers",
+                          tok1 == TOK_builtin_return_address ?
+                          "__builtin_return_address" :
+                          "__builtin_frame_address");
+            }
+            level = (uint32_t)tokc.i;
             next();
             skip(')');
@@ -3685,30 +4880,64 @@
                 indir();                    /* -> parent frame */
             }
+            if (tok1 == TOK_builtin_return_address) {
+                // assume return address is just above frame pointer on stack
+                vpushi(PTR_SIZE);
+                gen_op('+');
+                mk_pointer(&vtop->type);
+                indir();
+            }
         }
         break;
 #ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+    case TOK_builtin_va_start:
+	parse_builtin_params(0, "ee");
+        r = vtop->r & VT_VALMASK;
+        if (r == VT_LLOCAL)
+            r = VT_LOCAL;
+        if (r != VT_LOCAL)
+            tcc_error("__builtin_va_start expects a local variable");
+        vtop->r = r;
+	vtop->type = char_pointer_type;
+	vtop->c.i += 8;
+	vstore();
+        break;
+#else
     case TOK_builtin_va_arg_types:
-        {
-            /* This definition must be synced with stdarg.h */
-            enum __va_arg_type {
-                __va_gen_reg, __va_float_reg, __va_stack
-            };
-            CType type;
-            int bt;
-            next();
-            skip('(');
-            parse_type(&type);
-            skip(')');
-            bt = type.t & VT_BTYPE;
-            if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
-                vpushi(__va_stack);
-            } else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
-                vpushi(__va_float_reg);
-            } else {
-                vpushi(__va_gen_reg);
-            }
-        }
+	parse_builtin_params(0, "t");
+	vpushi(classify_x86_64_va_arg(&vtop->type));
+	vswap();
+	vpop();
         break;
 #endif
+#endif
+
+#ifdef TCC_TARGET_ARM64
+    case TOK___va_start: {
+	parse_builtin_params(0, "ee");
+        //xx check types
+        gen_va_start();
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+        break;
+    }
+    case TOK___va_arg: {
+	parse_builtin_params(0, "et");
+	type = vtop->type;
+	vpop();
+        //xx check types
+        gen_va_arg(&type);
+        vtop->type = type;
+        break;
+    }
+    case TOK___arm64_clear_cache: {
+	parse_builtin_params(0, "ee");
+        gen_clear_cache();
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+        break;
+    }
+#endif
+    /* pre operations */
     case TOK_INC:
     case TOK_DEC:
@@ -3720,7 +4949,20 @@
     case '-':
         next();
-        vpushi(0);
         unary();
-        gen_op('-');
+        t = vtop->type.t & VT_BTYPE;
+	if (is_float(t)) {
+            /* In IEEE negate(x) isn't subtract(0,x), but rather
+	       subtract(-0, x).  */
+	    vpush(&vtop->type);
+	    if (t == VT_FLOAT)
+	        vtop->c.f = -1.0 * 0.0;
+	    else if (t == VT_DOUBLE)
+	        vtop->c.d = -1.0 * 0.0;
+	    else
+	        vtop->c.ld = -1.0 * 0.0;
+	} else
+	    vpushi(0);
+	vswap();
+	gen_op('-');
         break;
     case TOK_LAND:
@@ -3743,9 +4985,69 @@
             s->type.t |= VT_STATIC;
         }
-        vset(&s->type, VT_CONST | VT_SYM, 0);
-        vtop->sym = s;
+        vpushsym(&s->type, s);
         next();
         break;
-    
+
+    case TOK_GENERIC:
+    {
+	CType controlling_type;
+	int has_default = 0;
+	int has_match = 0;
+	int learn = 0;
+	TokenString *str = NULL;
+
+	next();
+	skip('(');
+	expr_type(&controlling_type, expr_eq);
+	controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
+	for (;;) {
+	    learn = 0;
+	    skip(',');
+	    if (tok == TOK_DEFAULT) {
+		if (has_default)
+		    tcc_error("too many 'default'");
+		has_default = 1;
+		if (!has_match)
+		    learn = 1;
+		next();
+	    } else {
+	        AttributeDef ad_tmp;
+		int itmp;
+	        CType cur_type;
+		parse_btype(&cur_type, &ad_tmp);
+		type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
+		if (compare_types(&controlling_type, &cur_type, 0)) {
+		    if (has_match) {
+		      tcc_error("type match twice");
+		    }
+		    has_match = 1;
+		    learn = 1;
+		}
+	    }
+	    skip(':');
+	    if (learn) {
+		if (str)
+		    tok_str_free(str);
+		skip_or_save_block(&str);
+	    } else {
+		skip_or_save_block(NULL);
+	    }
+	    if (tok == ')')
+		break;
+	}
+	if (!str) {
+	    char buf[60];
+	    type_to_str(buf, sizeof buf, &controlling_type, NULL);
+	    tcc_error("type '%s' does not match any association", buf);
+	}
+	begin_macro(str, 1);
+	next();
+	expr_eq();
+	if (tok != TOK_EOF)
+	    expect(",");
+	end_macro();
+        next();
+	break;
+    }
     // special qnan , snan and infinity values
     case TOK___NAN__:
@@ -3769,32 +5071,37 @@
             expect("identifier");
         s = sym_find(t);
-        if (!s) {
+        if (!s || IS_ASM_SYM(s)) {
+            const char *name = get_tok_str(t, NULL);
             if (tok != '(')
-                tcc_error("'%s' undeclared", get_tok_str(t, NULL));
+                tcc_error("'%s' undeclared", name);
             /* for simple function calls, we tolerate undeclared
                external reference to int() function */
-            if (tcc_state->warn_implicit_function_declaration)
-                tcc_warning("implicit declaration of function '%s'",
-                        get_tok_str(t, NULL));
+            if (tcc_state->warn_implicit_function_declaration
+#ifdef TCC_TARGET_PE
+                /* people must be warned about using undeclared WINAPI functions
+                   (which usually start with uppercase letter) */
+                || (name[0] >= 'A' && name[0] <= 'Z')
+#endif
+            )
+                tcc_warning("implicit declaration of function '%s'", name);
             s = external_global_sym(t, &func_old_type, 0); 
         }
-        if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
-            (VT_STATIC | VT_INLINE | VT_FUNC)) {
-            /* if referencing an inline function, then we generate a
-               symbol to it if not already done. It will have the
-               effect to generate code for it at the end of the
-               compilation unit. Inline function as always
-               generated in the text section. */
-            if (!s->c)
-                put_extern_sym(s, text_section, 0, 0);
-            r = VT_SYM | VT_CONST;
-        } else {
-            r = s->r;
-        }
+
+        r = s->r;
+        /* A symbol that has a register is a local register variable,
+           which starts out as VT_LOCAL value.  */
+        if ((r & VT_VALMASK) < VT_CONST)
+            r = (r & ~VT_VALMASK) | VT_LOCAL;
+
         vset(&s->type, r, s->c);
-        /* if forward reference, we must point to s */
-        if (vtop->r & VT_SYM) {
-            vtop->sym = s;
-            vtop->c.ul = 0;
+        /* Point to s as backpointer (even without r&VT_SYM).
+	   Will be used by at least the x86 inline asm parser for
+	   regvars.  */
+	vtop->sym = s;
+
+        if (r & VT_SYM) {
+            vtop->c.i = 0;
+        } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
+            vtop->c.i = s->enum_val;
         }
         break;
@@ -3806,5 +5113,5 @@
             inc(1, tok);
             next();
-        } else if (tok == '.' || tok == TOK_ARROW) {
+        } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
             int qualifiers;
             /* field */ 
@@ -3814,17 +5121,15 @@
             test_lvalue();
             gaddrof();
-            next();
             /* expect pointer on structure */
             if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
                 expect("struct or union");
-            s = vtop->type.ref;
-            /* find field */
-            tok |= SYM_FIELD;
-            while ((s = s->next) != NULL) {
-                if (s->v == tok)
-                    break;
-            }
+            if (tok == TOK_CDOUBLE)
+                expect("field name");
+            next();
+            if (tok == TOK_CINT || tok == TOK_CUINT)
+                expect("field name");
+	    s = find_field(&vtop->type, tok);
             if (!s)
-                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, NULL));
+                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, &tokc));
             /* add field offset to pointer */
             vtop->type = char_pointer_type; /* change type to 'char *' */
@@ -3839,5 +5144,5 @@
 #ifdef CONFIG_TCC_BCHECK
                 /* if bound checking, the referenced pointer must be checked */
-                if (tcc_state->do_bounds_check)
+                if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
                     vtop->r |= VT_MUSTBOUND;
 #endif
@@ -3853,5 +5158,5 @@
             SValue ret;
             Sym *sa;
-            int nb_args;
+            int nb_args, ret_nregs, ret_align, regsize, variadic;
 
             /* function call  */
@@ -3873,26 +5178,54 @@
             next();
             sa = s->next; /* first parameter */
-            nb_args = 0;
+            nb_args = regsize = 0;
             ret.r2 = VT_CONST;
             /* compute first implicit argument if a structure is returned */
             if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
-                /* get some space for the returned structure */
-                size = type_size(&s->type, &align);
-                loc = (loc - size) & -align;
+                variadic = (s->f.func_type == FUNC_ELLIPSIS);
+                ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
+                                       &ret_align, &regsize);
+                if (!ret_nregs) {
+                    /* get some space for the returned structure */
+                    size = type_size(&s->type, &align);
+#ifdef TCC_TARGET_ARM64
+                /* On arm64, a small struct is return in registers.
+                   It is much easier to write it to memory if we know
+                   that we are allowed to write some extra bytes, so
+                   round the allocated space up to a power of 2: */
+                if (size < 16)
+                    while (size & (size - 1))
+                        size = (size | (size - 1)) + 1;
+#endif
+                    loc = (loc - size) & -align;
+                    ret.type = s->type;
+                    ret.r = VT_LOCAL | VT_LVAL;
+                    /* pass it as 'int' to avoid structure arg passing
+                       problems */
+                    vseti(VT_LOCAL, loc);
+                    ret.c = vtop->c;
+                    nb_args++;
+                }
+            } else {
+                ret_nregs = 1;
                 ret.type = s->type;
-                ret.r = VT_LOCAL | VT_LVAL;
-                /* pass it as 'int' to avoid structure arg passing
-                   problems */
-                vseti(VT_LOCAL, loc);
-                ret.c = vtop->c;
-                nb_args++;
-            } else {
-                ret.type = s->type; 
+            }
+
+            if (ret_nregs) {
                 /* return in register */
                 if (is_float(ret.type.t)) {
                     ret.r = reg_fret(ret.type.t);
+#ifdef TCC_TARGET_X86_64
+                    if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
+                      ret.r2 = REG_QRET;
+#endif
                 } else {
+#ifndef TCC_TARGET_ARM64
+#ifdef TCC_TARGET_X86_64
+                    if ((ret.type.t & VT_BTYPE) == VT_QLONG)
+#else
                     if ((ret.type.t & VT_BTYPE) == VT_LLONG)
+#endif
                         ret.r2 = REG_LRET;
+#endif
                     ret.r = REG_IRET;
                 }
@@ -3914,12 +5247,35 @@
                 tcc_error("too few arguments to function");
             skip(')');
-            if (!nocode_wanted) {
-                gfunc_call(nb_args);
-            } else {
-                vtop -= (nb_args + 1);
-            }
+            gfunc_call(nb_args);
+
             /* return value */
-            vsetc(&ret.type, ret.r, &ret.c);
-            vtop->r2 = ret.r2;
+            for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
+                vsetc(&ret.type, r, &ret.c);
+                vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
+            }
+
+            /* handle packed struct return */
+            if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
+                int addr, offset;
+
+                size = type_size(&s->type, &align);
+		/* We're writing whole regs often, make sure there's enough
+		   space.  Assume register size is power of 2.  */
+		if (regsize > align)
+		  align = regsize;
+                loc = (loc - size) & -align;
+                addr = loc;
+                offset = 0;
+                for (;;) {
+                    vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
+                    vswap();
+                    vstore();
+                    vtop--;
+                    if (--ret_nregs == 0)
+                        break;
+                    offset += regsize;
+                }
+                vset(&s->type, VT_LOCAL | VT_LVAL, addr);
+            }
         } else {
             break;
@@ -4024,44 +5380,42 @@
 }
 
-/* XXX: fix this mess */
-static void expr_land_const(void)
-{
-    expr_or();
-    while (tok == TOK_LAND) {
-        next();
-        expr_or();
-        gen_op(TOK_LAND);
-    }
-}
-
-/* XXX: fix this mess */
-static void expr_lor_const(void)
-{
-    expr_land_const();
-    while (tok == TOK_LOR) {
-        next();
-        expr_land_const();
-        gen_op(TOK_LOR);
-    }
-}
-
-/* only used if non constant */
 static void expr_land(void)
 {
-    int t;
-
     expr_or();
     if (tok == TOK_LAND) {
-        t = 0;
-        save_regs(1);
-        for(;;) {
-            t = gtst(1, t);
-            if (tok != TOK_LAND) {
-                vseti(VT_JMPI, t);
-                break;
-            }
-            next();
-            expr_or();
-        }
+	int t = 0;
+	for(;;) {
+	    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+                gen_cast_s(VT_BOOL);
+		if (vtop->c.i) {
+		    vpop();
+		} else {
+		    nocode_wanted++;
+		    while (tok == TOK_LAND) {
+			next();
+			expr_or();
+			vpop();
+		    }
+		    nocode_wanted--;
+		    if (t)
+		      gsym(t);
+		    gen_cast_s(VT_INT);
+		    break;
+		}
+	    } else {
+		if (!t)
+		  save_regs(1);
+		t = gvtst(1, t);
+	    }
+	    if (tok != TOK_LAND) {
+		if (t)
+		  vseti(VT_JMPI, t);
+		else
+		  vpushi(1);
+		break;
+	    }
+	    next();
+	    expr_or();
+	}
     }
 }
@@ -4069,95 +5423,130 @@
 static void expr_lor(void)
 {
-    int t;
-
     expr_land();
     if (tok == TOK_LOR) {
-        t = 0;
-        save_regs(1);
-        for(;;) {
-            t = gtst(0, t);
-            if (tok != TOK_LOR) {
-                vseti(VT_JMP, t);
-                break;
-            }
-            next();
-            expr_land();
-        }
-    }
-}
-
-/* XXX: better constant handling */
+	int t = 0;
+	for(;;) {
+	    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+                gen_cast_s(VT_BOOL);
+		if (!vtop->c.i) {
+		    vpop();
+		} else {
+		    nocode_wanted++;
+		    while (tok == TOK_LOR) {
+			next();
+			expr_land();
+			vpop();
+		    }
+		    nocode_wanted--;
+		    if (t)
+		      gsym(t);
+		    gen_cast_s(VT_INT);
+		    break;
+		}
+	    } else {
+		if (!t)
+		  save_regs(1);
+		t = gvtst(0, t);
+	    }
+	    if (tok != TOK_LOR) {
+		if (t)
+		  vseti(VT_JMP, t);
+		else
+		  vpushi(0);
+		break;
+	    }
+	    next();
+	    expr_land();
+	}
+    }
+}
+
+/* Assuming vtop is a value used in a conditional context
+   (i.e. compared with zero) return 0 if it's false, 1 if
+   true and -1 if it can't be statically determined.  */
+static int condition_3way(void)
+{
+    int c = -1;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+	(!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
+	vdup();
+        gen_cast_s(VT_BOOL);
+	c = vtop->c.i;
+	vpop();
+    }
+    return c;
+}
+
 static void expr_cond(void)
 {
-    int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
+    int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
     SValue sv;
     CType type, type1, type2;
 
-    if (const_wanted) {
-        expr_lor_const();
-        if (tok == '?') {
-            CType boolean;
-            int c;
-            boolean.t = VT_BOOL;
-            vdup();
-            gen_cast(&boolean);
-            c = vtop->c.i;
-            vpop();
-            next();
-            if (tok != ':' || !gnu_ext) {
+    expr_lor();
+    if (tok == '?') {
+        next();
+	c = condition_3way();
+        g = (tok == ':' && gnu_ext);
+        if (c < 0) {
+            /* needed to avoid having different registers saved in
+               each branch */
+            if (is_float(vtop->type.t)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                }
+#endif
+            } else
+                rc = RC_INT;
+            gv(rc);
+            save_regs(1);
+            if (g)
+                gv_dup();
+            tt = gvtst(1, 0);
+
+        } else {
+            if (!g)
                 vpop();
+            tt = 0;
+        }
+
+        if (1) {
+            if (c == 0)
+                nocode_wanted++;
+            if (!g)
                 gexpr();
-            }
-            if (!c)
-                vpop();
-            skip(':');
-            expr_cond();
-            if (c)
-                vpop();
-        }
-    } else {
-        expr_lor();
-        if (tok == '?') {
-            next();
-            if (vtop != vstack) {
-                /* needed to avoid having different registers saved in
-                   each branch */
-                if (is_float(vtop->type.t)) {
-                    rc = RC_FLOAT;
-#ifdef TCC_TARGET_X86_64
-                    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
-                        rc = RC_ST0;
-                    }
-#endif
-                }
-                else
-                    rc = RC_INT;
-                    gv(rc);
-                    save_regs(1);
-            }
-            if (tok == ':' && gnu_ext) {
-                gv_dup();
-                tt = gtst(1, 0);
-            } else {
-                tt = gtst(1, 0);
-                gexpr();
-            }
+
             type1 = vtop->type;
             sv = *vtop; /* save value to handle it later */
             vtop--; /* no vpop so that FP stack is not flushed */
             skip(':');
-            u = gjmp(0);
+
+            u = 0;
+            if (c < 0)
+                u = gjmp(0);
             gsym(tt);
+
+            if (c == 0)
+                nocode_wanted--;
+            if (c == 1)
+                nocode_wanted++;
             expr_cond();
+            if (c == 1)
+                nocode_wanted--;
+
             type2 = vtop->type;
-
             t1 = type1.t;
             bt1 = t1 & VT_BTYPE;
             t2 = type2.t;
             bt2 = t2 & VT_BTYPE;
+            type.ref = NULL;
+
             /* cast operands to correct type according to ISOC rules */
             if (is_float(bt1) || is_float(bt2)) {
                 if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
                     type.t = VT_LDOUBLE;
+
                 } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
                     type.t = VT_DOUBLE;
@@ -4167,8 +5556,12 @@
             } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
                 /* cast to biggest op */
-                type.t = VT_LLONG;
+                type.t = VT_LLONG | VT_LONG;
+                if (bt1 == VT_LLONG)
+                    type.t &= t1;
+                if (bt2 == VT_LLONG)
+                    type.t &= t2;
                 /* convert to unsigned if it does not fit in a long long */
-                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
-                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
                     type.t |= VT_UNSIGNED;
             } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
@@ -4194,15 +5587,25 @@
             } else {
                 /* integer operations */
-                type.t = VT_INT;
+                type.t = VT_INT | (VT_LONG & (t1 | t2));
                 /* convert to unsigned if it does not fit in an integer */
-                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
-                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
                     type.t |= VT_UNSIGNED;
             }
-                
+            /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
+               that `(expr ? a : b).mem` does not error  with "lvalue expected" */
+            islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
+            islv &= c < 0;
+
             /* now we convert second operand */
-            gen_cast(&type);
-            if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
-                gaddrof();
+            if (c != 1) {
+                gen_cast(&type);
+                if (islv) {
+                    mk_pointer(&vtop->type);
+                    gaddrof();
+                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                    gaddrof();
+            }
+
             rc = RC_INT;
             if (is_float(type.t)) {
@@ -4216,21 +5619,34 @@
                 /* for long longs, we use fixed registers to avoid having
                    to handle a complicated move */
-                rc = RC_IRET; 
-            }
-            
-            r2 = gv(rc);
+                rc = RC_IRET;
+            }
+
+            tt = r2 = 0;
+            if (c < 0) {
+                r2 = gv(rc);
+                tt = gjmp(0);
+            }
+            gsym(u);
+
             /* this is horrible, but we must also convert first
                operand */
-            tt = gjmp(0);
-            gsym(u);
-            /* put again first value and cast it */
-            *vtop = sv;
-            gen_cast(&type);
-            if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
-                gaddrof();
-            r1 = gv(rc);
-            move_reg(r2, r1);
-            vtop->r = r2;
-            gsym(tt);
+            if (c != 0) {
+                *vtop = sv;
+                gen_cast(&type);
+                if (islv) {
+                    mk_pointer(&vtop->type);
+                    gaddrof();
+                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                    gaddrof();
+            }
+
+            if (c < 0) {
+                r1 = gv(rc);
+                move_reg(r2, r1, type.t);
+                vtop->r = r2;
+                gsym(tt);
+                if (islv)
+                    indir();
+            }
         }
     }
@@ -4271,45 +5687,18 @@
 }
 
-/* parse an expression and return its type without any side effect. */
-static void expr_type(CType *type)
-{
-    int saved_nocode_wanted;
-
-    saved_nocode_wanted = nocode_wanted;
-    nocode_wanted = 1;
-    gexpr();
-    *type = vtop->type;
-    vpop();
-    nocode_wanted = saved_nocode_wanted;
-}
-
-/* parse a unary expression and return its type without any side
-   effect. */
-static void unary_type(CType *type)
-{
-    int a;
-
-    a = nocode_wanted;
-    nocode_wanted = 1;
-    unary();
-    *type = vtop->type;
-    vpop();
-    nocode_wanted = a;
-}
-
 /* parse a constant expression and return value in vtop.  */
 static void expr_const1(void)
 {
-    int a;
-    a = const_wanted;
-    const_wanted = 1;
+    const_wanted++;
+    nocode_wanted++;
     expr_cond();
-    const_wanted = a;
+    nocode_wanted--;
+    const_wanted--;
 }
 
 /* parse an integer constant and return its value. */
-ST_FUNC int expr_const(void)
-{
-    int c;
+static inline int64_t expr_const64(void)
+{
+    int64_t c;
     expr_const1();
     if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
@@ -4317,4 +5706,16 @@
     c = vtop->c.i;
     vpop();
+    return c;
+}
+
+/* parse an integer constant and return its value.
+   Complain if it doesn't fit 32bit (signed or unsigned).  */
+ST_FUNC int expr_const(void)
+{
+    int c;
+    int64_t wc = expr_const64();
+    c = wc;
+    if (c != wc && (unsigned)c != wc)
+        tcc_error("constant exceeds 32 bit");
     return c;
 }
@@ -4333,5 +5734,4 @@
     next();
     if (tok == ':') {
-        next();
         return last_tok;
     } else {
@@ -4341,36 +5741,145 @@
 }
 
-static void label_or_decl(int l)
-{
-    int last_tok;
-
-    /* fast test first */
-    if (tok >= TOK_UIDENT)
-      {
-	/* no need to save tokc because tok is an identifier */
-	last_tok = tok;
-	next();
-	if (tok == ':') {
-	    unget_tok(last_tok);
-	    return;
-	}
-	unget_tok(last_tok);
-      }
-    decl(l);
-}
-
-static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
-                  int case_reg, int is_expr)
-{
-    int a, b, c, d;
-    Sym *s, *frame_bottom;
+#ifndef TCC_TARGET_ARM64
+static void gfunc_return(CType *func_type)
+{
+    if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+        CType type, ret_type;
+        int ret_align, ret_nregs, regsize;
+        ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
+                               &ret_align, &regsize);
+        if (0 == ret_nregs) {
+            /* if returning structure, must copy it to implicit
+               first pointer arg location */
+            type = *func_type;
+            mk_pointer(&type);
+            vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+            indir();
+            vswap();
+            /* copy structure value to pointer */
+            vstore();
+        } else {
+            /* returning structure packed into registers */
+            int r, size, addr, align;
+            size = type_size(func_type,&align);
+            if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
+                 (vtop->c.i & (ret_align-1)))
+                && (align & (ret_align-1))) {
+                loc = (loc - size) & -ret_align;
+                addr = loc;
+                type = *func_type;
+                vset(&type, VT_LOCAL | VT_LVAL, addr);
+                vswap();
+                vstore();
+                vpop();
+                vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
+            }
+            vtop->type = ret_type;
+            if (is_float(ret_type.t))
+                r = rc_fret(ret_type.t);
+            else
+                r = RC_IRET;
+
+            if (ret_nregs == 1)
+                gv(r);
+            else {
+                for (;;) {
+                    vdup();
+                    gv(r);
+                    vpop();
+                    if (--ret_nregs == 0)
+                      break;
+                    /* We assume that when a structure is returned in multiple
+                       registers, their classes are consecutive values of the
+                       suite s(n) = 2^n */
+                    r <<= 1;
+                    vtop->c.i += regsize;
+                }
+            }
+        }
+    } else if (is_float(func_type->t)) {
+        gv(rc_fret(func_type->t));
+    } else {
+        gv(RC_IRET);
+    }
+    vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+}
+#endif
+
+static int case_cmp(const void *pa, const void *pb)
+{
+    int64_t a = (*(struct case_t**) pa)->v1;
+    int64_t b = (*(struct case_t**) pb)->v1;
+    return a < b ? -1 : a > b;
+}
+
+static void gcase(struct case_t **base, int len, int *bsym)
+{
+    struct case_t *p;
+    int e;
+    int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
+    gv(RC_INT);
+    while (len > 4) {
+        /* binary search */
+        p = base[len/2];
+        vdup();
+	if (ll)
+	    vpushll(p->v2);
+	else
+	    vpushi(p->v2);
+        gen_op(TOK_LE);
+        e = gtst(1, 0);
+        vdup();
+	if (ll)
+	    vpushll(p->v1);
+	else
+	    vpushi(p->v1);
+        gen_op(TOK_GE);
+        gtst_addr(0, p->sym); /* v1 <= x <= v2 */
+        /* x < v1 */
+        gcase(base, len/2, bsym);
+        if (cur_switch->def_sym)
+            gjmp_addr(cur_switch->def_sym);
+        else
+            *bsym = gjmp(*bsym);
+        /* x > v2 */
+        gsym(e);
+        e = len/2 + 1;
+        base += e; len -= e;
+    }
+    /* linear scan */
+    while (len--) {
+        p = *base++;
+        vdup();
+	if (ll)
+	    vpushll(p->v2);
+	else
+	    vpushi(p->v2);
+        if (p->v1 == p->v2) {
+            gen_op(TOK_EQ);
+            gtst_addr(0, p->sym);
+        } else {
+            gen_op(TOK_LE);
+            e = gtst(1, 0);
+            vdup();
+	    if (ll)
+	        vpushll(p->v1);
+	    else
+	        vpushi(p->v1);
+            gen_op(TOK_GE);
+            gtst_addr(0, p->sym);
+            gsym(e);
+        }
+    }
+}
+
+static void block(int *bsym, int *csym, int is_expr)
+{
+    int a, b, c, d, cond;
+    Sym *s;
 
     /* generate line number info */
-    if (tcc_state->do_debug &&
-        (last_line_num != file->line_num || last_ind != ind)) {
-        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
-        last_ind = ind;
-        last_line_num = file->line_num;
-    }
+    if (tcc_state->do_debug)
+        tcc_debug_line(tcc_state);
 
     if (is_expr) {
@@ -4382,10 +5891,19 @@
     if (tok == TOK_IF) {
         /* if test */
+	int saved_nocode_wanted = nocode_wanted;
         next();
         skip('(');
         gexpr();
         skip(')');
-        a = gtst(1, 0);
-        block(bsym, csym, case_sym, def_sym, case_reg, 0);
+	cond = condition_3way();
+        if (cond == 1)
+            a = 0, vpop();
+        else
+            a = gvtst(1, 0);
+        if (cond == 0)
+	    nocode_wanted |= 0x20000000;
+        block(bsym, csym, 0);
+	if (cond != 1)
+	    nocode_wanted = saved_nocode_wanted;
         c = tok;
         if (c == TOK_ELSE) {
@@ -4393,17 +5911,28 @@
             d = gjmp(0);
             gsym(a);
-            block(bsym, csym, case_sym, def_sym, case_reg, 0);
+	    if (cond == 1)
+	        nocode_wanted |= 0x20000000;
+            block(bsym, csym, 0);
             gsym(d); /* patch else jmp */
+	    if (cond != 0)
+		nocode_wanted = saved_nocode_wanted;
         } else
             gsym(a);
     } else if (tok == TOK_WHILE) {
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
         next();
         d = ind;
+        vla_sp_restore();
         skip('(');
         gexpr();
         skip(')');
-        a = gtst(1, 0);
+        a = gvtst(1, 0);
         b = 0;
-        block(&a, &b, case_sym, def_sym, case_reg, 0);
+        ++local_scope;
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
+	nocode_wanted = saved_nocode_wanted;
+        --local_scope;
         gjmp_addr(d);
         gsym(a);
@@ -4411,12 +5940,12 @@
     } else if (tok == '{') {
         Sym *llabel;
-        
+        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
+
         next();
         /* record local declaration stack position */
         s = local_stack;
-        frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
-        frame_bottom->next = scope_stack_bottom;
-        scope_stack_bottom = frame_bottom;
         llabel = local_label_stack;
+        ++local_scope;
+        
         /* handle local labels declarations */
         if (tok == TOK_LABEL) {
@@ -4436,30 +5965,34 @@
         }
         while (tok != '}') {
-            label_or_decl(VT_LOCAL);
+	    if ((a = is_label()))
+		unget_tok(a);
+	    else
+	        decl(VT_LOCAL);
             if (tok != '}') {
                 if (is_expr)
                     vpop();
-                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
+                block(bsym, csym, is_expr);
             }
         }
         /* pop locally defined labels */
-        label_pop(&local_label_stack, llabel);
-        if(is_expr) {
-            /* XXX: this solution makes only valgrind happy...
-               triggered by gcc.c-torture/execute/20000917-1.c */
-            Sym *p;
-            switch(vtop->type.t & VT_BTYPE) {
-            case VT_PTR:
-            case VT_STRUCT:
-            case VT_ENUM:
-            case VT_FUNC:
-                for(p=vtop->type.ref;p;p=p->prev)
-                    if(p->prev==s)
-                        tcc_error("unsupported expression type");
-            }
-        }
+        label_pop(&local_label_stack, llabel, is_expr);
         /* pop locally defined symbols */
-        scope_stack_bottom = scope_stack_bottom->next;
-        sym_pop(&local_stack, s);
+        --local_scope;
+	/* In the is_expr case (a statement expression is finished here),
+	   vtop might refer to symbols on the local_stack.  Either via the
+	   type or via vtop->sym.  We can't pop those nor any that in turn
+	   might be referred to.  To make it easier we don't roll back
+	   any symbols in that case; some upper level call to block() will
+	   do that.  We do have to remove such symbols from the lookup
+	   tables, though.  sym_pop will do that.  */
+	sym_pop(&local_stack, s, is_expr);
+
+        /* Pop VLA frames and restore stack pointer if required */
+        if (vlas_in_scope > saved_vlas_in_scope) {
+            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
+            vla_sp_restore();
+        }
+        vlas_in_scope = saved_vlas_in_scope;
+        
         next();
     } else if (tok == TOK_RETURN) {
@@ -4468,48 +6001,14 @@
             gexpr();
             gen_assign_cast(&func_vt);
-            if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
-                CType type;
-                /* if returning structure, must copy it to implicit
-                   first pointer arg location */
-#ifdef TCC_ARM_EABI
-                int align, size;
-                size = type_size(&func_vt,&align);
-                if(size <= 4)
-                {
-                    if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
-                       && (align & 3))
-                    {
-                        int addr;
-                        loc = (loc - size) & -4;
-                        addr = loc;
-                        type = func_vt;
-                        vset(&type, VT_LOCAL | VT_LVAL, addr);
-                        vswap();
-                        vstore();
-                        vset(&int_type, VT_LOCAL | VT_LVAL, addr);
-                    }
-                    vtop->type = int_type;
-                    gv(RC_IRET);
-                } else {
-#endif
-                type = func_vt;
-                mk_pointer(&type);
-                vset(&type, VT_LOCAL | VT_LVAL, func_vc);
-                indir();
-                vswap();
-                /* copy structure value to pointer */
-                vstore();
-#ifdef TCC_ARM_EABI
-                }
-#endif
-            } else if (is_float(func_vt.t)) {
-                gv(rc_fret(func_vt.t));
-            } else {
-                gv(RC_IRET);
-            }
-            vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+            if ((func_vt.t & VT_BTYPE) == VT_VOID)
+                vtop--;
+            else
+                gfunc_return(&func_vt);
         }
         skip(';');
-        rsym = gjmp(rsym); /* jmp */
+        /* jump unless last stmt in top-level block */
+        if (tok != '}' || local_scope != 1)
+            rsym = gjmp(rsym);
+	nocode_wanted |= 0x20000000;
     } else if (tok == TOK_BREAK) {
         /* compute jump */
@@ -4519,8 +6018,10 @@
         next();
         skip(';');
+	nocode_wanted |= 0x20000000;
     } else if (tok == TOK_CONTINUE) {
         /* compute jump */
         if (!csym)
             tcc_error("cannot continue");
+        vla_sp_restore_root();
         *csym = gjmp(*csym);
         next();
@@ -4528,13 +6029,13 @@
     } else if (tok == TOK_FOR) {
         int e;
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
         next();
         skip('(');
         s = local_stack;
-        frame_bottom = sym_push2(&local_stack, SYM_FIELD, 0, 0);
-        frame_bottom->next = scope_stack_bottom;
-        scope_stack_bottom = frame_bottom;
+        ++local_scope;
         if (tok != ';') {
             /* c99 for-loop init decl? */
-            if (!decl0(VT_LOCAL, 1)) {
+            if (!decl0(VT_LOCAL, 1, NULL)) {
                 /* no, regular for-loop init expr */
                 gexpr();
@@ -4545,9 +6046,10 @@
         d = ind;
         c = ind;
+        vla_sp_restore();
         a = 0;
         b = 0;
         if (tok != ';') {
             gexpr();
-            a = gtst(1, 0);
+            a = gvtst(1, 0);
         }
         skip(';');
@@ -4555,4 +6057,5 @@
             e = gjmp(0);
             c = ind;
+            vla_sp_restore();
             gexpr();
             vpop();
@@ -4561,23 +6064,31 @@
         }
         skip(')');
-        block(&a, &b, case_sym, def_sym, case_reg, 0);
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
+	nocode_wanted = saved_nocode_wanted;
         gjmp_addr(c);
         gsym(a);
         gsym_addr(b, c);
-        scope_stack_bottom = scope_stack_bottom->next;
-        sym_pop(&local_stack, s);
+        --local_scope;
+        sym_pop(&local_stack, s, 0);
+
     } else 
     if (tok == TOK_DO) {
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
         next();
         a = 0;
         b = 0;
         d = ind;
-        block(&a, &b, case_sym, def_sym, case_reg, 0);
+        vla_sp_restore();
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
         skip(TOK_WHILE);
         skip('(');
         gsym(b);
-        gexpr();
-        c = gtst(0, 0);
-        gsym_addr(c, d);
+	gexpr();
+	c = gvtst(0, 0);
+	gsym_addr(c, d);
+	nocode_wanted = saved_nocode_wanted;
         skip(')');
         gsym(a);
@@ -4585,53 +6096,55 @@
     } else
     if (tok == TOK_SWITCH) {
+        struct switch_t *saved, sw;
+	int saved_nocode_wanted = nocode_wanted;
+	SValue switchval;
         next();
         skip('(');
         gexpr();
-        /* XXX: other types than integer */
-        case_reg = gv(RC_INT);
-        vpop();
         skip(')');
+	switchval = *vtop--;
         a = 0;
         b = gjmp(0); /* jump to first case */
-        c = 0;
-        block(&a, csym, &b, &c, case_reg, 0);
-        /* if no default, jmp after switch */
-        if (c == 0)
-            c = ind;
-        /* default label */
-        gsym_addr(b, c);
+        sw.p = NULL; sw.n = 0; sw.def_sym = 0;
+        saved = cur_switch;
+        cur_switch = &sw;
+        block(&a, csym, 0);
+	nocode_wanted = saved_nocode_wanted;
+        a = gjmp(a); /* add implicit break */
+        /* case lookup */
+        gsym(b);
+        qsort(sw.p, sw.n, sizeof(void*), case_cmp);
+        for (b = 1; b < sw.n; b++)
+            if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
+                tcc_error("duplicate case value");
+        /* Our switch table sorting is signed, so the compared
+           value needs to be as well when it's 64bit.  */
+        if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
+            switchval.type.t &= ~VT_UNSIGNED;
+        vpushv(&switchval);
+        gcase(sw.p, sw.n, &a);
+        vpop();
+        if (sw.def_sym)
+          gjmp_addr(sw.def_sym);
+        dynarray_reset(&sw.p, &sw.n);
+        cur_switch = saved;
         /* break label */
         gsym(a);
     } else
     if (tok == TOK_CASE) {
-        int v1, v2;
-        if (!case_sym)
+        struct case_t *cr = tcc_malloc(sizeof(struct case_t));
+        if (!cur_switch)
             expect("switch");
+	nocode_wanted &= ~0x20000000;
         next();
-        v1 = expr_const();
-        v2 = v1;
+        cr->v1 = cr->v2 = expr_const64();
         if (gnu_ext && tok == TOK_DOTS) {
             next();
-            v2 = expr_const();
-            if (v2 < v1)
+            cr->v2 = expr_const64();
+            if (cr->v2 < cr->v1)
                 tcc_warning("empty case range");
         }
-        /* since a case is like a label, we must skip it with a jmp */
-        b = gjmp(0);
-        gsym(*case_sym);
-        vseti(case_reg, 0);
-        vpushi(v1);
-        if (v1 == v2) {
-            gen_op(TOK_EQ);
-            *case_sym = gtst(1, 0);
-        } else {
-            gen_op(TOK_GE);
-            *case_sym = gtst(1, 0);
-            vseti(case_reg, 0);
-            vpushi(v2);
-            gen_op(TOK_LE);
-            *case_sym = gtst(1, *case_sym);
-        }
-        gsym(b);
+        cr->sym = ind;
+        dynarray_add(&cur_switch->p, &cur_switch->n, cr);
         skip(':');
         is_expr = 0;
@@ -4641,9 +6154,9 @@
         next();
         skip(':');
-        if (!def_sym)
+        if (!cur_switch)
             expect("switch");
-        if (*def_sym)
+        if (cur_switch->def_sym)
             tcc_error("too many 'default'");
-        *def_sym = ind;
+        cur_switch->def_sym = ind;
         is_expr = 0;
         goto block_after_label;
@@ -4667,6 +6180,6 @@
                     s->r = LABEL_FORWARD;
             }
-            /* label already defined */
-            if (s->r & LABEL_FORWARD) 
+            vla_sp_restore_root();
+	    if (s->r & LABEL_FORWARD)
                 s->jnext = gjmp(s->jnext);
             else
@@ -4683,4 +6196,5 @@
         if (b) {
             /* label case */
+	    next();
             s = label_find(b);
             if (s) {
@@ -4693,6 +6207,8 @@
             }
             s->jnext = ind;
+            vla_sp_restore();
             /* we accept this, but it is a mistake */
         block_after_label:
+	    nocode_wanted &= ~0x20000000;
             if (tok == '}') {
                 tcc_warning("deprecated use of label at end of compound statement");
@@ -4700,5 +6216,5 @@
                 if (is_expr)
                     vpop();
-                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
+                block(bsym, csym, is_expr);
             }
         } else {
@@ -4718,141 +6234,49 @@
 }
 
-/* t is the array or struct type. c is the array or struct
-   address. cur_index/cur_field is the pointer to the current
-   value. 'size_only' is true if only size info is needed (only used
-   in arrays) */
-static void decl_designator(CType *type, Section *sec, unsigned long c, 
-                            int *cur_index, Sym **cur_field, 
-                            int size_only)
-{
-    Sym *s, *f;
-    int notfirst, index, index_last, align, l, nb_elems, elem_size;
-    CType type1;
-
-    notfirst = 0;
-    elem_size = 0;
-    nb_elems = 1;
-    if (gnu_ext && (l = is_label()) != 0)
-        goto struct_field;
-    while (tok == '[' || tok == '.') {
-        if (tok == '[') {
-            if (!(type->t & VT_ARRAY))
-                expect("array type");
-            s = type->ref;
-            next();
-            index = expr_const();
-            if (index < 0 || (s->c >= 0 && index >= s->c))
-                expect("invalid index");
-            if (tok == TOK_DOTS && gnu_ext) {
-                next();
-                index_last = expr_const();
-                if (index_last < 0 || 
-                    (s->c >= 0 && index_last >= s->c) ||
-                    index_last < index)
-                    expect("invalid index");
-            } else {
-                index_last = index;
-            }
-            skip(']');
-            if (!notfirst)
-                *cur_index = index_last;
-            type = pointed_type(type);
-            elem_size = type_size(type, &align);
-            c += index * elem_size;
-            /* NOTE: we only support ranges for last designator */
-            nb_elems = index_last - index + 1;
-            if (nb_elems != 1) {
-                notfirst = 1;
-                break;
-            }
-        } else {
-            next();
-            l = tok;
-            next();
-        struct_field:
-            if ((type->t & VT_BTYPE) != VT_STRUCT)
-                expect("struct/union type");
-            s = type->ref;
-            l |= SYM_FIELD;
-            f = s->next;
-            while (f) {
-                if (f->v == l)
-                    break;
-                f = f->next;
-            }
-            if (!f)
-                expect("field");
-            if (!notfirst)
-                *cur_field = f;
-            /* XXX: fix this mess by using explicit storage field */
-            type1 = f->type;
-            type1.t |= (type->t & ~VT_TYPE);
-            type = &type1;
-            c += f->c;
-        }
-        notfirst = 1;
-    }
-    if (notfirst) {
-        if (tok == '=') {
-            next();
-        } else {
-            if (!gnu_ext)
-                expect("=");
-        }
-    } else {
-        if (type->t & VT_ARRAY) {
-            index = *cur_index;
-            type = pointed_type(type);
-            c += index * type_size(type, &align);
-        } else {
-            f = *cur_field;
-            if (!f)
-                tcc_error("too many field init");
-            /* XXX: fix this mess by using explicit storage field */
-            type1 = f->type;
-            type1.t |= (type->t & ~VT_TYPE);
-            type = &type1;
-            c += f->c;
-        }
-    }
-    decl_initializer(type, sec, c, 0, size_only);
-
-    /* XXX: make it more general */
-    if (!size_only && nb_elems > 1) {
-        unsigned long c_end;
-        uint8_t *src, *dst;
-        int i;
-
-        if (!sec)
-            tcc_error("range init not supported yet for dynamic storage");
-        c_end = c + nb_elems * elem_size;
-        if (c_end > sec->data_allocated)
-            section_realloc(sec, c_end);
-        src = sec->data + c;
-        dst = src;
-        for(i = 1; i < nb_elems; i++) {
-            dst += elem_size;
-            memcpy(dst, src, elem_size);
-        }
-    }
-}
-
-#define EXPR_VAL   0
+/* This skips over a stream of tokens containing balanced {} and ()
+   pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
+   with a '{').  If STR then allocates and stores the skipped tokens
+   in *STR.  This doesn't check if () and {} are nested correctly,
+   i.e. "({)}" is accepted.  */
+static void skip_or_save_block(TokenString **str)
+{
+    int braces = tok == '{';
+    int level = 0;
+    if (str)
+      *str = tok_str_alloc();
+
+    while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
+	int t;
+	if (tok == TOK_EOF) {
+	     if (str || level > 0)
+	       tcc_error("unexpected end of file");
+	     else
+	       break;
+	}
+	if (str)
+	  tok_str_add_tok(*str);
+	t = tok;
+	next();
+	if (t == '{' || t == '(') {
+	    level++;
+	} else if (t == '}' || t == ')') {
+	    level--;
+	    if (level == 0 && braces && t == '}')
+	      break;
+	}
+    }
+    if (str) {
+	tok_str_add(*str, -1);
+	tok_str_add(*str, 0);
+    }
+}
+
 #define EXPR_CONST 1
 #define EXPR_ANY   2
 
-/* store a value or an expression directly in global data or in local array */
-static void init_putv(CType *type, Section *sec, unsigned long c, 
-                      int v, int expr_type)
-{
-    int saved_global_expr, bt, bit_pos, bit_size;
-    void *ptr;
-    unsigned long long bit_mask;
-    CType dtype;
-
+static void parse_init_elem(int expr_type)
+{
+    int saved_global_expr;
     switch(expr_type) {
-    case EXPR_VAL:
-        vpushi(v);
-        break;
     case EXPR_CONST:
         /* compound literals must be allocated globally in this case */
@@ -4861,6 +6285,13 @@
         expr_const1();
         global_expr = saved_global_expr;
-        /* NOTE: symbols are accepted */
-        if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
+        /* NOTE: symbols are accepted, as well as lvalue for anon symbols
+	   (compound literals).  */
+        if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
+	     && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
+		 || vtop->sym->v < SYM_FIRST_ANOM))
+#ifdef TCC_TARGET_PE
+                 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
+#endif
+            )
             tcc_error("initializer element is not constant");
         break;
@@ -4869,61 +6300,323 @@
         break;
     }
-    
+}
+
+/* put zeros for variable based init */
+static void init_putz(Section *sec, unsigned long c, int size)
+{
+    if (sec) {
+        /* nothing to do because globals are already set to zero */
+    } else {
+        vpush_global_sym(&func_old_type, TOK_memset);
+        vseti(VT_LOCAL, c);
+#ifdef TCC_TARGET_ARM
+        vpushs(size);
+        vpushi(0);
+#else
+        vpushi(0);
+        vpushs(size);
+#endif
+        gfunc_call(3);
+    }
+}
+
+/* t is the array or struct type. c is the array or struct
+   address. cur_field is the pointer to the current
+   field, for arrays the 'c' member contains the current start
+   index.  'size_only' is true if only size info is needed (only used
+   in arrays).  al contains the already initialized length of the
+   current container (starting at c).  This returns the new length of that.  */
+static int decl_designator(CType *type, Section *sec, unsigned long c,
+                           Sym **cur_field, int size_only, int al)
+{
+    Sym *s, *f;
+    int index, index_last, align, l, nb_elems, elem_size;
+    unsigned long corig = c;
+
+    elem_size = 0;
+    nb_elems = 1;
+    if (gnu_ext && (l = is_label()) != 0)
+        goto struct_field;
+    /* NOTE: we only support ranges for last designator */
+    while (nb_elems == 1 && (tok == '[' || tok == '.')) {
+        if (tok == '[') {
+            if (!(type->t & VT_ARRAY))
+                expect("array type");
+            next();
+            index = index_last = expr_const();
+            if (tok == TOK_DOTS && gnu_ext) {
+                next();
+                index_last = expr_const();
+            }
+            skip(']');
+            s = type->ref;
+	    if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
+		index_last < index)
+	        tcc_error("invalid index");
+            if (cur_field)
+		(*cur_field)->c = index_last;
+            type = pointed_type(type);
+            elem_size = type_size(type, &align);
+            c += index * elem_size;
+            nb_elems = index_last - index + 1;
+        } else {
+            next();
+            l = tok;
+        struct_field:
+            next();
+            if ((type->t & VT_BTYPE) != VT_STRUCT)
+                expect("struct/union type");
+	    f = find_field(type, l);
+            if (!f)
+                expect("field");
+            if (cur_field)
+                *cur_field = f;
+	    type = &f->type;
+            c += f->c;
+        }
+        cur_field = NULL;
+    }
+    if (!cur_field) {
+        if (tok == '=') {
+            next();
+        } else if (!gnu_ext) {
+	    expect("=");
+        }
+    } else {
+        if (type->t & VT_ARRAY) {
+	    index = (*cur_field)->c;
+	    if (type->ref->c >= 0 && index >= type->ref->c)
+	        tcc_error("index too large");
+            type = pointed_type(type);
+            c += index * type_size(type, &align);
+        } else {
+            f = *cur_field;
+	    while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
+	        *cur_field = f = f->next;
+            if (!f)
+                tcc_error("too many field init");
+	    type = &f->type;
+            c += f->c;
+        }
+    }
+    /* must put zero in holes (note that doing it that way
+       ensures that it even works with designators) */
+    if (!size_only && c - corig > al)
+	init_putz(sec, corig + al, c - corig - al);
+    decl_initializer(type, sec, c, 0, size_only);
+
+    /* XXX: make it more general */
+    if (!size_only && nb_elems > 1) {
+        unsigned long c_end;
+        uint8_t *src, *dst;
+        int i;
+
+        if (!sec) {
+	    vset(type, VT_LOCAL|VT_LVAL, c);
+	    for (i = 1; i < nb_elems; i++) {
+		vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
+		vswap();
+		vstore();
+	    }
+	    vpop();
+        } else if (!NODATA_WANTED) {
+	    c_end = c + nb_elems * elem_size;
+	    if (c_end > sec->data_allocated)
+	        section_realloc(sec, c_end);
+	    src = sec->data + c;
+	    dst = src;
+	    for(i = 1; i < nb_elems; i++) {
+		dst += elem_size;
+		memcpy(dst, src, elem_size);
+	    }
+	}
+    }
+    c += nb_elems * type_size(type, &align);
+    if (c - corig > al)
+      al = c - corig;
+    return al;
+}
+
+/* store a value or an expression directly in global data or in local array */
+static void init_putv(CType *type, Section *sec, unsigned long c)
+{
+    int bt;
+    void *ptr;
+    CType dtype;
+
     dtype = *type;
     dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
 
     if (sec) {
+	int size, align;
         /* XXX: not portable */
         /* XXX: generate error if incorrect relocation */
         gen_assign_cast(&dtype);
         bt = type->t & VT_BTYPE;
-        /* we'll write at most 12 bytes */
-        if (c + 12 > sec->data_allocated) {
-            section_realloc(sec, c + 12);
-        }
+
+        if ((vtop->r & VT_SYM)
+            && bt != VT_PTR
+            && bt != VT_FUNC
+            && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
+                || (type->t & VT_BITFIELD))
+            && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
+            )
+            tcc_error("initializer element is not computable at load time");
+
+        if (NODATA_WANTED) {
+            vtop--;
+            return;
+        }
+
+	size = type_size(type, &align);
+	section_reserve(sec, c + size);
         ptr = sec->data + c;
+
         /* XXX: make code faster ? */
-        if (!(type->t & VT_BITFIELD)) {
-            bit_pos = 0;
-            bit_size = 32;
-            bit_mask = -1LL;
-        } else {
-            bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
-            bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
-            bit_mask = (1LL << bit_size) - 1;
-        }
-        if ((vtop->r & VT_SYM) &&
-            (bt == VT_BYTE ||
-             bt == VT_SHORT ||
-             bt == VT_DOUBLE ||
-             bt == VT_LDOUBLE ||
-             bt == VT_LLONG ||
-             (bt == VT_INT && bit_size != 32)))
-            tcc_error("initializer element is not computable at load time");
-        switch(bt) {
-        case VT_BOOL:
-            vtop->c.i = (vtop->c.i != 0);
-        case VT_BYTE:
-            *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
-            break;
-        case VT_SHORT:
-            *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
-            break;
-        case VT_DOUBLE:
-            *(double *)ptr = vtop->c.d;
-            break;
-        case VT_LDOUBLE:
-            *(long double *)ptr = vtop->c.ld;
-            break;
-        case VT_LLONG:
-            *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
-            break;
-        default:
-            if (vtop->r & VT_SYM) {
-                greloc(sec, vtop->sym, c, R_DATA_PTR);
-            }
-            *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
-            break;
-        }
+	if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
+	    vtop->sym->v >= SYM_FIRST_ANOM &&
+	    /* XXX This rejects compound literals like
+	       '(void *){ptr}'.  The problem is that '&sym' is
+	       represented the same way, which would be ruled out
+	       by the SYM_FIRST_ANOM check above, but also '"string"'
+	       in 'char *p = "string"' is represented the same
+	       with the type being VT_PTR and the symbol being an
+	       anonymous one.  That is, there's no difference in vtop
+	       between '(void *){x}' and '&(void *){x}'.  Ignore
+	       pointer typed entities here.  Hopefully no real code
+	       will every use compound literals with scalar type.  */
+	    (vtop->type.t & VT_BTYPE) != VT_PTR) {
+	    /* These come from compound literals, memcpy stuff over.  */
+	    Section *ssec;
+	    ElfSym *esym;
+	    ElfW_Rel *rel;
+	    esym = elfsym(vtop->sym);
+	    ssec = tcc_state->sections[esym->st_shndx];
+	    memmove (ptr, ssec->data + esym->st_value, size);
+	    if (ssec->reloc) {
+		/* We need to copy over all memory contents, and that
+		   includes relocations.  Use the fact that relocs are
+		   created it order, so look from the end of relocs
+		   until we hit one before the copied region.  */
+		int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
+		rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
+		while (num_relocs--) {
+		    rel--;
+		    if (rel->r_offset >= esym->st_value + size)
+		      continue;
+		    if (rel->r_offset < esym->st_value)
+		      break;
+		    /* Note: if the same fields are initialized multiple
+		       times (possible with designators) then we possibly
+		       add multiple relocations for the same offset here.
+		       That would lead to wrong code, the last reloc needs
+		       to win.  We clean this up later after the whole
+		       initializer is parsed.  */
+		    put_elf_reloca(symtab_section, sec,
+				   c + rel->r_offset - esym->st_value,
+				   ELFW(R_TYPE)(rel->r_info),
+				   ELFW(R_SYM)(rel->r_info),
+#if PTR_SIZE == 8
+				   rel->r_addend
+#else
+				   0
+#endif
+				  );
+		}
+	    }
+	} else {
+            if (type->t & VT_BITFIELD) {
+                int bit_pos, bit_size, bits, n;
+                unsigned char *p, v, m;
+                bit_pos = BIT_POS(vtop->type.t);
+                bit_size = BIT_SIZE(vtop->type.t);
+                p = (unsigned char*)ptr + (bit_pos >> 3);
+                bit_pos &= 7, bits = 0;
+                while (bit_size) {
+                    n = 8 - bit_pos;
+                    if (n > bit_size)
+                        n = bit_size;
+                    v = vtop->c.i >> bits << bit_pos;
+                    m = ((1 << n) - 1) << bit_pos;
+                    *p = (*p & ~m) | (v & m);
+                    bits += n, bit_size -= n, bit_pos = 0, ++p;
+                }
+            } else
+            switch(bt) {
+		/* XXX: when cross-compiling we assume that each type has the
+		   same representation on host and target, which is likely to
+		   be wrong in the case of long double */
+	    case VT_BOOL:
+		vtop->c.i = vtop->c.i != 0;
+	    case VT_BYTE:
+		*(char *)ptr |= vtop->c.i;
+		break;
+	    case VT_SHORT:
+		*(short *)ptr |= vtop->c.i;
+		break;
+	    case VT_FLOAT:
+		*(float*)ptr = vtop->c.f;
+		break;
+	    case VT_DOUBLE:
+		*(double *)ptr = vtop->c.d;
+		break;
+	    case VT_LDOUBLE:
+#if defined TCC_IS_NATIVE_387
+                if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
+                    memcpy(ptr, &vtop->c.ld, 10);
+#ifdef __TINYC__
+                else if (sizeof (long double) == sizeof (double))
+                    __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
+#endif
+                else if (vtop->c.ld == 0.0)
+                    ;
+                else
+#endif
+                if (sizeof(long double) == LDOUBLE_SIZE)
+		    *(long double*)ptr = vtop->c.ld;
+                else if (sizeof(double) == LDOUBLE_SIZE)
+		    *(double *)ptr = (double)vtop->c.ld;
+                else
+                    tcc_error("can't cross compile long double constants");
+		break;
+#if PTR_SIZE != 8
+	    case VT_LLONG:
+		*(long long *)ptr |= vtop->c.i;
+		break;
+#else
+	    case VT_LLONG:
+#endif
+	    case VT_PTR:
+		{
+		    addr_t val = vtop->c.i;
+#if PTR_SIZE == 8
+		    if (vtop->r & VT_SYM)
+		      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+		    else
+		      *(addr_t *)ptr |= val;
+#else
+		    if (vtop->r & VT_SYM)
+		      greloc(sec, vtop->sym, c, R_DATA_PTR);
+		    *(addr_t *)ptr |= val;
+#endif
+		    break;
+		}
+	    default:
+		{
+		    int val = vtop->c.i;
+#if PTR_SIZE == 8
+		    if (vtop->r & VT_SYM)
+		      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+		    else
+		      *(int *)ptr |= val;
+#else
+		    if (vtop->r & VT_SYM)
+		      greloc(sec, vtop->sym, c, R_DATA_PTR);
+		    *(int *)ptr |= val;
+#endif
+		    break;
+		}
+	    }
+	}
         vtop--;
     } else {
@@ -4932,18 +6625,4 @@
         vstore();
         vpop();
-    }
-}
-
-/* put zeros for variable based init */
-static void init_putz(CType *t, Section *sec, unsigned long c, int size)
-{
-    if (sec) {
-        /* nothing to do because globals are already set to zero */
-    } else {
-        vpush_global_sym(&func_old_type, TOK_memset);
-        vseti(VT_LOCAL, c);
-        vpushi(0);
-        vpushi(size);
-        gfunc_call(3);
     }
 }
@@ -4957,32 +6636,34 @@
                              int first, int size_only)
 {
-    int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
-    int size1, align1, expr_type;
+    int len, n, no_oblock, nb, i;
+    int size1, align1;
+    int have_elem;
     Sym *s, *f;
+    Sym indexsym;
     CType *t1;
 
-    if (type->t & VT_VLA) {
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-        int a;
-        CValue retcval;
-
-        vpush_global_sym(&func_old_type, TOK_alloca);
-        vla_runtime_type_size(type, &a);
-        gfunc_call(1);
-
-        /* return value */
-        retcval.i = 0;
-        vsetc(type, REG_IRET, &retcval);
-        vset(type, VT_LOCAL|VT_LVAL, c);
-        vswap();
-        vstore();
-        vpop();
-#else
-        tcc_error("variable length arrays unsupported for this target");
-#endif
+    /* If we currently are at an '}' or ',' we have read an initializer
+       element in one of our callers, and not yet consumed it.  */
+    have_elem = tok == '}' || tok == ',';
+    if (!have_elem && tok != '{' &&
+	/* In case of strings we have special handling for arrays, so
+	   don't consume them as initializer value (which would commit them
+	   to some anonymous symbol).  */
+	tok != TOK_LSTR && tok != TOK_STR &&
+	!size_only) {
+	parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+	have_elem = 1;
+    }
+
+    if (have_elem &&
+	!(type->t & VT_ARRAY) &&
+	/* Use i_c_parameter_t, to strip toplevel qualifiers.
+	   The source type might have VT_CONSTANT set, which is
+	   of course assignable to non-const elements.  */
+	is_compatible_unqualified_types(type, &vtop->type)) {
+        init_putv(type, sec, c);
     } else if (type->t & VT_ARRAY) {
         s = type->ref;
         n = s->c;
-        array_length = 0;
         t1 = pointed_type(type);
         size1 = type_size(t1, &align1);
@@ -5007,18 +6688,17 @@
 #endif
             ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
+	    len = 0;
             while (tok == TOK_STR || tok == TOK_LSTR) {
                 int cstr_len, ch;
-                CString *cstr;
-
-                cstr = tokc.cstr;
+
                 /* compute maximum number of chars wanted */
                 if (tok == TOK_STR)
-                    cstr_len = cstr->size;
+                    cstr_len = tokc.str.size;
                 else
-                    cstr_len = cstr->size / sizeof(nwchar_t);
+                    cstr_len = tokc.str.size / sizeof(nwchar_t);
                 cstr_len--;
                 nb = cstr_len;
-                if (n >= 0 && nb > (n - array_length))
-                    nb = n - array_length;
+                if (n >= 0 && nb > (n - len))
+                    nb = n - len;
                 if (!size_only) {
                     if (cstr_len > nb)
@@ -5028,92 +6708,70 @@
                        specifically */
                     if (sec && tok == TOK_STR && size1 == 1) {
-                        memcpy(sec->data + c + array_length, cstr->data, nb);
+                        if (!NODATA_WANTED)
+                            memcpy(sec->data + c + len, tokc.str.data, nb);
                     } else {
                         for(i=0;i<nb;i++) {
                             if (tok == TOK_STR)
-                                ch = ((unsigned char *)cstr->data)[i];
+                                ch = ((unsigned char *)tokc.str.data)[i];
                             else
-                                ch = ((nwchar_t *)cstr->data)[i];
-                            init_putv(t1, sec, c + (array_length + i) * size1,
-                                      ch, EXPR_VAL);
+                                ch = ((nwchar_t *)tokc.str.data)[i];
+			    vpushi(ch);
+                            init_putv(t1, sec, c + (len + i) * size1);
                         }
                     }
                 }
-                array_length += nb;
+                len += nb;
                 next();
             }
             /* only add trailing zero if enough storage (no
                warning in this case since it is standard) */
-            if (n < 0 || array_length < n) {
+            if (n < 0 || len < n) {
                 if (!size_only) {
-                    init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
+		    vpushi(0);
+                    init_putv(t1, sec, c + (len * size1));
                 }
-                array_length++;
-            }
+                len++;
+            }
+	    len *= size1;
         } else {
-            index = 0;
-            while (tok != '}') {
-                decl_designator(type, sec, c, &index, NULL, size_only);
-                if (n >= 0 && index >= n)
-                    tcc_error("index too large");
-                /* must put zero in holes (note that doing it that way
-                   ensures that it even works with designators) */
-                if (!size_only && array_length < index) {
-                    init_putz(t1, sec, c + array_length * size1, 
-                              (index - array_length) * size1);
-                }
-                index++;
-                if (index > array_length)
-                    array_length = index;
-                /* special test for multi dimensional arrays (may not
-                   be strictly correct if designators are used at the
-                   same time) */
-                if (index >= n && no_oblock)
-                    break;
-                if (tok == '}')
-                    break;
-                skip(',');
-            }
-        }
+	    indexsym.c = 0;
+	    f = &indexsym;
+
+          do_init_list:
+	    len = 0;
+	    while (tok != '}' || have_elem) {
+		len = decl_designator(type, sec, c, &f, size_only, len);
+		have_elem = 0;
+		if (type->t & VT_ARRAY) {
+		    ++indexsym.c;
+		    /* special test for multi dimensional arrays (may not
+		       be strictly correct if designators are used at the
+		       same time) */
+		    if (no_oblock && len >= n*size1)
+		        break;
+		} else {
+		    if (s->type.t == VT_UNION)
+		        f = NULL;
+		    else
+		        f = f->next;
+		    if (no_oblock && f == NULL)
+		        break;
+		}
+
+		if (tok == '}')
+		    break;
+		skip(',');
+	    }
+        }
+        /* put zeros at the end */
+	if (!size_only && len < n*size1)
+	    init_putz(sec, c + len, n*size1 - len);
         if (!no_oblock)
             skip('}');
-        /* put zeros at the end */
-        if (!size_only && n >= 0 && array_length < n) {
-            init_putz(t1, sec, c + array_length * size1, 
-                      (n - array_length) * size1);
-        }
-        /* patch type size if needed */
+        /* patch type size if needed, which happens only for array types */
         if (n < 0)
-            s->c = array_length;
-    } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
-               (sec || !first || tok == '{')) {
-        int par_count;
-
-        /* NOTE: the previous test is a specific case for automatic
-           struct/union init */
-        /* XXX: union needs only one init */
-
-        /* XXX: this test is incorrect for local initializers
-           beginning with ( without {. It would be much more difficult
-           to do it correctly (ideally, the expression parser should
-           be used in all cases) */
-        par_count = 0;
-        if (tok == '(') {
-            AttributeDef ad1;
-            CType type1;
-            next();
-            while (tok == '(') {
-                par_count++;
-                next();
-            }
-            if (!parse_btype(&type1, &ad1))
-                expect("cast");
-            type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
-#if 0
-            if (!is_assignable_types(type, &type1))
-                tcc_error("invalid type for cast");
-#endif
-            skip(')');
-        }
+            s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
+    } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+	size1 = 1;
         no_oblock = 1;
         if (first || tok == '{') {
@@ -5123,53 +6781,6 @@
         s = type->ref;
         f = s->next;
-        array_length = 0;
-        index = 0;
         n = s->c;
-        while (tok != '}') {
-            decl_designator(type, sec, c, NULL, &f, size_only);
-            index = f->c;
-            if (!size_only && array_length < index) {
-                init_putz(type, sec, c + array_length, 
-                          index - array_length);
-            }
-            index = index + type_size(&f->type, &align1);
-            if (index > array_length)
-                array_length = index;
-
-            /* gr: skip fields from same union - ugly. */
-            while (f->next) {
-                ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t);
-                /* test for same offset */
-                if (f->next->c != f->c)
-                    break;
-                /* if yes, test for bitfield shift */
-                if ((f->type.t & VT_BITFIELD) && (f->next->type.t & VT_BITFIELD)) {
-                    int bit_pos_1 = (f->type.t >> VT_STRUCT_SHIFT) & 0x3f;
-                    int bit_pos_2 = (f->next->type.t >> VT_STRUCT_SHIFT) & 0x3f;
-                    //printf("bitfield %d %d\n", bit_pos_1, bit_pos_2);
-                    if (bit_pos_1 != bit_pos_2)
-                        break;
-                }
-                f = f->next;
-            }
-
-            f = f->next;
-            if (no_oblock && f == NULL)
-                break;
-            if (tok == '}')
-                break;
-            skip(',');
-        }
-        /* put zeros at the end */
-        if (!size_only && array_length < n) {
-            init_putz(type, sec, c + array_length, 
-                      n - array_length);
-        }
-        if (!no_oblock)
-            skip('}');
-        while (par_count) {
-            skip(')');
-            par_count--;
-        }
+	goto do_init_list;
     } else if (tok == '{') {
         next();
@@ -5177,25 +6788,22 @@
         skip('}');
     } else if (size_only) {
+	/* If we supported only ISO C we wouldn't have to accept calling
+	   this on anything than an array size_only==1 (and even then
+	   only on the outermost level, so no recursion would be needed),
+	   because initializing a flex array member isn't supported.
+	   But GNU C supports it, so we need to recurse even into
+	   subfields of structs and arrays when size_only is set.  */
         /* just skip expression */
-        parlevel = parlevel1 = 0;
-        while ((parlevel > 0 || parlevel1 > 0 ||
-		(tok != '}' && tok != ',')) &&  tok != -1) {
-            if (tok == '(')
-                parlevel++;
-            else if (tok == ')')
-                parlevel--;
-	    else if (tok == '{')
-		parlevel1++;
-	    else if (tok == '}')
-		parlevel1--;
-            next();
-        }
+        skip_or_save_block(NULL);
     } else {
-        /* currently, we always use constant expression for globals
-           (may change for scripting case) */
-        expr_type = EXPR_CONST;
-        if (!sec)
-            expr_type = EXPR_ANY;
-        init_putv(type, sec, c, 0, expr_type);
+	if (!have_elem) {
+	    /* This should happen only when we haven't parsed
+	       the init element above for fear of committing a
+	       string constant to memory too early.  */
+	    if (tok != TOK_STR && tok != TOK_LSTR)
+	      expect("string constant");
+	    parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+	}
+        init_putv(type, sec, c);
     }
 }
@@ -5204,28 +6812,34 @@
    allocate space in local or global data space ('r' is either
    VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
-   variable 'v' with an associated name represented by 'asm_label' of
-   scope 'scope' is declared before initializers are parsed. If 'v' is
-   zero, then a reference to the new object is put in the value stack.
-   If 'has_init' is 2, a special parsing is done to handle string
-   constants. */
+   variable 'v' of scope 'scope' is declared before initializers
+   are parsed. If 'v' is zero, then a reference to the new object
+   is put in the value stack. If 'has_init' is 2, a special parsing
+   is done to handle string constants. */
 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
-                                   int has_init, int v, char *asm_label,
-                                   int scope)
-{
-    int size, align, addr, data_offset;
-    int level;
-    ParseState saved_parse_state = {0};
-    TokenString init_str;
+                                   int has_init, int v, int scope)
+{
+    int size, align, addr;
+    TokenString *init_str = NULL;
+
     Section *sec;
     Sym *flexible_array;
+    Sym *sym = NULL;
+    int saved_nocode_wanted = nocode_wanted;
+#ifdef CONFIG_TCC_BCHECK
+    int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
+#endif
+
+    if (type->t & VT_STATIC)
+        nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
 
     flexible_array = NULL;
     if ((type->t & VT_BTYPE) == VT_STRUCT) {
-        Sym *field;
-        field = type->ref;
-        while (field && field->next)
-            field = field->next;
-        if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
-            flexible_array = field;
+        Sym *field = type->ref->next;
+        if (field) {
+            while (field->next)
+                field = field->next;
+            if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
+                flexible_array = field;
+        }
     }
 
@@ -5237,5 +6851,4 @@
        literals). It also simplifies local
        initializers handling */
-    tok_str_new(&init_str);
     if (size < 0 || (flexible_array && has_init)) {
         if (!has_init) 
@@ -5243,38 +6856,23 @@
         /* get all init string */
         if (has_init == 2) {
+	    init_str = tok_str_alloc();
             /* only get strings */
             while (tok == TOK_STR || tok == TOK_LSTR) {
-                tok_str_add_tok(&init_str);
+                tok_str_add_tok(init_str);
                 next();
             }
+	    tok_str_add(init_str, -1);
+	    tok_str_add(init_str, 0);
         } else {
-            level = 0;
-            while (level > 0 || (tok != ',' && tok != ';')) {
-                if (tok < 0)
-                    tcc_error("unexpected end of file in initializer");
-                tok_str_add_tok(&init_str);
-                if (tok == '{')
-                    level++;
-                else if (tok == '}') {
-                    level--;
-                    if (level <= 0) {
-                        next();
-                        break;
-                    }
-                }
-                next();
-            }
-        }
-        tok_str_add(&init_str, -1);
-        tok_str_add(&init_str, 0);
-        
+	    skip_or_save_block(&init_str);
+        }
+        unget_tok(0);
+
         /* compute size */
-        save_parse_state(&saved_parse_state);
-
-        macro_ptr = init_str.str;
+        begin_macro(init_str, 1);
         next();
         decl_initializer(type, NULL, 0, 1, 1);
         /* prepare second initializer parsing */
-        macro_ptr = init_str.str;
+        macro_ptr = init_str->str;
         next();
         
@@ -5284,17 +6882,26 @@
             tcc_error("unknown type size");
     }
-    if (flexible_array)
-        size += flexible_array->type.ref->c * pointed_size(&flexible_array->type);
+    /* If there's a flex member and it was used in the initializer
+       adjust size.  */
+    if (flexible_array &&
+	flexible_array->type.ref->c > 0)
+        size += flexible_array->type.ref->c
+	        * pointed_size(&flexible_array->type);
     /* take into account specified alignment if bigger */
-    if (ad->aligned) {
-        if (ad->aligned > align)
-            align = ad->aligned;
-    } else if (ad->packed) {
+    if (ad->a.aligned) {
+	int speca = 1 << (ad->a.aligned - 1);
+        if (speca > align)
+            align = speca;
+    } else if (ad->a.packed) {
         align = 1;
     }
+
+    if (NODATA_WANTED)
+        size = 0, align = 1;
+
     if ((r & VT_VALMASK) == VT_LOCAL) {
         sec = NULL;
 #ifdef CONFIG_TCC_BCHECK
-        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
+        if (bcheck && (type->t & VT_ARRAY)) {
             loc--;
         }
@@ -5306,10 +6913,10 @@
         /* XXX: currently, since we do only one pass, we cannot track
            '&' operators, so we add only arrays */
-        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
-            unsigned long *bounds_ptr;
+        if (bcheck && (type->t & VT_ARRAY)) {
+            addr_t *bounds_ptr;
             /* add padding between regions */
             loc--;
             /* then add local bound info */
-            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
+            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
             bounds_ptr[0] = addr;
             bounds_ptr[1] = size;
@@ -5318,5 +6925,13 @@
         if (v) {
             /* local variable */
-            sym_push(v, type, r, addr);
+#ifdef CONFIG_TCC_ASM
+	    if (ad->asm_label) {
+		int reg = asm_parse_regvar(ad->asm_label);
+		if (reg >= 0)
+		    r = (r & ~VT_VALMASK) | reg;
+	    }
+#endif
+            sym = sym_push(v, type, r, addr);
+            sym->a = ad->a;
         } else {
             /* push local reference */
@@ -5324,34 +6939,12 @@
         }
     } else {
-        Sym *sym;
-
-        sym = NULL;
         if (v && scope == VT_CONST) {
             /* see if the symbol was already defined */
             sym = sym_find(v);
             if (sym) {
-                if (!is_compatible_types(&sym->type, type))
-                    tcc_error("incompatible types for redefinition of '%s'", 
-                          get_tok_str(v, NULL));
-                if (sym->type.t & VT_EXTERN) {
-                    /* if the variable is extern, it was not allocated */
-                    sym->type.t &= ~VT_EXTERN;
-                    /* set array size if it was ommited in extern
-                       declaration */
-                    if ((sym->type.t & VT_ARRAY) && 
-                        sym->type.ref->c < 0 &&
-                        type->ref->c >= 0)
-                        sym->type.ref->c = type->ref->c;
-                } else {
-                    /* we accept several definitions of the same
-                       global variable. this is tricky, because we
-                       must play with the SHN_COMMON type of the symbol */
-                    /* XXX: should check if the variable was already
-                       initialized. It is incorrect to initialized it
-                       twice */
-                    /* no init data, we won't add more to the symbol */
-                    if (!has_init)
-                        goto no_alloc;
-                }
+                patch_storage(sym, ad, type);
+                /* we accept several definitions of the same global variable. */
+                if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
+                    goto no_alloc;
             }
         }
@@ -5365,65 +6958,43 @@
                 sec = bss_section;
         }
+
         if (sec) {
-            data_offset = sec->data_offset;
-            data_offset = (data_offset + align - 1) & -align;
-            addr = data_offset;
-            /* very important to increment global pointer at this time
-               because initializers themselves can create new initializers */
-            data_offset += size;
+	    addr = section_add(sec, size, align);
 #ifdef CONFIG_TCC_BCHECK
             /* add padding if bound check */
-            if (tcc_state->do_bounds_check)
-                data_offset++;
-#endif
-            sec->data_offset = data_offset;
-            /* allocate section space to put the data */
-            if (sec->sh_type != SHT_NOBITS && 
-                data_offset > sec->data_allocated)
-                section_realloc(sec, data_offset);
-            /* align section if needed */
-            if (align > sec->sh_addralign)
-                sec->sh_addralign = align;
+            if (bcheck)
+                section_add(sec, 1, 1);
+#endif
         } else {
-            addr = 0; /* avoid warning */
+            addr = align; /* SHN_COMMON is special, symbol value is align */
+	    sec = common_section;
         }
 
         if (v) {
-            if (scope != VT_CONST || !sym) {
+            if (!sym) {
                 sym = sym_push(v, type, r | VT_SYM, 0);
-                sym->asm_label = asm_label;
-            }
+                patch_storage(sym, ad, NULL);
+            }
+            /* Local statics have a scope until now (for
+               warnings), remove it here.  */
+            sym->sym_scope = 0;
             /* update symbol definition */
-            if (sec) {
-                put_extern_sym(sym, sec, addr, size);
-            } else {
-                ElfW(Sym) *esym;
-                /* put a common area */
-                put_extern_sym(sym, NULL, align, size);
-                /* XXX: find a nicer way */
-                esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
-                esym->st_shndx = SHN_COMMON;
-            }
+	    put_extern_sym(sym, sec, addr, size);
         } else {
-            CValue cval;
-
             /* push global reference */
             sym = get_sym_ref(type, sec, addr, size);
-            cval.ul = 0;
-            vsetc(type, VT_CONST | VT_SYM, &cval);
-            vtop->sym = sym;
-        }
-        /* patch symbol weakness */
-        if (type->t & VT_WEAK)
-            weaken_symbol(sym);
+	    vpushsym(type, sym);
+	    vtop->r |= r;
+        }
+
 #ifdef CONFIG_TCC_BCHECK
         /* handles bounds now because the symbol must be defined
            before for the relocation */
-        if (tcc_state->do_bounds_check) {
-            unsigned long *bounds_ptr;
-
-            greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR);
+        if (bcheck) {
+            addr_t *bounds_ptr;
+
+            greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
             /* then add global bound info */
-            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
+            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
             bounds_ptr[0] = 0; /* relocated */
             bounds_ptr[1] = size;
@@ -5431,11 +7002,36 @@
 #endif
     }
-    if (has_init || (type->t & VT_VLA)) {
+
+    if (type->t & VT_VLA) {
+        int a;
+
+        if (NODATA_WANTED)
+            goto no_alloc;
+
+        /* save current stack pointer */
+        if (vlas_in_scope == 0) {
+            if (vla_sp_root_loc == -1)
+                vla_sp_root_loc = (loc -= PTR_SIZE);
+            gen_vla_sp_save(vla_sp_root_loc);
+        }
+
+        vla_runtime_type_size(type, &a);
+        gen_vla_alloc(type, a);
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+        /* on _WIN64, because of the function args scratch area, the
+           result of alloca differs from RSP and is returned in RAX.  */
+        gen_vla_result(addr), addr = (loc -= PTR_SIZE);
+#endif
+        gen_vla_sp_save(addr);
+        vla_sp_loc = addr;
+        vlas_in_scope++;
+
+    } else if (has_init) {
+	size_t oldreloc_offset = 0;
+	if (sec && sec->reloc)
+	  oldreloc_offset = sec->reloc->data_offset;
         decl_initializer(type, sec, addr, 1, 0);
-        /* restore parse state if needed */
-        if (init_str.str) {
-            tok_str_free(init_str.str);
-            restore_parse_state(&saved_parse_state);
-        }
+	if (sec && sec->reloc)
+	  squeeze_multi_relocs(sec, oldreloc_offset);
         /* patch flexible array member size back to -1, */
         /* for possible subsequent similar declarations */
@@ -5443,70 +7039,13 @@
             flexible_array->type.ref->c = -1;
     }
- no_alloc: ;
-}
-
-static void put_func_debug(Sym *sym)
-{
-    char buf[512];
-
-    /* stabs info */
-    /* XXX: we put here a dummy type */
-    snprintf(buf, sizeof(buf), "%s:%c1", 
-             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
-    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
-                cur_text_section, sym->c);
-    /* //gr gdb wants a line at the function */
-    put_stabn(N_SLINE, 0, file->line_num, 0); 
-    last_ind = 0;
-    last_line_num = 0;
-}
-
-/* parse an old style function declaration list */
-/* XXX: check multiple parameter */
-static void func_decl_list(Sym *func_sym)
-{
-    AttributeDef ad;
-    int v;
-    Sym *s;
-    CType btype, type;
-
-    /* parse each declaration */
-    while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
-           tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
-        if (!parse_btype(&btype, &ad)) 
-            expect("declaration list");
-        if (((btype.t & VT_BTYPE) == VT_ENUM ||
-             (btype.t & VT_BTYPE) == VT_STRUCT) && 
-            tok == ';') {
-            /* we accept no variable after */
-        } else {
-            for(;;) {
-                type = btype;
-                type_decl(&type, &ad, &v, TYPE_DIRECT);
-                /* find parameter in function parameter list */
-                s = func_sym->next;
-                while (s != NULL) {
-                    if ((s->v & ~SYM_FIELD) == v)
-                        goto found;
-                    s = s->next;
-                }
-                tcc_error("declaration for parameter '%s' but no such parameter",
-                      get_tok_str(v, NULL));
-            found:
-                /* check that no storage specifier except 'register' was given */
-                if (type.t & VT_STORAGE)
-                    tcc_error("storage class specified for '%s'", get_tok_str(v, NULL)); 
-                convert_parameter_type(&type);
-                /* we can add the type (NOTE: it could be local to the function) */
-                s->type = type;
-                /* accept other parameters */
-                if (tok == ',')
-                    next();
-                else
-                    break;
-            }
-        }
-        skip(';');
-    }
+
+ no_alloc:
+    /* restore parse state if needed */
+    if (init_str) {
+        end_macro();
+        next();
+    }
+
+    nocode_wanted = saved_nocode_wanted;
 }
 
@@ -5515,5 +7054,4 @@
 static void gen_function(Sym *sym)
 {
-    int saved_nocode_wanted = nocode_wanted;
     nocode_wanted = 0;
     ind = cur_text_section->data_offset;
@@ -5522,81 +7060,87 @@
     funcname = get_tok_str(sym->v, NULL);
     func_ind = ind;
+    /* Initialize VLA state */
+    vla_sp_loc = -1;
+    vla_sp_root_loc = -1;
     /* put debug symbol */
-    if (tcc_state->do_debug)
-        put_func_debug(sym);
+    tcc_debug_funcstart(tcc_state, sym);
     /* push a dummy symbol to enable local sym storage */
     sym_push2(&local_stack, SYM_FIELD, 0, 0);
+    local_scope = 1; /* for function parameters */
     gfunc_prolog(&sym->type);
+    local_scope = 0;
     rsym = 0;
-    block(NULL, NULL, NULL, NULL, 0, 0);
+    block(NULL, NULL, 0);
+    nocode_wanted = 0;
     gsym(rsym);
     gfunc_epilog();
     cur_text_section->data_offset = ind;
-    label_pop(&global_label_stack, NULL);
+    label_pop(&global_label_stack, NULL, 0);
     /* reset local stack */
-    scope_stack_bottom = NULL;
-    sym_pop(&local_stack, NULL);
+    local_scope = 0;
+    sym_pop(&local_stack, NULL, 0);
     /* end of function */
     /* patch symbol size */
-    ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = 
-        ind - func_ind;
-    /* patch symbol weakness (this definition overrules any prototype) */
-    if (sym->type.t & VT_WEAK)
-        weaken_symbol(sym);
-    if (tcc_state->do_debug) {
-        put_stabn(N_FUN, 0, 0, ind - func_ind);
-    }
+    elfsym(sym)->st_size = ind - func_ind;
+    tcc_debug_funcend(tcc_state, ind - func_ind);
     /* It's better to crash than to generate wrong code */
     cur_text_section = NULL;
     funcname = ""; /* for safety */
     func_vt.t = VT_VOID; /* for safety */
+    func_var = 0; /* for safety */
     ind = 0; /* for safety */
-    nocode_wanted = saved_nocode_wanted;
-}
-
-ST_FUNC void gen_inline_functions(void)
+    nocode_wanted = 0x80000000;
+    check_vstack();
+}
+
+static void gen_inline_functions(TCCState *s)
 {
     Sym *sym;
-    int *str, inline_generated, i;
+    int inline_generated, i, ln;
     struct InlineFunc *fn;
 
+    ln = file->line_num;
     /* iterate while inline function are referenced */
-    for(;;) {
+    do {
         inline_generated = 0;
-        for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
-            fn = tcc_state->inline_fns[i];
+        for (i = 0; i < s->nb_inline_fns; ++i) {
+            fn = s->inline_fns[i];
             sym = fn->sym;
             if (sym && sym->c) {
                 /* the function was used: generate its code and
                    convert it to a normal function */
-                str = fn->token_str;
                 fn->sym = NULL;
                 if (file)
                     pstrcpy(file->filename, sizeof file->filename, fn->filename);
-                sym->r = VT_SYM | VT_CONST;
                 sym->type.t &= ~VT_INLINE;
 
-                macro_ptr = str;
+                begin_macro(fn->func_str, 1);
                 next();
                 cur_text_section = text_section;
                 gen_function(sym);
-                macro_ptr = NULL; /* fail safe */
+                end_macro();
 
                 inline_generated = 1;
             }
         }
-        if (!inline_generated)
-            break;
-    }
-    for (i = 0; i < tcc_state->nb_inline_fns; ++i) {
-        fn = tcc_state->inline_fns[i];
-        str = fn->token_str;
-        tok_str_free(str);
-    }
-    dynarray_reset(&tcc_state->inline_fns, &tcc_state->nb_inline_fns);
-}
-
-/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
-static int decl0(int l, int is_for_loop_init)
+    } while (inline_generated);
+    file->line_num = ln;
+}
+
+ST_FUNC void free_inline_functions(TCCState *s)
+{
+    int i;
+    /* free tokens of unused inline functions */
+    for (i = 0; i < s->nb_inline_fns; ++i) {
+        struct InlineFunc *fn = s->inline_fns[i];
+        if (fn->sym)
+            tok_str_free(fn->func_str);
+    }
+    dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
+}
+
+/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
+   if parsing old style parameter decl list (and FUNC_SYM is set then) */
+static int decl0(int l, int is_for_loop_init, Sym *func_sym)
 {
     int v, has_init, r;
@@ -5609,37 +7153,54 @@
             if (is_for_loop_init)
                 return 0;
-            /* skip redundant ';' */
-            /* XXX: find more elegant solution */
-            if (tok == ';') {
+            /* skip redundant ';' if not in old parameter decl scope */
+            if (tok == ';' && l != VT_CMP) {
                 next();
                 continue;
             }
-            if (l == VT_CONST &&
-                (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+            if (l != VT_CONST)
+                break;
+            if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
                 /* global asm block */
                 asm_global_instr();
                 continue;
             }
-            /* special test for old K&R protos without explicit int
-               type. Only accepted when defining global data */
-            if (l == VT_LOCAL || tok < TOK_DEFINE)
+            if (tok >= TOK_UIDENT) {
+               /* special test for old K&R protos without explicit int
+                  type. Only accepted when defining global data */
+                btype.t = VT_INT;
+            } else {
+                if (tok != TOK_EOF)
+                    expect("declaration");
                 break;
-            btype.t = VT_INT;
-        }
-        if (((btype.t & VT_BTYPE) == VT_ENUM ||
-             (btype.t & VT_BTYPE) == VT_STRUCT) && 
-            tok == ';') {
-            /* we accept no variable after */
-            next();
-            continue;
+            }
+        }
+        if (tok == ';') {
+	    if ((btype.t & VT_BTYPE) == VT_STRUCT) {
+		int v = btype.ref->v;
+		if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
+        	    tcc_warning("unnamed struct/union that defines no instances");
+                next();
+                continue;
+	    }
+            if (IS_ENUM(btype.t)) {
+                next();
+                continue;
+            }
         }
         while (1) { /* iterate thru each declaration */
-            char *asm_label; // associated asm label
             type = btype;
+	    /* If the base type itself was an array type of unspecified
+	       size (like in 'typedef int arr[]; arr x = {1};') then
+	       we will overwrite the unknown size by the real one for
+	       this decl.  We need to unshare the ref symbol holding
+	       that size.  */
+	    if ((type.t & VT_ARRAY) && type.ref->c < 0) {
+		type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
+	    }
             type_decl(&type, &ad, &v, TYPE_DIRECT);
 #if 0
             {
                 char buf[500];
-                type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
+                type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
                 printf("type = '%s'\n", buf);
             }
@@ -5652,75 +7213,52 @@
                    declaration list */
                 sym = type.ref;
-                if (sym->c == FUNC_OLD)
-                    func_decl_list(sym);
-            }
-
-            asm_label = NULL;
+                if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
+                    decl0(VT_CMP, 0, sym);
+            }
+
             if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
-                CString astr;
-
-                asm_label_instr(&astr);
-                asm_label = tcc_strdup(astr.data);
-                cstr_free(&astr);
-                
+                ad.asm_label = asm_label_instr();
                 /* parse one last attribute list, after asm label */
                 parse_attribute(&ad);
-            }
-
-            if (ad.weak)
-                type.t |= VT_WEAK;
+                if (tok == '{')
+                    expect(";");
+            }
+
 #ifdef TCC_TARGET_PE
-            if (ad.func_import)
-                type.t |= VT_IMPORT;
-            if (ad.func_export)
-                type.t |= VT_EXPORT;
+            if (ad.a.dllimport || ad.a.dllexport) {
+                if (type.t & (VT_STATIC|VT_TYPEDEF))
+                    tcc_error("cannot have dll linkage with static or typedef");
+                if (ad.a.dllimport) {
+                    if ((type.t & VT_BTYPE) == VT_FUNC)
+                        ad.a.dllimport = 0;
+                    else
+                        type.t |= VT_EXTERN;
+                }
+            }
 #endif
             if (tok == '{') {
-                if (l == VT_LOCAL)
+                if (l != VT_CONST)
                     tcc_error("cannot use local functions");
                 if ((type.t & VT_BTYPE) != VT_FUNC)
                     expect("function definition");
 
-                /* reject abstract declarators in function definition */
+                /* reject abstract declarators in function definition
+		   make old style params without decl have int type */
                 sym = type.ref;
-                while ((sym = sym->next) != NULL)
+                while ((sym = sym->next) != NULL) {
                     if (!(sym->v & ~SYM_FIELD))
-                       expect("identifier");
+                        expect("identifier");
+		    if (sym->type.t == VT_VOID)
+		        sym->type = int_type;
+		}
                 
                 /* XXX: cannot do better now: convert extern line to static inline */
                 if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
                     type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
-                
-                sym = sym_find(v);
-                if (sym) {
-                    if ((sym->type.t & VT_BTYPE) != VT_FUNC)
-                        goto func_error1;
-
-                    r = sym->type.ref->r;
-                    /* use func_call from prototype if not defined */
-                    if (FUNC_CALL(r) != FUNC_CDECL
-                     && FUNC_CALL(type.ref->r) == FUNC_CDECL)
-                        FUNC_CALL(type.ref->r) = FUNC_CALL(r);
-
-                    /* use export from prototype */
-                    if (FUNC_EXPORT(r))
-                        FUNC_EXPORT(type.ref->r) = 1;
-
-                    /* use static from prototype */
-                    if (sym->type.t & VT_STATIC)
-                        type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
-
-                    if (!is_compatible_types(&sym->type, &type)) {
-                    func_error1:
-                        tcc_error("incompatible types for redefinition of '%s'", 
-                              get_tok_str(v, NULL));
-                    }
-                    /* if symbol is already defined, then put complete type */
-                    sym->type = type;
-                } else {
-                    /* put function symbol */
-                    sym = global_identifier_push(v, type.t, 0);
-                    sym->type.ref = type.ref;
-                }
+
+                /* put function symbol */
+                sym = external_global_sym(v, &type, 0);
+                type.t &= ~VT_EXTERN;
+                patch_storage(sym, &ad, &type);
 
                 /* static inline functions are just recorded as a kind
@@ -5729,36 +7267,14 @@
                 if ((type.t & (VT_INLINE | VT_STATIC)) == 
                     (VT_INLINE | VT_STATIC)) {
-                    TokenString func_str;
-                    int block_level;
                     struct InlineFunc *fn;
                     const char *filename;
                            
-                    tok_str_new(&func_str);
-                    
-                    block_level = 0;
-                    for(;;) {
-                        int t;
-                        if (tok == TOK_EOF)
-                            tcc_error("unexpected end of file");
-                        tok_str_add_tok(&func_str);
-                        t = tok;
-                        next();
-                        if (t == '{') {
-                            block_level++;
-                        } else if (t == '}') {
-                            block_level--;
-                            if (block_level == 0)
-                                break;
-                        }
-                    }
-                    tok_str_add(&func_str, -1);
-                    tok_str_add(&func_str, 0);
                     filename = file ? file->filename : "";
                     fn = tcc_malloc(sizeof *fn + strlen(filename));
                     strcpy(fn->filename, filename);
                     fn->sym = sym;
-                    fn->token_str = func_str.str;
-                    dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn);
-
+		    skip_or_save_block(&fn->func_str);
+                    dynarray_add(&tcc_state->inline_fns,
+				 &tcc_state->nb_inline_fns, fn);
                 } else {
                     /* compute text section */
@@ -5766,14 +7282,39 @@
                     if (!cur_text_section)
                         cur_text_section = text_section;
-                    sym->r = VT_SYM | VT_CONST;
                     gen_function(sym);
                 }
                 break;
             } else {
-                if (btype.t & VT_TYPEDEF) {
+		if (l == VT_CMP) {
+		    /* find parameter in function parameter list */
+		    for (sym = func_sym->next; sym; sym = sym->next)
+			if ((sym->v & ~SYM_FIELD) == v)
+			    goto found;
+		    tcc_error("declaration for parameter '%s' but no such parameter",
+			      get_tok_str(v, NULL));
+found:
+		    if (type.t & VT_STORAGE) /* 'register' is okay */
+		        tcc_error("storage class specified for '%s'",
+				  get_tok_str(v, NULL));
+		    if (sym->type.t != VT_VOID)
+		        tcc_error("redefinition of parameter '%s'",
+				  get_tok_str(v, NULL));
+		    convert_parameter_type(&type);
+		    sym->type = type;
+		} else if (type.t & VT_TYPEDEF) {
                     /* save typedefed type  */
                     /* XXX: test storage specifiers ? */
-                    sym = sym_push(v, &type, INT_ATTR(&ad), 0);
-                    sym->type.t |= VT_TYPEDEF;
+                    sym = sym_find(v);
+                    if (sym && sym->sym_scope == local_scope) {
+                        if (!is_compatible_types(&sym->type, &type)
+                            || !(sym->type.t & VT_TYPEDEF))
+                            tcc_error("incompatible redefinition of '%s'",
+                                get_tok_str(v, NULL));
+                        sym->type = type;
+                    } else {
+                        sym = sym_push(v, &type, 0, 0);
+                    }
+                    sym->a = ad.a;
+                    sym->f = ad.f;
                 } else {
                     r = 0;
@@ -5781,5 +7322,5 @@
                         /* external function definition */
                         /* specific case for func_call attribute */
-                        type.ref->r = INT_ATTR(&ad);
+                        type.ref->f = ad.f;
                     } else if (!(type.t & VT_ARRAY)) {
                         /* not lvalue if array */
@@ -5788,6 +7329,7 @@
                     has_init = (tok == '=');
                     if (has_init && (type.t & VT_VLA))
-                        tcc_error("Variable length array cannot be initialized");
-                    if ((btype.t & VT_EXTERN) || ((type.t & VT_BTYPE) == VT_FUNC) ||
+                        tcc_error("variable length array cannot be initialized");
+                    if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
+			((type.t & VT_BTYPE) == VT_FUNC) ||
                         ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
                          !has_init && l == VT_CONST && type.ref->c < 0)) {
@@ -5796,23 +7338,19 @@
                            arrays of null size are considered as
                            extern */
-                        sym = external_sym(v, &type, r, asm_label);
-
-                        if (type.t & VT_WEAK)
-                            weaken_symbol(sym);
-
+                        type.t |= VT_EXTERN;
+                        sym = external_sym(v, &type, r, &ad);
                         if (ad.alias_target) {
-                            Section tsec;
-                            Elf32_Sym *esym;
+                            ElfSym *esym;
                             Sym *alias_target;
-
                             alias_target = sym_find(ad.alias_target);
-                            if (!alias_target || !alias_target->c)
+                            esym = elfsym(alias_target);
+                            if (!esym)
                                 tcc_error("unsupported forward __alias__ attribute");
-                            esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
-                            tsec.sh_num = esym->st_shndx;
-                            put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
+                            /* Local statics have a scope until now (for
+                               warnings), remove it here.  */
+                            sym->sym_scope = 0;
+                            put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
                         }
                     } else {
-                        type.t |= (btype.t & VT_STATIC); /* Retain "static". */
                         if (type.t & VT_STATIC)
                             r |= VT_CONST;
@@ -5821,5 +7359,8 @@
                         if (has_init)
                             next();
-                        decl_initializer_alloc(&type, &ad, r, has_init, v, asm_label, l);
+                        else if (l == VT_CONST)
+                            /* uninitialized global variables may be overridden */
+                            type.t |= VT_EXTERN;
+                        decl_initializer_alloc(&type, &ad, r, has_init, v, l);
                     }
                 }
@@ -5832,5 +7373,5 @@
                 next();
             }
-            ad.aligned = 0;
+            ad.a.aligned = 0;
         }
     }
@@ -5838,6 +7379,8 @@
 }
 
-ST_FUNC void decl(int l)
-{
-    decl0(l, 0);
-}
+static void decl(int l)
+{
+    decl0(l, 0, NULL);
+}
+
+/* ------------------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h	(revision 331)
@@ -0,0 +1,80 @@
+/* Simple libc header for TCC 
+ * 
+ * Add any function you want from the libc there. This file is here
+ * only for your convenience so that you do not need to put the whole
+ * glibc include files on your floppy disk 
+ */
+#ifndef _TCCLIB_H
+#define _TCCLIB_H
+
+#include <stddef.h>
+#include <stdarg.h>
+
+/* stdlib.h */
+void *calloc(size_t nmemb, size_t size);
+void *malloc(size_t size);
+void free(void *ptr);
+void *realloc(void *ptr, size_t size);
+int atoi(const char *nptr);
+long int strtol(const char *nptr, char **endptr, int base);
+unsigned long int strtoul(const char *nptr, char **endptr, int base);
+void exit(int);
+
+/* stdio.h */
+typedef struct __FILE FILE;
+#define EOF (-1)
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+FILE *fopen(const char *path, const char *mode);
+FILE *fdopen(int fildes, const char *mode);
+FILE *freopen(const  char *path, const char *mode, FILE *stream);
+int fclose(FILE *stream);
+size_t  fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t  fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
+int fgetc(FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+int getc(FILE *stream);
+int getchar(void);
+char *gets(char *s);
+int ungetc(int c, FILE *stream);
+int fflush(FILE *stream);
+int putchar (int c);
+
+int printf(const char *format, ...);
+int fprintf(FILE *stream, const char *format, ...);
+int sprintf(char *str, const char *format, ...);
+int snprintf(char *str, size_t size, const  char  *format, ...);
+int asprintf(char **strp, const char *format, ...);
+int dprintf(int fd, const char *format, ...);
+int vprintf(const char *format, va_list ap);
+int vfprintf(FILE  *stream,  const  char *format, va_list ap);
+int vsprintf(char *str, const char *format, va_list ap);
+int vsnprintf(char *str, size_t size, const char  *format, va_list ap);
+int vasprintf(char  **strp,  const  char *format, va_list ap);
+int vdprintf(int fd, const char *format, va_list ap);
+
+void perror(const char *s);
+
+/* string.h */
+char *strcat(char *dest, const char *src);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strcpy(char *dest, const char *src);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+char *strdup(const char *s);
+size_t strlen(const char *s);
+
+/* dlfcn.h */
+#define RTLD_LAZY       0x001
+#define RTLD_NOW        0x002
+#define RTLD_GLOBAL     0x100
+
+void *dlopen(const char *filename, int flag);
+const char *dlerror(void);
+void *dlsym(void *handle, char *symbol);
+int dlclose(void *handle);
+
+#endif /* _TCCLIB_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccpe.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c	(revision 331)
@@ -21,36 +21,42 @@
 #include "tcc.h"
 
+#define PE_MERGE_DATA
+/* #define PE_PRINT_SECTIONS */
+
 #ifndef _WIN32
 #define stricmp strcasecmp
 #define strnicmp strncasecmp
-#endif
-
-#ifndef MAX_PATH
-#define MAX_PATH 260
-#endif
-
-#define PE_MERGE_DATA
-// #define PE_PRINT_SECTIONS
+#include <sys/stat.h> /* chmod() */
+#endif
 
 #ifdef TCC_TARGET_X86_64
 # define ADDR3264 ULONGLONG
-#else
+# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
+# define REL_TYPE_DIRECT R_X86_64_64
+# define R_XXX_THUNKFIX R_X86_64_PC32
+# define R_XXX_RELATIVE R_X86_64_RELATIVE
+# define IMAGE_FILE_MACHINE 0x8664
+# define RSRC_RELTYPE 3
+
+#elif defined TCC_TARGET_ARM
 # define ADDR3264 DWORD
-#endif
-
-#ifdef _WIN32
-void dbg_printf (const char *fmt, ...)
-{
-    char buffer[4000];
-    va_list arg;
-    int x;
-    va_start(arg, fmt);
-    x = vsprintf (buffer, fmt, arg);
-    strcpy(buffer+x, "\n");
-    OutputDebugString(buffer);
-}
-#endif
-
-/* ----------------------------------------------------------- */
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_ARM_ABS32
+# define R_XXX_THUNKFIX R_ARM_ABS32
+# define R_XXX_RELATIVE R_ARM_RELATIVE
+# define IMAGE_FILE_MACHINE 0x01C0
+# define RSRC_RELTYPE 7 /* ??? (not tested) */
+
+#elif defined TCC_TARGET_I386
+# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_386_32
+# define R_XXX_THUNKFIX R_386_32
+# define R_XXX_RELATIVE R_386_RELATIVE
+# define IMAGE_FILE_MACHINE 0x014C
+# define RSRC_RELTYPE 7 /* DIR32NB */
+
+#endif
+
 #ifndef IMAGE_NT_SIGNATURE
 /* ----------------------------------------------------------- */
@@ -224,4 +230,5 @@
 #define IMAGE_REL_BASED_SECTION          6
 #define IMAGE_REL_BASED_REL32            7
+#define IMAGE_REL_BASED_DIR64           10
 
 #pragma pack(pop)
@@ -230,6 +237,10 @@
 #endif /* ndef IMAGE_NT_SIGNATURE */
 /* ----------------------------------------------------------- */
+
+#ifndef IMAGE_REL_BASED_DIR64
+# define IMAGE_REL_BASED_DIR64 10
+#endif
+
 #pragma pack(push, 1)
-
 struct pe_header
 {
@@ -264,5 +275,4 @@
     WORD type;
 };
-
 #pragma pack(pop)
 
@@ -337,4 +347,5 @@
     DWORD sizeofheaders;
     ADDR3264 imagebase;
+    const char *start_symbol;
     DWORD start_addr;
     DWORD imp_offs;
@@ -363,6 +374,6 @@
 static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
 {
-    const char *name = symtab_section->link->data + sym->st_name;
-    if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2))
+    const char *name = (char*)symtab_section->link->data + sym->st_name;
+    if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL))
         return name + 1;
     return name;
@@ -374,10 +385,12 @@
     const char *s, *p;
     int sym_index = 0, n = 0;
+    int a, err = 0;
 
     do {
         s = pe_export_name(s1, sym);
+        a = 0;
         if (n) {
             /* second try: */
-	    if (sym->st_other & 2) {
+	    if (sym->st_other & ST_PE_STDCALL) {
                 /* try w/0 stdcall deco (windows API convention) */
 	        p = strrchr(s, '@');
@@ -387,10 +400,10 @@
 	    } else if (s[0] != '_') { /* try non-ansi function */
 	        buffer[0] = '_', strcpy(buffer + 1, s);
-	    } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
-	        strcpy(buffer, s + 6);
-	    } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
-	        strcpy(buffer, s + 6);
+	    } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
+	        strcpy(buffer, s + 6), a = 1;
+	    } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
+	        strcpy(buffer, s + 6), a = 1;
 	    } else {
-	        break;
+	        continue;
 	    }
 	    s = buffer;
@@ -398,6 +411,11 @@
         sym_index = find_elf_sym(s1->dynsymtab_section, s);
         // printf("find (%d) %d %s\n", n, sym_index, s);
+        if (sym_index
+            && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT
+            && 0 == (sym->st_other & ST_PE_IMPORT)
+            && 0 == a
+            ) err = -1, sym_index = 0;
     } while (0 == sym_index && ++n < 2);
-    return sym_index;
+    return n == 2 ? err : sym_index;
 }
 
@@ -508,11 +526,5 @@
     {
     /* IMAGE_FILE_HEADER filehdr */
-#if defined(TCC_TARGET_I386)
-    0x014C,   /*WORD    Machine; */
-#elif defined(TCC_TARGET_X86_64)
-    0x8664,   /*WORD    Machine; */
-#elif defined(TCC_TARGET_ARM)
-    0x01C0,   /*WORD    Machine; */
-#endif
+    IMAGE_FILE_MACHINE, /*WORD    Machine; */
     0x0003, /*WORD    NumberOfSections; */
     0x00000000, /*DWORD   TimeDateStamp; */
@@ -623,5 +635,4 @@
             case sec_text:
                 pe_header.opthdr.BaseOfCode = addr;
-                pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
                 break;
 
@@ -664,5 +675,5 @@
         }
 
-        pstrcpy((char*)psh->Name, sizeof psh->Name, sh_name);
+        strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
 
         psh->Characteristics = pe_sec_flags[si->cls];
@@ -676,4 +687,8 @@
             file_offset = pe_file_align(pe, file_offset + si->data_size);
             psh->SizeOfRawData = file_offset - psh->PointerToRawData;
+            if (si->cls == sec_text)
+                pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
+            else
+                pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
         }
     }
@@ -681,4 +696,5 @@
     //pe_header.filehdr.TimeDateStamp = time(NULL);
     pe_header.filehdr.NumberOfSections = pe->sec_count;
+    pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
     pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
     pe_header.opthdr.ImageBase = pe->imagebase;
@@ -688,4 +704,5 @@
     if (PE_DLL == pe->type)
         pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
+    pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics;
 
     sum = 0;
@@ -708,4 +725,7 @@
     pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
     fclose (op);
+#ifndef _WIN32
+    chmod(pe->filename, 0777);
+#endif
 
     if (2 == pe->s1->verbose)
@@ -717,22 +737,4 @@
 }
 
-/*----------------------------------------------------------------------------*/
-
-#if defined(TCC_TARGET_X86_64)
-#define REL_TYPE_DIRECT R_X86_64_64
-#define R_XXX_THUNKFIX R_X86_64_PC32
-#define R_XXX_RELATIVE R_X86_64_RELATIVE
-
-#elif defined(TCC_TARGET_I386)
-#define REL_TYPE_DIRECT R_386_32
-#define R_XXX_THUNKFIX R_386_32
-#define R_XXX_RELATIVE R_386_RELATIVE
-
-#elif defined(TCC_TARGET_ARM)
-#define REL_TYPE_DIRECT R_ARM_ABS32
-#define R_XXX_THUNKFIX R_ARM_ABS32
-#define R_XXX_RELATIVE R_ARM_RELATIVE
-
-#endif
 /*----------------------------------------------------------------------------*/
 
@@ -755,5 +757,5 @@
     p = tcc_mallocz(sizeof *p);
     p->dll_index = dll_index;
-    dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
+    dynarray_add(&pe->imp_info, &pe->imp_count, p);
 
 found_dll:
@@ -763,7 +765,17 @@
 
     s = tcc_mallocz(sizeof *s);
-    dynarray_add((void***)&p->symbols, &p->sym_count, s);
+    dynarray_add(&p->symbols, &p->sym_count, s);
     s->sym_index = sym_index;
     return s;
+}
+
+void pe_free_imports(struct pe_info *pe)
+{
+    int i;
+    for (i = 0; i < pe->imp_count; ++i) {
+        struct pe_import_info *p = pe->imp_info[i];
+        dynarray_reset(&p->symbols, &p->sym_count);
+    }
+    dynarray_reset(&pe->imp_info, &pe->imp_count);
 }
 
@@ -819,26 +831,38 @@
                 ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
                 ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
-                const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
+                const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
+                int ordinal;
 
                 org_sym->st_value = thk_ptr;
                 org_sym->st_shndx = pe->thunk->sh_num;
-                v = pe->thunk->data_offset + rva_base;
-                section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
-                put_elf_str(pe->thunk, name);
+
+                if (dllref)
+                    v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
+                else
+                    ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */
+
 #ifdef TCC_IS_NATIVE
                 if (pe->type == PE_RUN) {
-                    v = imp_sym->st_value;
                     if (dllref) {
                         if ( !dllref->handle )
                             dllref->handle = LoadLibrary(dllref->name);
-                        v = (ADDR3264)GetProcAddress(dllref->handle, name);
+                        v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
                     }
                     if (!v)
-                        tcc_error_noabort("undefined symbol '%s'", name);
+                        tcc_error_noabort("can't build symbol '%s'", name);
+                } else
+#endif
+                if (ordinal) {
+                    v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1);
+                } else {
+                    v = pe->thunk->data_offset + rva_base;
+                    section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
+                    put_elf_str(pe->thunk, name);
                 }
-#endif
+
             } else {
                 v = 0; /* last entry is zero */
             }
+
             *(ADDR3264*)(pe->thunk->data+thk_ptr) =
             *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
@@ -847,7 +871,5 @@
         }
         dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
-        dynarray_reset(&p->symbols, &p->sym_count);
-    }
-    dynarray_reset(&pe->imp_info, &pe->imp_count);
+    }
 }
 
@@ -877,5 +899,5 @@
 
     FILE *op;
-    char buf[MAX_PATH];
+    char buf[260];
     const char *dllname;
     const char *name;
@@ -888,5 +910,5 @@
         sym = (ElfW(Sym)*)symtab_section->data + sym_index;
         name = pe_export_name(pe->s1, sym);
-        if ((sym->st_other & 1)
+        if ((sym->st_other & ST_PE_EXPORT)
             /* export only symbols from actually written sections */
             && pe->s1->sections[sym->st_shndx]->sh_addr) {
@@ -894,10 +916,10 @@
             p->index = sym_index;
             p->name = name;
-            dynarray_add((void***)&sorted, &sym_count, p);
+            dynarray_add(&sorted, &sym_count, p);
         }
 #if 0
-        if (sym->st_other & 1)
+        if (sym->st_other & ST_PE_EXPORT)
             printf("export: %s\n", name);
-        if (sym->st_other & 2)
+        if (sym->st_other & ST_PE_STDCALL)
             printf("stdcall: %s\n", name);
 #endif
@@ -933,5 +955,5 @@
     pstrcpy(buf, sizeof buf, pe->filename);
     strcpy(tcc_fileextension(buf), ".def");
-    op = fopen(buf, "w");
+    op = fopen(buf, "wb");
     if (NULL == op) {
         tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
@@ -939,5 +961,5 @@
         fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
         if (pe->s1->verbose)
-            printf("<- %s (%d symbols)\n", buf, sym_count);
+            printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]);
     }
 #endif
@@ -946,5 +968,5 @@
     {
         p = sorted[ord], sym_index = p->index, name = p->name;
-        /* insert actual address later in pe_relocate_rva */
+        /* insert actual address later in relocate_section() */
         put_elf_reloc(symtab_section, pe->thunk,
             func_o, R_XXX_RELATIVE, sym_index);
@@ -991,5 +1013,5 @@
             if ((addr -= offset)  < (1<<12)) { /* one block spans 4k addresses */
                 WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
-                *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
+                *wp = addr | PE_IMAGE_REL<<12;
                 ++count;
                 continue;
@@ -1065,4 +1087,7 @@
     Section *s;
 
+    if (PE_DLL == pe->type)
+        pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0);
+
     // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
 
@@ -1157,24 +1182,4 @@
 }
 
-/* ------------------------------------------------------------- */
-static void pe_relocate_rva (struct pe_info *pe, Section *s)
-{
-    Section *sr = s->reloc;
-    ElfW_Rel *rel, *rel_end;
-    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-    for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
-        if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) {
-            int sym_index = ELFW(R_SYM)(rel->r_info);
-            DWORD addr = s->sh_addr;
-            if (sym_index) {
-                ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
-                addr = sym->st_value;
-            }
-            // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, s->name);
-            *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
-        }
-    }
-}
-
 /*----------------------------------------------------------------------------*/
 
@@ -1208,10 +1213,10 @@
         if (sym->st_shndx == SHN_UNDEF) {
 
-            const char *name = symtab_section->link->data + sym->st_name;
+            const char *name = (char*)symtab_section->link->data + sym->st_name;
             unsigned type = ELFW(ST_TYPE)(sym->st_info);
             int imp_sym = pe_find_import(pe->s1, sym);
             struct import_symbol *is;
 
-            if (0 == imp_sym)
+            if (imp_sym <= 0)
                 goto not_found;
 
@@ -1271,5 +1276,5 @@
                 sym->st_value = offset;
                 sym->st_shndx = text_section->sh_num;
-                sym->st_other &= ~1; /* do not export */
+                sym->st_other &= ~ST_PE_EXPORT; /* do not export */
                 continue;
             }
@@ -1284,5 +1289,9 @@
 
         not_found:
-            tcc_error_noabort("undefined symbol '%s'", name);
+            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+                /* STB_WEAK undefined symbols are accepted */
+                continue;
+            tcc_error_noabort("undefined symbol '%s'%s", name,
+                imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
             ret = -1;
 
@@ -1290,5 +1299,5 @@
                    && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
             /* if -rdynamic option, then export all non local symbols */
-            sym->st_other |= 1;
+            sym->st_other |= ST_PE_EXPORT;
         }
     }
@@ -1300,5 +1309,5 @@
 static void pe_print_section(FILE * f, Section * s)
 {
-    /* just if you'r curious */
+    /* just if you're curious */
     BYTE *p, *e, b;
     int i, n, l, m;
@@ -1438,23 +1447,13 @@
 /* helper function for load/store to insert one more indirection */
 
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
 {
-    Sym *sym;
-    ElfW(Sym) *esym;
     int r2;
-
     if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
         return sv;
-    sym = sv->sym;
-    if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN)
+    if (!sv->sym->a.dllimport)
         return sv;
-    if (!sym->c)
-        put_extern_sym(sym, NULL, 0, 0);
-    esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
-    if (!(esym->st_other & 4))
-        return sv;
-
-    // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
-
+    // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
     memset(v2, 0, sizeof *v2);
     v2->type.t = VT_PTR;
@@ -1465,20 +1464,19 @@
     load(r2, v2);
     v2->r = r2;
-
-    if (sv->c.ui) {
+    if ((uint32_t)sv->c.i) {
         vpushv(v2);
-        vpushi(sv->c.ui);
+        vpushi(sv->c.i);
         gen_opi('+');
         *v2 = *vtop--;
     }
-
     v2->type.t = sv->type.t;
     v2->r |= sv->r & VT_LVAL;
     return v2;
 }
+#endif
 
 ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
 {
-    return add_elf_sym(
+    return set_elf_sym(
         s1->dynsymtab_section,
         value,
@@ -1500,5 +1498,5 @@
     dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
     strcpy(dllref->name, dllname);
-    dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
     return s1->nb_loaded_dlls;
 }
@@ -1510,4 +1508,99 @@
     lseek(fd, offset, SEEK_SET);
     return len == read(fd, buffer, len);
+}
+
+/* ------------------------------------------------------------- */
+
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
+{
+    int l, i, n, n0, ret;
+    char *p;
+    int fd;
+
+    IMAGE_SECTION_HEADER ish;
+    IMAGE_EXPORT_DIRECTORY ied;
+    IMAGE_DOS_HEADER dh;
+    IMAGE_FILE_HEADER ih;
+    DWORD sig, ref, addr, ptr, namep;
+
+    int pef_hdroffset, opt_hdroffset, sec_hdroffset;
+
+    n = n0 = 0;
+    p = NULL;
+    ret = -1;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        goto the_end_1;
+    ret = 1;
+    if (!read_mem(fd, 0, &dh, sizeof dh))
+        goto the_end;
+    if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
+        goto the_end;
+    if (sig != 0x00004550)
+        goto the_end;
+    pef_hdroffset = dh.e_lfanew + sizeof sig;
+    if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
+        goto the_end;
+    opt_hdroffset = pef_hdroffset + sizeof ih;
+    if (ih.Machine == 0x014C) {
+        IMAGE_OPTIONAL_HEADER32 oh;
+        sec_hdroffset = opt_hdroffset + sizeof oh;
+        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+            goto the_end;
+        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+            goto the_end_0;
+        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+    } else if (ih.Machine == 0x8664) {
+        IMAGE_OPTIONAL_HEADER64 oh;
+        sec_hdroffset = opt_hdroffset + sizeof oh;
+        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+            goto the_end;
+        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+            goto the_end_0;
+        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+    } else
+        goto the_end;
+
+    //printf("addr: %08x\n", addr);
+    for (i = 0; i < ih.NumberOfSections; ++i) {
+        if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
+            goto the_end;
+        //printf("vaddr: %08x\n", ish.VirtualAddress);
+        if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
+            goto found;
+    }
+    goto the_end_0;
+
+found:
+    ref = ish.VirtualAddress - ish.PointerToRawData;
+    if (!read_mem(fd, addr - ref, &ied, sizeof ied))
+        goto the_end;
+
+    namep = ied.AddressOfNames - ref;
+    for (i = 0; i < ied.NumberOfNames; ++i) {
+        if (!read_mem(fd, namep, &ptr, sizeof ptr))
+            goto the_end;
+        namep += sizeof ptr;
+        for (l = 0;;) {
+            if (n+1 >= n0)
+                p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
+            if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
+                tcc_free(p), p = NULL;
+                goto the_end;
+            }
+            if (p[n++] == 0)
+                break;
+        }
+    }
+    if (p)
+        p[n] = 0;
+the_end_0:
+    ret = 0;
+the_end:
+    close(fd);
+the_end_1:
+    *pp = p;
+    return ret;
 }
 
@@ -1521,5 +1614,5 @@
     struct pe_rsrc_header hdr;
     Section *rsrc_section;
-    int i, ret = -1;
+    int i, ret = -1, sym_index;
     BYTE *ptr;
     unsigned offs;
@@ -1528,7 +1621,7 @@
         goto quit;
 
-    if (hdr.filehdr.Machine != 0x014C
+    if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE
         || hdr.filehdr.NumberOfSections != 1
-        || strcmp(hdr.sectionhdr.Name, ".rsrc") != 0)
+        || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0)
         goto quit;
 
@@ -1539,14 +1632,14 @@
         goto quit;
     offs = hdr.sectionhdr.PointerToRelocations;
-    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
-    {
+    sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, ".rsrc");
+    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) {
         struct pe_rsrc_reloc rel;
         if (!read_mem(fd, offs, &rel, sizeof rel))
             goto quit;
         // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
-        if (rel.type != 7) /* DIR32NB */
+        if (rel.type != RSRC_RELTYPE)
             goto quit;
         put_elf_reloc(symtab_section, rsrc_section,
-            rel.offset, R_XXX_RELATIVE, 0);
+            rel.offset, R_XXX_RELATIVE, sym_index);
         offs += sizeof rel;
     }
@@ -1557,8 +1650,9 @@
 
 /* ------------------------------------------------------------- */
+
 static char *trimfront(char *p)
 {
     while (*p && (unsigned char)*p <= ' ')
-        ++p;
+	++p;
     return p;
 }
@@ -1567,33 +1661,23 @@
 {
     while (e > a && (unsigned char)e[-1] <= ' ')
-        --e;
+	--e;
     *e = 0;;
     return a;
 }
 
-static char *get_line(char *line, int size, int fd)
-{
-    int n;
-    for (n = 0; n < size - 1; )
-        if (read(fd, line + n, 1) < 1 || line[n++] == '\n')
-            break;
-    if (0 == n)
-        return NULL;
-    trimback(line, line + n);
-    return trimfront(line);
-}
-
 /* ------------------------------------------------------------- */
 static int pe_load_def(TCCState *s1, int fd)
 {
-    int state = 0, ret = -1, dllindex = 0;
-    char line[400], dllname[80], *p;
-
-    for (;;) {
-        p = get_line(line, sizeof line, fd);
-        if (NULL == p)
-            break;
+    int state = 0, ret = -1, dllindex = 0, ord;
+    char line[400], dllname[80], *p, *x;
+    FILE *fp;
+
+    fp = fdopen(dup(fd), "rb");
+    while (fgets(line, sizeof line, fp))
+    {
+        p = trimfront(trimback(line, strchr(line, 0)));
         if (0 == *p || ';' == *p)
             continue;
+
         switch (state) {
         case 0:
@@ -1613,7 +1697,19 @@
             dllindex = add_dllref(s1, dllname);
             ++state;
-
+            /* fall through */
         default:
-            pe_putimport(s1, dllindex, p, 0);
+            /* get ordinal and will store in sym->st_value */
+            ord = 0;
+            x = strchr(p, ' ');
+            if (x) {
+                *x = 0, x = strrchr(x + 1, '@');
+                if (x) {
+                    char *d;
+                    ord = (int)strtol(x + 1, &d, 10);
+                    if (*d)
+                        ord = 0;
+                }
+            }
+            pe_putimport(s1, dllindex, p, ord);
             continue;
         }
@@ -1621,22 +1717,23 @@
     ret = 0;
 quit:
+    fclose(fp);
     return ret;
 }
 
 /* ------------------------------------------------------------- */
-#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
-#include "win32/tools/tiny_impdef.c"
-
-static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
+static int pe_load_dll(TCCState *s1, const char *filename)
 {
     char *p, *q;
-    int index;
-    p = get_export_names(fd);
-    if (!p)
+    int index, ret;
+
+    ret = tcc_get_dllexports(filename, &p);
+    if (ret) {
         return -1;
-    index = add_dllref(s1, dllname);
-    for (q = p; *q; q += 1 + strlen(q))
-        pe_putimport(s1, index, q, 0);
-    tcc_free(p);
+    } else if (p) {
+        index = add_dllref(s1, tcc_basename(filename));
+        for (q = p; *q; q += 1 + strlen(q))
+            pe_putimport(s1, index, q, 0);
+        tcc_free(p);
+    }
     return 0;
 }
@@ -1651,6 +1748,6 @@
     else if (pe_load_res(s1, fd) == 0)
         ret = 0;
-    else if (read_mem(fd, 0, buf, sizeof buf) && 0 == strncmp(buf, "MZ", 2))
-        ret = pe_load_dll(s1, tcc_basename(filename), fd);
+    else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
+        ret = pe_load_dll(s1, filename);
     return ret;
 }
@@ -1663,7 +1760,7 @@
         s1->uw_pdata = find_section(tcc_state, ".pdata");
         s1->uw_pdata->sh_addralign = 4;
-        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, NULL);
-    }
-
+    }
+    if (0 == s1->uw_sym)
+        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, ".uw_base");
     if (0 == s1->uw_offs) {
         /* As our functions all have the same stackframe, we use one entry for all */
@@ -1714,5 +1811,5 @@
     /* put relocations on it */
     for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
-        put_elf_reloc(symtab_section, pd, o,  R_X86_64_RELATIVE, s1->uw_sym);
+        put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
 }
 #endif
@@ -1727,9 +1824,14 @@
 {
     const char *start_symbol;
-    ADDR3264 addr = 0;
     int pe_type = 0;
+    int unicode_entry = 0;
 
     if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
         pe_type = PE_GUI;
+    else
+    if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
+        pe_type = PE_GUI;
+        unicode_entry = PE_GUI;
+    }
     else
     if (TCC_OUTPUT_DLL == s1->output_type) {
@@ -1738,30 +1840,36 @@
         s1->output_type = TCC_OUTPUT_EXE;
     }
-    else
+    else {
         pe_type = PE_EXE;
+        if (find_elf_sym(symtab_section, "wmain"))
+            unicode_entry = PE_EXE;
+    }
 
     start_symbol =
         TCC_OUTPUT_MEMORY == s1->output_type
-        ? PE_GUI == pe_type ? "__runwinmain" : "_main"
+        ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
+            : (unicode_entry ? "__runwmain" : "__runmain")
         : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
-        : PE_GUI == pe_type ? "__winstart" : "__start"
+            : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
+                : (unicode_entry ? "__wstart" : "__start")
         ;
 
-    if (!s1->leading_underscore || strchr(start_symbol, '@')) {
+    if (!s1->leading_underscore || strchr(start_symbol, '@'))
         ++start_symbol;
-        if (start_symbol[0] != '_')
-            start_symbol = NULL;
-    }
 
     /* grab the startup code from libtcc1 */
-    if (start_symbol)
-        add_elf_sym(symtab_section,
-            0, 0,
-            ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
-            SHN_UNDEF, start_symbol);
+#ifdef TCC_IS_NATIVE
+    if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
+#endif
+    set_elf_sym(symtab_section,
+        0, 0,
+        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+        SHN_UNDEF, start_symbol);
+
+    tcc_add_pragma_libs(s1);
 
     if (0 == s1->nostdlib) {
         static const char *libs[] = {
-            "libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
+            TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
         };
         const char **pp, *p;
@@ -1770,7 +1878,8 @@
                 if (PE_DLL != pe_type && PE_GUI != pe_type)
                     break;
-            } else if (pp == libs ? tcc_add_dll(s1, p, 0) : tcc_add_library(s1, p)) {
-                tcc_error_noabort("cannot find library: %s", p);
-                break;
+            } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
+                continue;
+            } else {
+                tcc_add_library_err(s1, p);
             }
         }
@@ -1779,20 +1888,56 @@
     if (TCC_OUTPUT_MEMORY == s1->output_type)
         pe_type = PE_RUN;
-
-    if (start_symbol) {
-        addr = get_elf_sym_addr(s1, start_symbol, 1);
-        if (PE_RUN == pe_type && addr)
-            /* for -run GUI's, put '_runwinmain' instead of 'main' */
-            add_elf_sym(symtab_section,
-                    addr, 0,
-                    ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
-                    text_section->sh_num, "main");
-    }
-
     pe->type = pe_type;
-    pe->start_addr = addr;
-}
-
-ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
+    pe->start_symbol = start_symbol;
+}
+
+static void pe_set_options(TCCState * s1, struct pe_info *pe)
+{
+    if (PE_DLL == pe->type) {
+        /* XXX: check if is correct for arm-pe target */
+        pe->imagebase = 0x10000000;
+    } else {
+#if defined(TCC_TARGET_ARM)
+        pe->imagebase = 0x00010000;
+#else
+        pe->imagebase = 0x00400000;
+#endif
+    }
+
+#if defined(TCC_TARGET_ARM)
+    /* we use "console" subsystem by default */
+    pe->subsystem = 9;
+#else
+    if (PE_DLL == pe->type || PE_GUI == pe->type)
+        pe->subsystem = 2;
+    else
+        pe->subsystem = 3;
+#endif
+    /* Allow override via -Wl,-subsystem=... option */
+    if (s1->pe_subsystem != 0)
+        pe->subsystem = s1->pe_subsystem;
+
+    /* set default file/section alignment */
+    if (pe->subsystem == 1) {
+        pe->section_align = 0x20;
+        pe->file_align = 0x20;
+    } else {
+        pe->section_align = 0x1000;
+        pe->file_align = 0x200;
+    }
+
+    if (s1->section_align != 0)
+        pe->section_align = s1->section_align;
+    if (s1->pe_file_align != 0)
+        pe->file_align = s1->pe_file_align;
+
+    if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
+        pe->imagebase = 0;
+
+    if (s1->has_text_addr)
+        pe->imagebase = s1->text_addr;
+}
+
+ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
 {
     int ret;
@@ -1806,6 +1951,6 @@
     tcc_add_bcheck(s1);
     pe_add_runtime(s1, &pe);
-    relocate_common_syms(); /* assign bss adresses */
-    tcc_add_linker_symbols(s1);
+    resolve_common_syms(s1);
+    pe_set_options(s1, &pe);
 
     ret = pe_check_symbols(&pe);
@@ -1813,58 +1958,16 @@
         ;
     else if (filename) {
-        if (PE_DLL == pe.type) {
-            pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
-            /* XXX: check if is correct for arm-pe target */
-            pe.imagebase = 0x10000000;
-        } else {
-#if defined(TCC_TARGET_ARM)
-            pe.imagebase = 0x00010000;
-#else
-            pe.imagebase = 0x00400000;
-#endif
-        }
-
-#if defined(TCC_TARGET_ARM)
-        /* we use "console" subsystem by default */
-        pe.subsystem = 9;
-#else
-        if (PE_DLL == pe.type || PE_GUI == pe.type)
-            pe.subsystem = 2;
-        else
-            pe.subsystem = 3;
-#endif
-        /* Allow override via -Wl,-subsystem=... option */
-        if (s1->pe_subsystem != 0)
-            pe.subsystem = s1->pe_subsystem;
-
-        /* set default file/section alignment */
-	if (pe.subsystem == 1) {
-	    pe.section_align = 0x20;
-	    pe.file_align = 0x20;
-	} else {
-	    pe.section_align = 0x1000;
-	    pe.file_align = 0x200;
-	}
-
-        if (s1->section_align != 0)
-            pe.section_align = s1->section_align;
-        if (s1->pe_file_align != 0)
-            pe.file_align = s1->pe_file_align;
-
-        if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
-            pe.imagebase = 0;
-
-        if (s1->has_text_addr)
-            pe.imagebase = s1->text_addr;
-
         pe_assign_addresses(&pe);
-        relocate_syms(s1, 0);
+        relocate_syms(s1, s1->symtab, 0);
+        s1->pe_imagebase = pe.imagebase;
         for (i = 1; i < s1->nb_sections; ++i) {
             Section *s = s1->sections[i];
             if (s->reloc) {
                 relocate_section(s1, s);
-                pe_relocate_rva(&pe, s);
             }
         }
+        pe.start_addr = (DWORD)
+            ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
+                - pe.imagebase);
         if (s1->nb_errors)
             ret = -1;
@@ -1876,6 +1979,12 @@
         pe.thunk = data_section;
         pe_build_imports(&pe);
-#endif
-    }
+        s1->runtime_main = pe.start_symbol;
+#ifdef TCC_TARGET_X86_64
+        s1->uw_pdata = find_section(s1, ".pdata");
+#endif
+#endif
+    }
+
+    pe_free_imports(&pe);
 
 #ifdef PE_PRINT_SECTIONS
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccpp.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c	(revision 331)
@@ -25,18 +25,5 @@
 
 ST_DATA int tok_flags;
-/* additional informations about token */
-#define TOK_FLAG_BOL   0x0001 /* beginning of line before */
-#define TOK_FLAG_BOF   0x0002 /* beginning of file before */
-#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
-#define TOK_FLAG_EOF   0x0008 /* end of file */
-
 ST_DATA int parse_flags;
-#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
-#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
-#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
-                                        token. line feed is also
-                                        returned at eof */
-#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
-#define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
 
 ST_DATA struct BufferedFile *file;
@@ -54,12 +41,21 @@
 /* ------------------------------------------------------------------------- */
 
-static int *macro_ptr_allocated;
-static const int *unget_saved_macro_ptr;
-static int unget_saved_buffer[TOK_MAX_SIZE + 1];
-static int unget_buffer_enabled;
 static TokenSym *hash_ident[TOK_HASH_SIZE];
 static char token_buf[STRING_MAX_SIZE + 1];
-/* true if isid(c) || isnum(c) */
-static unsigned char isidnum_table[256-CH_EOF];
+static CString cstr_buf;
+static CString macro_equal_buf;
+static TokenString tokstr_buf;
+static unsigned char isidnum_table[256 - CH_EOF];
+static int pp_debug_tok, pp_debug_symv;
+static int pp_once;
+static int pp_expr;
+static int pp_counter;
+static void tok_print(const char *msg, const int *str);
+
+static struct TinyAlloc *toksym_alloc;
+static struct TinyAlloc *tokstr_alloc;
+static struct TinyAlloc *cstr_alloc;
+
+static TokenString *macro_stack;
 
 static const char tcc_keywords[] = 
@@ -71,20 +67,33 @@
 /* WARNING: the content of this string encodes token numbers */
 static const unsigned char tok_two_chars[] =
+/* outdated -- gr
     "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
     "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
-
-struct macro_level {
-    struct macro_level *prev;
-    const int *p;
+*/{
+    '<','=', TOK_LE,
+    '>','=', TOK_GE,
+    '!','=', TOK_NE,
+    '&','&', TOK_LAND,
+    '|','|', TOK_LOR,
+    '+','+', TOK_INC,
+    '-','-', TOK_DEC,
+    '=','=', TOK_EQ,
+    '<','<', TOK_SHL,
+    '>','>', TOK_SAR,
+    '+','=', TOK_A_ADD,
+    '-','=', TOK_A_SUB,
+    '*','=', TOK_A_MUL,
+    '/','=', TOK_A_DIV,
+    '%','=', TOK_A_MOD,
+    '&','=', TOK_A_AND,
+    '^','=', TOK_A_XOR,
+    '|','=', TOK_A_OR,
+    '-','>', TOK_ARROW,
+    '.','.', TOK_TWODOTS,
+    '#','#', TOK_TWOSHARPS,
+    0
 };
 
-ST_FUNC void next_nomacro(void);
 static void next_nomacro_spc(void);
-static void macro_subst(
-    TokenString *tok_str,
-    Sym **nested_list,
-    const int *macro_str,
-    struct macro_level **can_read_stream
-    );
 
 ST_FUNC void skip(int c)
@@ -101,23 +110,232 @@
 
 /* ------------------------------------------------------------------------- */
+/* Custom allocator for tiny objects */
+
+//#define USE_TAL
+
+#ifndef USE_TAL
+#define tal_free(al, p) tcc_free(p)
+#define tal_realloc(al, p, size) tcc_realloc(p, size)
+#define tal_new(a,b,c)
+#define tal_delete(a)
+#else
+#if !defined(MEM_DEBUG)
+#define tal_free(al, p) tal_free_impl(al, p)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
+#define TAL_DEBUG_PARAMS
+#else
+#define TAL_DEBUG 1
+//#define TAL_INFO 1 /* collect and dump allocators stats */
+#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
+#define TAL_DEBUG_PARAMS , const char *file, int line
+#define TAL_DEBUG_FILE_LEN 40
+#endif
+
+#define TOKSYM_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenSym in table_ident */
+#define TOKSTR_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenString instances */
+#define CSTR_TAL_SIZE       (256 * 1024) /* allocator for tiny CString instances */
+#define TOKSYM_TAL_LIMIT    256 /* prefer unique limits to distinguish allocators debug msgs */
+#define TOKSTR_TAL_LIMIT    128 /* 32 * sizeof(int) */
+#define CSTR_TAL_LIMIT      1024
+
+typedef struct TinyAlloc {
+    unsigned  limit;
+    unsigned  size;
+    uint8_t *buffer;
+    uint8_t *p;
+    unsigned  nb_allocs;
+    struct TinyAlloc *next, *top;
+#ifdef TAL_INFO
+    unsigned  nb_peak;
+    unsigned  nb_total;
+    unsigned  nb_missed;
+    uint8_t *peak_p;
+#endif
+} TinyAlloc;
+
+typedef struct tal_header_t {
+    unsigned  size;
+#ifdef TAL_DEBUG
+    int     line_num; /* negative line_num used for double free check */
+    char    file_name[TAL_DEBUG_FILE_LEN + 1];
+#endif
+} tal_header_t;
+
+/* ------------------------------------------------------------------------- */
+
+static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
+{
+    TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
+    al->p = al->buffer = tcc_malloc(size);
+    al->limit = limit;
+    al->size = size;
+    if (pal) *pal = al;
+    return al;
+}
+
+static void tal_delete(TinyAlloc *al)
+{
+    TinyAlloc *next;
+
+tail_call:
+    if (!al)
+        return;
+#ifdef TAL_INFO
+    fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
+            al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
+            (al->peak_p - al->buffer) * 100.0 / al->size);
+#endif
+#ifdef TAL_DEBUG
+    if (al->nb_allocs > 0) {
+        uint8_t *p;
+        fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
+                al->nb_allocs, al->limit);
+        p = al->buffer;
+        while (p < al->p) {
+            tal_header_t *header = (tal_header_t *)p;
+            if (header->line_num > 0) {
+                fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
+                        header->file_name, header->line_num, header->size);
+            }
+            p += header->size + sizeof(tal_header_t);
+        }
+#if MEM_DEBUG-0 == 2
+        exit(2);
+#endif
+    }
+#endif
+    next = al->next;
+    tcc_free(al->buffer);
+    tcc_free(al);
+    al = next;
+    goto tail_call;
+}
+
+static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
+{
+    if (!p)
+        return;
+tail_call:
+    if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
+#ifdef TAL_DEBUG
+        tal_header_t *header = (((tal_header_t *)p) - 1);
+        if (header->line_num < 0) {
+            fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
+                    file, line);
+            fprintf(stderr, "%s:%d: %d bytes\n",
+                    header->file_name, (int)-header->line_num, (int)header->size);
+        } else
+            header->line_num = -header->line_num;
+#endif
+        al->nb_allocs--;
+        if (!al->nb_allocs)
+            al->p = al->buffer;
+    } else if (al->next) {
+        al = al->next;
+        goto tail_call;
+    }
+    else
+        tcc_free(p);
+}
+
+static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
+{
+    tal_header_t *header;
+    void *ret;
+    int is_own;
+    unsigned adj_size = (size + 3) & -4;
+    TinyAlloc *al = *pal;
+
+tail_call:
+    is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
+    if ((!p || is_own) && size <= al->limit) {
+        if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) {
+            header = (tal_header_t *)al->p;
+            header->size = adj_size;
+#ifdef TAL_DEBUG
+            { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
+            strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
+            header->file_name[TAL_DEBUG_FILE_LEN] = 0;
+            header->line_num = line; }
+#endif
+            ret = al->p + sizeof(tal_header_t);
+            al->p += adj_size + sizeof(tal_header_t);
+            if (is_own) {
+                header = (((tal_header_t *)p) - 1);
+                memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+                header->line_num = -header->line_num;
+#endif
+            } else {
+                al->nb_allocs++;
+            }
+#ifdef TAL_INFO
+            if (al->nb_peak < al->nb_allocs)
+                al->nb_peak = al->nb_allocs;
+            if (al->peak_p < al->p)
+                al->peak_p = al->p;
+            al->nb_total++;
+#endif
+            return ret;
+        } else if (is_own) {
+            al->nb_allocs--;
+            ret = tal_realloc(*pal, 0, size);
+            header = (((tal_header_t *)p) - 1);
+            memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+            header->line_num = -header->line_num;
+#endif
+            return ret;
+        }
+        if (al->next) {
+            al = al->next;
+        } else {
+            TinyAlloc *bottom = al, *next = al->top ? al->top : al;
+
+            al = tal_new(pal, next->limit, next->size * 2);
+            al->next = next;
+            bottom->top = al;
+        }
+        goto tail_call;
+    }
+    if (is_own) {
+        al->nb_allocs--;
+        ret = tcc_malloc(size);
+        header = (((tal_header_t *)p) - 1);
+        memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+        header->line_num = -header->line_num;
+#endif
+    } else if (al->next) {
+        al = al->next;
+        goto tail_call;
+    } else
+        ret = tcc_realloc(p, size);
+#ifdef TAL_INFO
+    al->nb_missed++;
+#endif
+    return ret;
+}
+
+#endif /* USE_TAL */
+
+/* ------------------------------------------------------------------------- */
 /* CString handling */
 static void cstr_realloc(CString *cstr, int new_size)
 {
     int size;
-    void *data;
 
     size = cstr->size_allocated;
-    if (size == 0)
+    if (size < 8)
         size = 8; /* no need to allocate a too small first string */
     while (size < new_size)
         size = size * 2;
-    data = tcc_realloc(cstr->data_allocated, size);
-    cstr->data_allocated = data;
+    cstr->data = tal_realloc(cstr_alloc, cstr->data, size);
     cstr->size_allocated = size;
-    cstr->data = data;
 }
 
 /* add a byte */
-ST_FUNC void cstr_ccat(CString *cstr, int ch)
+ST_INLN void cstr_ccat(CString *cstr, int ch)
 {
     int size;
@@ -129,14 +347,14 @@
 }
 
-ST_FUNC void cstr_cat(CString *cstr, const char *str)
-{
-    int c;
-    for(;;) {
-        c = *str;
-        if (c == '\0')
-            break;
-        cstr_ccat(cstr, c);
-        str++;
-    }
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
+{
+    int size;
+    if (len <= 0)
+        len = strlen(str) + 1 + len;
+    size = cstr->size + len;
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
+    cstr->size = size;
 }
 
@@ -160,5 +378,5 @@
 ST_FUNC void cstr_free(CString *cstr)
 {
-    tcc_free(cstr->data_allocated);
+    tal_free(cstr_alloc, cstr->data);
     cstr_new(cstr);
 }
@@ -199,5 +417,5 @@
 
     if (tok_ident >= SYM_FIRST_ANOM) 
-        tcc_error("memory full");
+        tcc_error("memory full (symbols)");
 
     /* expand token table if needed */
@@ -208,5 +426,5 @@
     }
 
-    ts = tcc_malloc(sizeof(TokenSym) + len);
+    ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
     table_ident[i] = ts;
     ts->tok = tok_ident++;
@@ -224,5 +442,6 @@
 
 #define TOK_HASH_INIT 1
-#define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
+#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))
+
 
 /* find a token and add it if not found */
@@ -252,31 +471,24 @@
 /* XXX: buffer overflow */
 /* XXX: float tokens */
-ST_FUNC char *get_tok_str(int v, CValue *cv)
-{
-    static char buf[STRING_MAX_SIZE + 1];
-    static CString cstr_buf;
-    CString *cstr;
+ST_FUNC const char *get_tok_str(int v, CValue *cv)
+{
     char *p;
     int i, len;
 
-    /* NOTE: to go faster, we give a fixed buffer for small strings */
     cstr_reset(&cstr_buf);
-    cstr_buf.data = buf;
-    cstr_buf.size_allocated = sizeof(buf);
-    p = buf;
+    p = cstr_buf.data;
 
     switch(v) {
     case TOK_CINT:
     case TOK_CUINT:
-        /* XXX: not quite exact, but only useful for testing */
-        sprintf(p, "%u", cv->ui);
-        break;
+    case TOK_CLONG:
+    case TOK_CULONG:
     case TOK_CLLONG:
     case TOK_CULLONG:
         /* XXX: not quite exact, but only useful for testing  */
 #ifdef _WIN32
-        sprintf(p, "%u", (unsigned)cv->ull);
+        sprintf(p, "%u", (unsigned)cv->i);
 #else
-        sprintf(p, "%Lu", cv->ull);
+        sprintf(p, "%llu", (unsigned long long)cv->i);
 #endif
         break;
@@ -290,27 +502,37 @@
         break;
     case TOK_PPNUM:
-        cstr = cv->cstr;
-        len = cstr->size - 1;
-        for(i=0;i<len;i++)
-            add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
-        cstr_ccat(&cstr_buf, '\0');
-        break;
+    case TOK_PPSTR:
+        return (char*)cv->str.data;
     case TOK_LSTR:
         cstr_ccat(&cstr_buf, 'L');
     case TOK_STR:
-        cstr = cv->cstr;
         cstr_ccat(&cstr_buf, '\"');
         if (v == TOK_STR) {
-            len = cstr->size - 1;
+            len = cv->str.size - 1;
             for(i=0;i<len;i++)
-                add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
+                add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
         } else {
-            len = (cstr->size / sizeof(nwchar_t)) - 1;
+            len = (cv->str.size / sizeof(nwchar_t)) - 1;
             for(i=0;i<len;i++)
-                add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]);
+                add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
         }
         cstr_ccat(&cstr_buf, '\"');
         cstr_ccat(&cstr_buf, '\0');
         break;
+
+    case TOK_CFLOAT:
+        cstr_cat(&cstr_buf, "<float>", 0);
+        break;
+    case TOK_CDOUBLE:
+	cstr_cat(&cstr_buf, "<double>", 0);
+	break;
+    case TOK_CLDOUBLE:
+	cstr_cat(&cstr_buf, "<long double>", 0);
+	break;
+    case TOK_LINENUM:
+	cstr_cat(&cstr_buf, "<linenumber>", 0);
+	break;
+
+    /* above tokens have value, the ones below don't */
     case TOK_LT:
         v = '<';
@@ -325,4 +547,6 @@
     case TOK_A_SAR:
         return strcpy(p, ">>=");
+    case TOK_EOF:
+        return strcpy(p, "<eof>");
     default:
         if (v < TOK_IDENT) {
@@ -334,8 +558,12 @@
                     *p++ = q[1];
                     *p = '\0';
-                    return buf;
+                    return cstr_buf.data;
                 }
                 q += 3;
             }
+        if (v >= 127) {
+            sprintf(cstr_buf.data, "<%02x>", v);
+            return cstr_buf.data;
+        }
         addv:
             *p++ = v;
@@ -355,13 +583,16 @@
 }
 
-/* fill input buffer and peek next char */
-static int tcc_peekc_slow(BufferedFile *bf)
-{
+/* return the current character, handling end of block if necessary
+   (but not stray) */
+ST_FUNC int handle_eob(void)
+{
+    BufferedFile *bf = file;
     int len;
+
     /* only tries to read if really end of buffer */
     if (bf->buf_ptr >= bf->buf_end) {
-        if (bf->fd != -1) {
+        if (bf->fd >= 0) {
 #if defined(PARSE_DEBUG)
-            len = 8;
+            len = 1;
 #else
             len = IO_BUF_SIZE;
@@ -384,11 +615,4 @@
         return CH_EOF;
     }
-}
-
-/* return the current character, handling end of block if necessary
-   (but not stray) */
-ST_FUNC int handle_eob(void)
-{
-    return tcc_peekc_slow(file);
 }
 
@@ -436,18 +660,19 @@
     int c;
 
+    file->buf_ptr = p;
     if (p >= file->buf_end) {
-        file->buf_ptr = p;
         c = handle_eob();
+        if (c != '\\')
+            return c;
         p = file->buf_ptr;
-        if (c == '\\')
-            goto parse_stray;
-    } else {
-    parse_stray:
-        file->buf_ptr = p;
-        ch = *p;
-        handle_stray();
-        p = file->buf_ptr;
-        c = *p;
-    }
+    }
+    ch = *p;
+    if (handle_stray_noerror()) {
+        if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+            tcc_error("stray '\\' in program");
+        *--file->buf_ptr = '\\';
+    }
+    p = file->buf_ptr;
+    c = *p;
     return c;
 }
@@ -485,5 +710,4 @@
         handle_stray();
 }
-
 
 /* single line C++ comments */
@@ -528,5 +752,5 @@
 {
     int c;
-    
+
     p++;
     for(;;) {
@@ -558,4 +782,6 @@
                     c = handle_eob();
                     p = file->buf_ptr;
+                    if (c == CH_EOF)
+                        tcc_error("unexpected end of file in comment");
                     if (c == '\\') {
                         /* skip '\[\r]\n', otherwise just skip the stray */
@@ -598,9 +824,16 @@
 }
 
+ST_FUNC int set_idnum(int c, int val)
+{
+    int prev = isidnum_table[c - CH_EOF];
+    isidnum_table[c - CH_EOF] = val;
+    return prev;
+}
+
 #define cinp minp
 
 static inline void skip_spaces(void)
 {
-    while (is_space(ch))
+    while (isidnum_table[ch - CH_EOF] & IS_SPC)
         cinp();
 }
@@ -608,5 +841,5 @@
 static inline int check_space(int t, int *spc) 
 {
-    if (is_space(t)) {
+    if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
         if (*spc) 
             return 1;
@@ -756,5 +989,8 @@
                 else if (tok == TOK_LINEFEED)
                     goto redo_start;
-            }
+                else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                    p = parse_line_comment(p - 1);
+            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                p = parse_line_comment(p - 1);
             break;
 _default:
@@ -769,33 +1005,10 @@
 }
 
-/* ParseState handling */
-
-/* XXX: currently, no include file info is stored. Thus, we cannot display
-   accurate messages if the function or data definition spans multiple
-   files */
-
-/* save current parse state in 's' */
-ST_FUNC void save_parse_state(ParseState *s)
-{
-    s->line_num = file->line_num;
-    s->macro_ptr = macro_ptr;
-    s->tok = tok;
-    s->tokc = tokc;
-}
-
-/* restore parse state from 's' */
-ST_FUNC void restore_parse_state(ParseState *s)
-{
-    file->line_num = s->line_num;
-    macro_ptr = s->macro_ptr;
-    tok = s->tok;
-    tokc = s->tokc;
-}
-
+#if 0
 /* return the number of additional 'ints' necessary to store the
    token */
-static inline int tok_ext_size(int t)
-{
-    switch(t) {
+static inline int tok_size(const int *p)
+{
+    switch(*p) {
         /* 4 bytes */
     case TOK_CINT:
@@ -805,49 +1018,76 @@
     case TOK_CFLOAT:
     case TOK_LINENUM:
-        return 1;
+        return 1 + 1;
     case TOK_STR:
     case TOK_LSTR:
     case TOK_PPNUM:
-        tcc_error("unsupported token");
-        return 1;
+    case TOK_PPSTR:
+        return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
+    case TOK_CLONG:
+    case TOK_CULONG:
+	return 1 + LONG_SIZE / 4;
     case TOK_CDOUBLE:
     case TOK_CLLONG:
     case TOK_CULLONG:
-        return 2;
+        return 1 + 2;
     case TOK_CLDOUBLE:
-        return LDOUBLE_SIZE / 4;
+        return 1 + LDOUBLE_SIZE / 4;
     default:
-        return 0;
-    }
-}
+        return 1 + 0;
+    }
+}
+#endif
 
 /* token string handling */
-
 ST_INLN void tok_str_new(TokenString *s)
 {
     s->str = NULL;
-    s->len = 0;
+    s->len = s->lastlen = 0;
     s->allocated_len = 0;
     s->last_line_num = -1;
 }
 
-ST_FUNC void tok_str_free(int *str)
-{
-    tcc_free(str);
-}
-
-static int *tok_str_realloc(TokenString *s)
-{
-    int *str, len;
-
-    if (s->allocated_len == 0) {
-        len = 8;
-    } else {
-        len = s->allocated_len * 2;
-    }
-    str = tcc_realloc(s->str, len * sizeof(int));
-    s->allocated_len = len;
-    s->str = str;
+ST_FUNC TokenString *tok_str_alloc(void)
+{
+    TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
+    tok_str_new(str);
     return str;
+}
+
+ST_FUNC int *tok_str_dup(TokenString *s)
+{
+    int *str;
+
+    str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
+    memcpy(str, s->str, s->len * sizeof(int));
+    return str;
+}
+
+ST_FUNC void tok_str_free_str(int *str)
+{
+    tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC void tok_str_free(TokenString *str)
+{
+    tok_str_free_str(str->str);
+    tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
+{
+    int *str, size;
+
+    size = s->allocated_len;
+    if (size < 16)
+        size = 16;
+    while (size < new_size)
+        size = size * 2;
+    if (size > s->allocated_len) {
+        str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
+        s->allocated_len = size;
+        s->str = str;
+    }
+    return s->str;
 }
 
@@ -859,19 +1099,42 @@
     str = s->str;
     if (len >= s->allocated_len)
-        str = tok_str_realloc(s);
+        str = tok_str_realloc(s, len + 1);
     str[len++] = t;
     s->len = len;
 }
 
+ST_FUNC void begin_macro(TokenString *str, int alloc)
+{
+    str->alloc = alloc;
+    str->prev = macro_stack;
+    str->prev_ptr = macro_ptr;
+    str->save_line_num = file->line_num;
+    macro_ptr = str->str;
+    macro_stack = str;
+}
+
+ST_FUNC void end_macro(void)
+{
+    TokenString *str = macro_stack;
+    macro_stack = str->prev;
+    macro_ptr = str->prev_ptr;
+    file->line_num = str->save_line_num;
+    if (str->alloc == 2) {
+        str->alloc = 3; /* just mark as finished */
+    } else {
+        tok_str_free(str);
+    }
+}
+
 static void tok_str_add2(TokenString *s, int t, CValue *cv)
 {
     int len, *str;
 
-    len = s->len;
+    len = s->lastlen = s->len;
     str = s->str;
 
     /* allocate space for worst case */
-    if (len + TOK_MAX_SIZE > s->allocated_len)
-        str = tok_str_realloc(s);
+    if (len + TOK_MAX_SIZE >= s->allocated_len)
+        str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
     str[len++] = t;
     switch(t) {
@@ -882,23 +1145,22 @@
     case TOK_CFLOAT:
     case TOK_LINENUM:
+#if LONG_SIZE == 4
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
         str[len++] = cv->tab[0];
         break;
     case TOK_PPNUM:
+    case TOK_PPSTR:
     case TOK_STR:
     case TOK_LSTR:
         {
-            int nb_words;
-            CString *cstr;
-
-            nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
-            while ((len + nb_words) > s->allocated_len)
-                str = tok_str_realloc(s);
-            cstr = (CString *)(str + len);
-            cstr->data = NULL;
-            cstr->size = cv->cstr->size;
-            cstr->data_allocated = NULL;
-            cstr->size_allocated = cstr->size;
-            memcpy((char *)cstr + sizeof(CString), 
-                   cv->cstr->data, cstr->size);
+            /* Insert the string into the int array. */
+            size_t nb_words =
+                1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
+            if (len + nb_words >= s->allocated_len)
+                str = tok_str_realloc(s, len + nb_words + 1);
+            str[len] = cv->str.size;
+            memcpy(&str[len + 1], cv->str.data, cv->str.size);
             len += nb_words;
         }
@@ -907,4 +1169,8 @@
     case TOK_CLLONG:
     case TOK_CULLONG:
+#if LONG_SIZE == 8
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
 #if LDOUBLE_SIZE == 8
     case TOK_CLDOUBLE:
@@ -957,22 +1223,37 @@
     tab = cv->tab;
     switch(*t = *p++) {
+#if LONG_SIZE == 4
+    case TOK_CLONG:
+#endif
     case TOK_CINT:
-    case TOK_CUINT:
     case TOK_CCHAR:
     case TOK_LCHAR:
+    case TOK_LINENUM:
+        cv->i = *p++;
+        break;
+#if LONG_SIZE == 4
+    case TOK_CULONG:
+#endif
+    case TOK_CUINT:
+        cv->i = (unsigned)*p++;
+        break;
     case TOK_CFLOAT:
-    case TOK_LINENUM:
-        tab[0] = *p++;
-        break;
+	tab[0] = *p++;
+	break;
     case TOK_STR:
     case TOK_LSTR:
     case TOK_PPNUM:
-        cv->cstr = (CString *)p;
-        cv->cstr->data = (char *)p + sizeof(CString);
-        p += (sizeof(CString) + cv->cstr->size + 3) >> 2;
+    case TOK_PPSTR:
+        cv->str.size = *p++;
+        cv->str.data = p;
+        p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
         break;
     case TOK_CDOUBLE:
     case TOK_CLLONG:
     case TOK_CULLONG:
+#if LONG_SIZE == 8
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
         n = 2;
         goto copy;
@@ -1000,12 +1281,17 @@
 static int macro_is_equal(const int *a, const int *b)
 {
-    char buf[STRING_MAX_SIZE + 1];
     CValue cv;
     int t;
+
+    if (!a || !b)
+        return 1;
+
     while (*a && *b) {
+        /* first time preallocate macro_equal_buf, next time only reset position to start */
+        cstr_reset(&macro_equal_buf);
         TOK_GET(&t, &a, &cv);
-        pstrcpy(buf, sizeof buf, get_tok_str(t, &cv));
+        cstr_cat(&macro_equal_buf, get_tok_str(t, &cv), 0);
         TOK_GET(&t, &b, &cv);
-        if (strcmp(buf, get_tok_str(t, &cv)))
+        if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
             return 0;
     }
@@ -1016,14 +1302,14 @@
 ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
 {
-    Sym *s;
-
-    s = define_find(v);
-    if (s && !macro_is_equal(s->d, str))
-        tcc_warning("%s redefined", get_tok_str(v, NULL));
-
+    Sym *s, *o;
+
+    o = define_find(v);
     s = sym_push2(&define_stack, v, macro_type, 0);
     s->d = str;
     s->next = first_arg;
     table_ident[v - TOK_IDENT]->sym_define = s;
+
+    if (o && !macro_is_equal(o->d, s->d))
+	tcc_warning("%s redefined", get_tok_str(v, NULL));
 }
 
@@ -1031,9 +1317,7 @@
 ST_FUNC void define_undef(Sym *s)
 {
-    int v;
-    v = s->v;
+    int v = s->v;
     if (v >= TOK_IDENT && v < tok_ident)
         table_ident[v - TOK_IDENT]->sym_define = NULL;
-    s->v = 0;
 }
 
@@ -1049,20 +1333,23 @@
 ST_FUNC void free_defines(Sym *b)
 {
-    Sym *top, *top1;
-    int v;
-
-    top = define_stack;
-    while (top != b) {
-        top1 = top->prev;
-        /* do not free args or predefined defines */
-        if (top->d)
-            tok_str_free(top->d);
-        v = top->v;
-        if (v >= TOK_IDENT && v < tok_ident)
-            table_ident[v - TOK_IDENT]->sym_define = NULL;
+    while (define_stack != b) {
+        Sym *top = define_stack;
+        define_stack = top->prev;
+        tok_str_free_str(top->d);
+        define_undef(top);
         sym_free(top);
-        top = top1;
-    }
-    define_stack = b;
+    }
+
+    /* restore remaining (-D or predefined) symbols if they were
+       #undef'd in the file */
+    while (b) {
+        int v = b->v;
+        if (v >= TOK_IDENT && v < tok_ident) {
+            Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
+            if (!*d)
+                *d = b;
+        }
+        b = b->prev;
+    }
 }
 
@@ -1095,5 +1382,5 @@
 /* pop labels until element last is reached. Look if any labels are
    undefined. Define symbols if '&&label' was used. */
-ST_FUNC void label_pop(Sym **ptop, Sym *slast)
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
 {
     Sym *s, *s1;
@@ -1114,7 +1401,24 @@
         /* remove label */
         table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
-        sym_free(s);
-    }
-    *ptop = slast;
+        if (!keep)
+            sym_free(s);
+    }
+    if (!keep)
+        *ptop = slast;
+}
+
+/* fake the nth "#if defined test_..." for tcc -dt -run */
+static void maybe_run_test(TCCState *s)
+{
+    const char *p;
+    if (s->include_stack_ptr != s->include_stack)
+        return;
+    p = get_tok_str(tok, NULL);
+    if (0 != memcmp(p, "test_", 5))
+        return;
+    if (0 != --s->run_test)
+        return;
+    fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
+    define_push(tok, MACRO_OBJ, NULL, NULL);
 }
 
@@ -1123,7 +1427,8 @@
 {
     int c, t;
-    TokenString str;
+    TokenString *str;
     
-    tok_str_new(&str);
+    str = tok_str_alloc();
+    pp_expr = 1;
     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
         next(); /* do macro subst */
@@ -1133,7 +1438,14 @@
             if (t == '(') 
                 next_nomacro();
+            if (tok < TOK_IDENT)
+                expect("identifier");
+            if (tcc_state->run_test)
+                maybe_run_test(tcc_state);
             c = define_find(tok) != 0;
-            if (t == '(')
+            if (t == '(') {
                 next_nomacro();
+                if (tok != ')')
+                    expect("')'");
+            }
             tok = TOK_CINT;
             tokc.i = c;
@@ -1143,33 +1455,17 @@
             tokc.i = 0;
         }
-        tok_str_add_tok(&str);
-    }
-    tok_str_add(&str, -1); /* simulate end of file */
-    tok_str_add(&str, 0);
+        tok_str_add_tok(str);
+    }
+    pp_expr = 0;
+    tok_str_add(str, -1); /* simulate end of file */
+    tok_str_add(str, 0);
     /* now evaluate C constant expression */
-    macro_ptr = str.str;
+    begin_macro(str, 1);
     next();
     c = expr_const();
-    macro_ptr = NULL;
-    tok_str_free(str.str);
+    end_macro();
     return c != 0;
 }
 
-#if defined(PARSE_DEBUG) || defined(PP_DEBUG)
-static void tok_print(int *str)
-{
-    int t;
-    CValue cval;
-
-    printf("<");
-    while (1) {
-        TOK_GET(&t, &str, &cval);
-        if (!t)
-            break;
-        printf("%s", get_tok_str(t, &cval));
-    }
-    printf(">\n");
-}
-#endif
 
 /* parse after #define */
@@ -1178,18 +1474,24 @@
     Sym *s, *first, **ps;
     int v, t, varg, is_vaargs, spc;
-    TokenString str;
-    
+    int saved_parse_flags = parse_flags;
+
     v = tok;
-    if (v < TOK_IDENT)
+    if (v < TOK_IDENT || v == TOK_DEFINED)
         tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
     /* XXX: should check if same macro (ANSI) */
     first = NULL;
     t = MACRO_OBJ;
+    /* We have to parse the whole define as if not in asm mode, in particular
+       no line comment with '#' must be ignored.  Also for function
+       macros the argument list must be parsed without '.' being an ID
+       character.  */
+    parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
     /* '(' must be just after macro definition for MACRO_FUNC */
     next_nomacro_spc();
     if (tok == '(') {
+        int dotid = set_idnum('.', 0);
         next_nomacro();
         ps = &first;
-        while (tok != ')') {
+        if (tok != ')') for (;;) {
             varg = tok;
             next_nomacro();
@@ -1203,64 +1505,76 @@
             }
             if (varg < TOK_IDENT)
-                tcc_error("badly punctuated parameter list");
+        bad_list:
+                tcc_error("bad macro parameter list");
             s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
             *ps = s;
             ps = &s->next;
-            if (tok != ',')
+            if (tok == ')')
                 break;
+            if (tok != ',' || is_vaargs)
+                goto bad_list;
             next_nomacro();
         }
-        if (tok == ')')
-            next_nomacro_spc();
+        next_nomacro_spc();
         t = MACRO_FUNC;
-    }
-    tok_str_new(&str);
+        set_idnum('.', dotid);
+    }
+
+    tokstr_buf.len = 0;
     spc = 2;
-    /* EOF testing necessary for '-D' handling */
+    parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
+    /* The body of a macro definition should be parsed such that identifiers
+       are parsed like the file mode determines (i.e. with '.' being an
+       ID character in asm mode).  But '#' should be retained instead of
+       regarded as line comment leader, so still don't set ASM_FILE
+       in parse_flags. */
     while (tok != TOK_LINEFEED && tok != TOK_EOF) {
-        /* remove spaces around ## and after '#' */        
+        /* remove spaces around ## and after '#' */
         if (TOK_TWOSHARPS == tok) {
+            if (2 == spc)
+                goto bad_twosharp;
             if (1 == spc)
-                --str.len;
-            spc = 2;
+                --tokstr_buf.len;
+            spc = 3;
+	    tok = TOK_PPJOIN;
         } else if ('#' == tok) {
-            spc = 2;
+            spc = 4;
         } else if (check_space(tok, &spc)) {
             goto skip;
         }
-        tok_str_add2(&str, tok, &tokc);
+        tok_str_add2(&tokstr_buf, tok, &tokc);
     skip:
         next_nomacro_spc();
     }
+
+    parse_flags = saved_parse_flags;
     if (spc == 1)
-        --str.len; /* remove trailing space */
-    tok_str_add(&str, 0);
-#ifdef PP_DEBUG
-    printf("define %s %d: ", get_tok_str(v, NULL), t);
-    tok_print(str.str);
-#endif
-    define_push(v, t, str.str, first);
-}
-
-static inline int hash_cached_include(const char *filename)
+        --tokstr_buf.len; /* remove trailing space */
+    tok_str_add(&tokstr_buf, 0);
+    if (3 == spc)
+bad_twosharp:
+        tcc_error("'##' cannot appear at either end of macro");
+    define_push(v, t, tok_str_dup(&tokstr_buf), first);
+}
+
+static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
 {
     const unsigned char *s;
     unsigned int h;
+    CachedInclude *e;
+    int i;
 
     h = TOK_HASH_INIT;
-    s = filename;
+    s = (unsigned char *) filename;
     while (*s) {
+#ifdef _WIN32
+        h = TOK_HASH_FUNC(h, toup(*s));
+#else
         h = TOK_HASH_FUNC(h, *s);
+#endif
         s++;
     }
     h &= (CACHED_INCLUDES_HASH_SIZE - 1);
-    return h;
-}
-
-static CachedInclude *search_cached_include(TCCState *s1, const char *filename)
-{
-    CachedInclude *e;
-    int i, h;
-    h = hash_cached_include(filename);
+
     i = s1->cached_includes_hash[h];
     for(;;) {
@@ -1272,40 +1586,67 @@
         i = e->hash_next;
     }
-    return NULL;
-}
-
-static inline void add_cached_include(TCCState *s1, const char *filename, int ifndef_macro)
-{
-    CachedInclude *e;
-    int h;
-
-    if (search_cached_include(s1, filename))
-        return;
-#ifdef INC_DEBUG
-    printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
-#endif
+    if (!add)
+        return NULL;
+
     e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
     strcpy(e->filename, filename);
-    e->ifndef_macro = ifndef_macro;
-    dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
+    e->ifndef_macro = e->once = 0;
+    dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
     /* add in hash table */
-    h = hash_cached_include(filename);
     e->hash_next = s1->cached_includes_hash[h];
     s1->cached_includes_hash[h] = s1->nb_cached_includes;
+#ifdef INC_DEBUG
+    printf("adding cached '%s'\n", filename);
+#endif
+    return e;
 }
 
 static void pragma_parse(TCCState *s1)
 {
-    int val;
-
-    next();
-    if (tok == TOK_pack) {
-        /*
-          This may be:
-          #pragma pack(1) // set
-          #pragma pack() // reset to default
-          #pragma pack(push,1) // push & set
-          #pragma pack(pop) // restore previous
-        */
+    next_nomacro();
+    if (tok == TOK_push_macro || tok == TOK_pop_macro) {
+        int t = tok, v;
+        Sym *s;
+
+        if (next(), tok != '(')
+            goto pragma_err;
+        if (next(), tok != TOK_STR)
+            goto pragma_err;
+        v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
+        if (next(), tok != ')')
+            goto pragma_err;
+        if (t == TOK_push_macro) {
+            while (NULL == (s = define_find(v)))
+                define_push(v, 0, NULL, NULL);
+            s->type.ref = s; /* set push boundary */
+        } else {
+            for (s = define_stack; s; s = s->prev)
+                if (s->v == v && s->type.ref == s) {
+                    s->type.ref = NULL;
+                    break;
+                }
+        }
+        if (s)
+            table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
+        else
+            tcc_warning("unbalanced #pragma pop_macro");
+        pp_debug_tok = t, pp_debug_symv = v;
+
+    } else if (tok == TOK_once) {
+        search_cached_include(s1, file->filename, 1)->once = pp_once;
+
+    } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+        /* tcc -E: keep pragmas below unchanged */
+        unget_tok(' ');
+        unget_tok(TOK_PRAGMA);
+        unget_tok('#');
+        unget_tok(TOK_LINEFEED);
+
+    } else if (tok == TOK_pack) {
+        /* This may be:
+           #pragma pack(1) // set
+           #pragma pack() // reset to default
+           #pragma pack(push,1) // push & set
+           #pragma pack(pop) // restore previous */
         next();
         skip('(');
@@ -1318,5 +1659,5 @@
             s1->pack_stack_ptr--;
         } else {
-            val = 0;
+            int val = 0;
             if (tok != ')') {
                 if (tok == TOK_ASM_push) {
@@ -1327,17 +1668,45 @@
                     skip(',');
                 }
-                if (tok != TOK_CINT) {
-                pack_error:
-                    tcc_error("invalid pack pragma");
-                }
+                if (tok != TOK_CINT)
+                    goto pragma_err;
                 val = tokc.i;
                 if (val < 1 || val > 16 || (val & (val - 1)) != 0)
-                    goto pack_error;
+                    goto pragma_err;
                 next();
             }
             *s1->pack_stack_ptr = val;
-            skip(')');
-        }
-    }
+        }
+        if (tok != ')')
+            goto pragma_err;
+
+    } else if (tok == TOK_comment) {
+        char *p; int t;
+        next();
+        skip('(');
+        t = tok;
+        next();
+        skip(',');
+        if (tok != TOK_STR)
+            goto pragma_err;
+        p = tcc_strdup((char *)tokc.str.data);
+        next();
+        if (tok != ')')
+            goto pragma_err;
+        if (t == TOK_lib) {
+            dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
+        } else {
+            if (t == TOK_option)
+                tcc_set_options(s1, p);
+            tcc_free(p);
+        }
+
+    } else if (s1->warn_unsupported) {
+        tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
+    }
+    return;
+
+pragma_err:
+    tcc_error("malformed #pragma directive");
+    return;
 }
 
@@ -1351,15 +1720,24 @@
 
     saved_parse_flags = parse_flags;
-    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
-        PARSE_FLAG_LINEFEED;
+    parse_flags = PARSE_FLAG_PREPROCESS
+        | PARSE_FLAG_TOK_NUM
+        | PARSE_FLAG_TOK_STR
+        | PARSE_FLAG_LINEFEED
+        | (parse_flags & PARSE_FLAG_ASM_FILE)
+        ;
+
     next_nomacro();
  redo:
     switch(tok) {
     case TOK_DEFINE:
+        pp_debug_tok = tok;
         next_nomacro();
+        pp_debug_symv = tok;
         parse_define();
         break;
     case TOK_UNDEF:
+        pp_debug_tok = tok;
         next_nomacro();
+        pp_debug_symv = tok;
         s = define_find(tok);
         /* undefine symbol by putting an invalid name */
@@ -1398,32 +1776,25 @@
 #endif
         } else {
-            /* computed #include : either we have only strings or
-               we have anything enclosed in '<>' */
+	    int len;
+            /* computed #include : concatenate everything up to linefeed,
+	       the result must be one of the two accepted forms.
+	       Don't convert pp-tokens to tokens here.  */
+	    parse_flags = (PARSE_FLAG_PREPROCESS
+			   | PARSE_FLAG_LINEFEED
+			   | (parse_flags & PARSE_FLAG_ASM_FILE));
             next();
             buf[0] = '\0';
-            if (tok == TOK_STR) {
-                while (tok != TOK_LINEFEED) {
-                    if (tok != TOK_STR) {
-                    include_syntax:
-                        tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
-                    }
-                    pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
-                    next();
-                }
-                c = '\"';
-            } else {
-                int len;
-                while (tok != TOK_LINEFEED) {
-                    pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
-                    next();
-                }
-                len = strlen(buf);
-                /* check syntax and remove '<>' */
-                if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
-                    goto include_syntax;
-                memmove(buf, buf + 1, len - 2);
-                buf[len - 2] = '\0';
-                c = '>';
-            }
+	    while (tok != TOK_LINEFEED) {
+		pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
+		next();
+	    }
+	    len = strlen(buf);
+	    /* check syntax and remove '<>|""' */
+	    if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
+			     (buf[0] != '<' || buf[len-1] != '>'))))
+	        tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
+	    c = buf[len-1];
+	    memmove(buf, buf + 1, len - 2);
+	    buf[len - 2] = '\0';
         }
 
@@ -1432,32 +1803,29 @@
         /* store current file in stack, but increment stack later below */
         *s1->include_stack_ptr = file;
-
-        n = s1->nb_include_paths + s1->nb_sysinclude_paths;
-        for (i = -2; i < n; ++i) {
+        i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
+        n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
+        for (; i < n; ++i) {
             char buf1[sizeof file->filename];
             CachedInclude *e;
-            BufferedFile **f;
             const char *path;
 
-            if (i == -2) {
+            if (i == 0) {
                 /* check absolute include path */
                 if (!IS_ABSPATH(buf))
                     continue;
                 buf1[0] = 0;
-                i = n; /* force end loop */
-
-            } else if (i == -1) {
-                /* search in current dir if "header.h" */
+
+            } else if (i == 1) {
+                /* search in file's dir if "header.h" */
                 if (c != '\"')
                     continue;
-                path = file->filename;
+                /* https://savannah.nongnu.org/bugs/index.php?50847 */
+                path = file->true_filename;
                 pstrncpy(buf1, path, tcc_basename(path) - path);
 
             } else {
                 /* search in all the include paths */
-                if (i < s1->nb_include_paths)
-                    path = s1->include_paths[i];
-                else
-                    path = s1->sysinclude_paths[i - s1->nb_include_paths];
+                int j = i - 2, k = j - s1->nb_include_paths;
+                path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
                 pstrcpy(buf1, sizeof(buf1), path);
                 pstrcat(buf1, sizeof(buf1), "/");
@@ -1465,18 +1833,8 @@
 
             pstrcat(buf1, sizeof(buf1), buf);
-
-            if (tok == TOK_INCLUDE_NEXT)
-                for (f = s1->include_stack_ptr; f >= s1->include_stack; --f)
-                    if (0 == PATHCMP((*f)->filename, buf1)) {
-#ifdef INC_DEBUG
-                        printf("%s: #include_next skipping %s\n", file->filename, buf1);
-#endif
-                        goto include_trynext;
-                    }
-
-            e = search_cached_include(s1, buf1);
-            if (e && define_find(e->ifndef_macro)) {
+            e = search_cached_include(s1, buf1, 0);
+            if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
                 /* no need to parse the include because the 'ifndef macro'
-                   is defined */
+                   is defined (or had #pragma once) */
 #ifdef INC_DEBUG
                 printf("%s: skipping cached %s\n", file->filename, buf1);
@@ -1486,12 +1844,12 @@
 
             if (tcc_open(s1, buf1) < 0)
-include_trynext:
                 continue;
 
+            file->include_next_index = i + 1;
 #ifdef INC_DEBUG
             printf("%s: including %s\n", file->prev->filename, file->filename);
 #endif
             /* update target deps */
-            dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
+            dynarray_add(&s1->target_deps, &s1->nb_target_deps,
                     tcc_strdup(buf1));
             /* push current file in stack */
@@ -1530,5 +1888,5 @@
     do_if:
         if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
-            tcc_error("memory full");
+            tcc_error("memory full (ifdef)");
         *s1->ifdef_stack_ptr++ = c;
         goto test_skip;
@@ -1547,8 +1905,10 @@
             tcc_error("#elif after #else");
         /* last #if/#elif expression was true: we skip */
-        if (c == 1)
-            goto skip;
-        c = expr_preprocess();
-        s1->ifdef_stack_ptr[-1] = c;
+        if (c == 1) {
+            c = 0;
+        } else {
+            c = expr_preprocess();
+            s1->ifdef_stack_ptr[-1] = c;
+        }
     test_else:
         if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
@@ -1556,5 +1916,4 @@
     test_skip:
         if (!(c & 1)) {
-        skip:
             preprocess_skip();
             is_bof = 0;
@@ -1580,16 +1939,31 @@
         }
         break;
+    case TOK_PPNUM:
+        n = strtoul((char*)tokc.str.data, &q, 10);
+        goto _line_num;
     case TOK_LINE:
         next();
         if (tok != TOK_CINT)
-            tcc_error("#line");
-        file->line_num = tokc.i - 1; /* the line number will be incremented after */
+    _line_err:
+            tcc_error("wrong #line format");
+        n = tokc.i;
+    _line_num:
         next();
         if (tok != TOK_LINEFEED) {
-            if (tok != TOK_STR)
-                tcc_error("#line");
-            pstrcpy(file->filename, sizeof(file->filename), 
-                    (char *)tokc.cstr->data);
-        }
+            if (tok == TOK_STR) {
+                if (file->true_filename == file->filename)
+                    file->true_filename = tcc_strdup(file->filename);
+                pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
+            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                break;
+            else
+                goto _line_err;
+            --n;
+        }
+        if (file->fd > 0)
+            total_lines += file->line_num - n;
+        file->line_num = n;
+        if (s1->do_debug)
+    	    put_stabs(file->filename, N_BINCL, 0, 0, 0);
         break;
     case TOK_ERROR:
@@ -1617,18 +1991,17 @@
         pragma_parse(s1);
         break;
+    case TOK_LINEFEED:
+        goto the_end;
     default:
-        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
-            /* '!' is ignored to allow C scripts. numbers are ignored
-               to emulate cpp behaviour */
-        } else {
-            if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
-                tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
-            else {
-                /* this is a gas line comment in an 'S' file. */
-                file->buf_ptr = parse_line_comment(file->buf_ptr);
-                goto the_end;
-            }
-        }
-        break;
+        /* ignore gas line comment in an 'S' file. */
+        if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
+            goto ignore;
+        if (tok == '!' && is_bof)
+            /* '!' is ignored at beginning to allow C scripts. */
+            goto ignore;
+        tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
+    ignore:
+        file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
+        goto the_end;
     }
     /* ignore other preprocess commands or #! for C scripts */
@@ -1731,4 +2104,58 @@
                 break;
             }
+        } else if (is_long && c >= 0x80) {
+            /* assume we are processing UTF-8 sequence */
+            /* reference: The Unicode Standard, Version 10.0, ch3.9 */
+
+            int cont; /* count of continuation bytes */
+            int skip; /* how many bytes should skip when error occurred */
+            int i;
+
+            /* decode leading byte */
+            if (c < 0xC2) {
+	            skip = 1; goto invalid_utf8_sequence;
+            } else if (c <= 0xDF) {
+	            cont = 1; n = c & 0x1f;
+            } else if (c <= 0xEF) {
+	            cont = 2; n = c & 0xf;
+            } else if (c <= 0xF4) {
+	            cont = 3; n = c & 0x7;
+            } else {
+	            skip = 1; goto invalid_utf8_sequence;
+            }
+
+            /* decode continuation bytes */
+            for (i = 1; i <= cont; i++) {
+                int l = 0x80, h = 0xBF;
+
+                /* adjust limit for second byte */
+                if (i == 1) {
+                    switch (c) {
+                    case 0xE0: l = 0xA0; break;
+                    case 0xED: h = 0x9F; break;
+                    case 0xF0: l = 0x90; break;
+                    case 0xF4: h = 0x8F; break;
+                    }
+                }
+
+                if (p[i] < l || p[i] > h) {
+                    skip = i; goto invalid_utf8_sequence;
+                }
+
+                n = (n << 6) | (p[i] & 0x3f);
+            }
+
+            /* advance pointer */
+            p += 1 + cont;
+            c = n;
+            goto add_char_nonext;
+
+            /* error handling */
+        invalid_utf8_sequence:
+            tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c);
+            c = 0xFFFD;
+            p += skip;
+            goto add_char_nonext;
+
         }
         p++;
@@ -1736,6 +2163,18 @@
         if (!is_long)
             cstr_ccat(outstr, c);
-        else
+        else {
+#ifdef TCC_TARGET_PE
+            /* store as UTF-16 */
+            if (c < 0x10000) {
+                cstr_wccat(outstr, c);
+            } else {
+                c -= 0x10000;
+                cstr_wccat(outstr, (c >> 10) + 0xD800);
+                cstr_wccat(outstr, (c & 0x3FF) + 0xDC00);
+            }
+#else
             cstr_wccat(outstr, c);
+#endif
+        }
     }
     /* add a trailing '\0' */
@@ -1744,4 +2183,52 @@
     else
         cstr_wccat(outstr, '\0');
+}
+
+static void parse_string(const char *s, int len)
+{
+    uint8_t buf[1000], *p = buf;
+    int is_long, sep;
+
+    if ((is_long = *s == 'L'))
+        ++s, --len;
+    sep = *s++;
+    len -= 2;
+    if (len >= sizeof buf)
+        p = tcc_malloc(len + 1);
+    memcpy(p, s, len);
+    p[len] = 0;
+
+    cstr_reset(&tokcstr);
+    parse_escape_string(&tokcstr, p, is_long);
+    if (p != buf)
+        tcc_free(p);
+
+    if (sep == '\'') {
+        int char_size, i, n, c;
+        /* XXX: make it portable */
+        if (!is_long)
+            tok = TOK_CCHAR, char_size = 1;
+        else
+            tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
+        n = tokcstr.size / char_size - 1;
+        if (n < 1)
+            tcc_error("empty character constant");
+        if (n > 1)
+            tcc_warning("multi-character character constant");
+        for (c = i = 0; i < n; ++i) {
+            if (is_long)
+                c = ((nwchar_t *)tokcstr.data)[i];
+            else
+                c = (c << 8) | ((char *)tokcstr.data)[i];
+        }
+        tokc.i = c;
+    } else {
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
+        if (!is_long)
+            tok = TOK_STR;
+        else
+            tok = TOK_LSTR;
+    }
 }
 
@@ -1831,5 +2318,5 @@
                 shift = 4;
             else 
-                shift = 2;
+                shift = 1;
             bn_zero(bn);
             q = token_buf;
@@ -1969,5 +2456,6 @@
     } else {
         unsigned long long n, n1;
-        int lcount, ucount;
+        int lcount, ucount, ov = 0;
+        const char *p1;
 
         /* integer number */
@@ -1982,36 +2470,25 @@
             t = *q++;
             /* no need for checks except for base 10 / 8 errors */
-            if (t == '\0') {
+            if (t == '\0')
                 break;
-            } else if (t >= 'a') {
+            else if (t >= 'a')
                 t = t - 'a' + 10;
-            } else if (t >= 'A') {
+            else if (t >= 'A')
                 t = t - 'A' + 10;
-            } else {
+            else
                 t = t - '0';
-                if (t >= b)
-                    tcc_error("invalid digit");
-            }
+            if (t >= b)
+                tcc_error("invalid digit");
             n1 = n;
             n = n * b + t;
             /* detect overflow */
-            /* XXX: this test is not reliable */
-            if (n < n1)
-                tcc_error("integer constant overflow");
-        }
-        
-        /* XXX: not exactly ANSI compliant */
-        if ((n & 0xffffffff00000000LL) != 0) {
-            if ((n >> 63) != 0)
-                tok = TOK_CULLONG;
-            else
-                tok = TOK_CLLONG;
-        } else if (n > 0x7fffffff) {
-            tok = TOK_CUINT;
-        } else {
-            tok = TOK_CINT;
-        }
-        lcount = 0;
-        ucount = 0;
+            if (n1 >= 0x1000000000000000ULL && n / b != n1)
+                ov = 1;
+        }
+
+        /* Determine the characteristics (unsigned and/or 64bit) the type of
+           the constant must have according to the constant suffix(es) */
+        lcount = ucount = 0;
+        p1 = p;
         for(;;) {
             t = toup(ch);
@@ -2019,15 +2496,7 @@
                 if (lcount >= 2)
                     tcc_error("three 'l's in integer constant");
+                if (lcount && *(p - 1) != ch)
+                    tcc_error("incorrect integer suffix: %s", p1);
                 lcount++;
-#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
-                if (lcount == 2) {
-#endif
-                    if (tok == TOK_CINT)
-                        tok = TOK_CLLONG;
-                    else if (tok == TOK_CUINT)
-                        tok = TOK_CULLONG;
-#if !defined TCC_TARGET_X86_64 || defined TCC_TARGET_PE
-                }
-#endif
                 ch = *p++;
             } else if (t == 'U') {
@@ -2035,8 +2504,4 @@
                     tcc_error("two 'u's in integer constant");
                 ucount++;
-                if (tok == TOK_CINT)
-                    tok = TOK_CUINT;
-                else if (tok == TOK_CLLONG)
-                    tok = TOK_CULLONG;
                 ch = *p++;
             } else {
@@ -2044,8 +2509,36 @@
             }
         }
-        if (tok == TOK_CINT || tok == TOK_CUINT)
-            tokc.ui = n;
-        else
-            tokc.ull = n;
+
+        /* Determine if it needs 64 bits and/or unsigned in order to fit */
+        if (ucount == 0 && b == 10) {
+            if (lcount <= (LONG_SIZE == 4)) {
+                if (n >= 0x80000000U)
+                    lcount = (LONG_SIZE == 4) + 1;
+            }
+            if (n >= 0x8000000000000000ULL)
+                ov = 1, ucount = 1;
+        } else {
+            if (lcount <= (LONG_SIZE == 4)) {
+                if (n >= 0x100000000ULL)
+                    lcount = (LONG_SIZE == 4) + 1;
+                else if (n >= 0x80000000U)
+                    ucount = 1;
+            }
+            if (n >= 0x8000000000000000ULL)
+                ucount = 1;
+        }
+
+        if (ov)
+            tcc_warning("integer constant overflow");
+
+        tok = TOK_CINT;
+	if (lcount) {
+            tok = TOK_CLONG;
+            if (lcount == 2)
+                tok = TOK_CLLONG;
+	}
+	if (ucount)
+	    ++tok; /* TOK_CU... */
+        tokc.i = n;
     }
     if (ch)
@@ -2068,5 +2561,5 @@
 static inline void next_nomacro1(void)
 {
-    int t, c, is_long;
+    int t, c, is_long, len;
     TokenSym *ts;
     uint8_t *p, *p1;
@@ -2081,5 +2574,9 @@
         tok = c;
         p++;
-        goto keep_tok_flags;
+        if (parse_flags & PARSE_FLAG_SPACES)
+            goto keep_tok_flags;
+        while (isidnum_table[*p - CH_EOF] & IS_SPC)
+            ++p;
+        goto redo_no_start;
     case '\f':
     case '\v':
@@ -2089,20 +2586,10 @@
     case '\\':
         /* first look if it is in fact an end of buffer */
-        if (p >= file->buf_end) {
-            file->buf_ptr = p;
-            handle_eob();
-            p = file->buf_ptr;
-            if (p >= file->buf_end)
-                goto parse_eof;
-            else
-                goto redo_no_start;
-        } else {
-            file->buf_ptr = p;
-            ch = *p;
-            handle_stray();
-            p = file->buf_ptr;
+        c = handle_stray1(p);
+        p = file->buf_ptr;
+        if (c == '\\')
+            goto parse_simple;
+        if (c != CH_EOF)
             goto redo_no_start;
-        }
-    parse_eof:
         {
             TCCState *s1 = tcc_state;
@@ -2129,5 +2616,6 @@
                     printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
 #endif
-                    add_cached_include(s1, file->filename, file->ifndef_macro_saved);
+                    search_cached_include(s1, file->filename, 1)
+                        ->ifndef_macro = file->ifndef_macro_saved;
                     tok_flags &= ~TOK_FLAG_ENDIF;
                 }
@@ -2141,4 +2629,6 @@
                 s1->include_stack_ptr--;
                 p = file->buf_ptr;
+                if (p == file->buffer)
+                    tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
                 goto redo_no_start;
             }
@@ -2170,5 +2660,5 @@
                 tok = TOK_TWOSHARPS;
             } else {
-                if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
+                if (parse_flags & PARSE_FLAG_ASM_FILE) {
                     p = parse_line_comment(p - 1);
                     goto redo_no_start;
@@ -2179,4 +2669,10 @@
         }
         break;
+    
+    /* dollar is allowed to start identifiers when not parsing asm */
+    case '$':
+        if (!(isidnum_table[c - CH_EOF] & IS_ID)
+         || (parse_flags & PARSE_FLAG_ASM_FILE))
+            goto parse_simple;
 
     case 'a': case 'b': case 'c': case 'd':
@@ -2199,19 +2695,12 @@
         h = TOK_HASH_INIT;
         h = TOK_HASH_FUNC(h, c);
-        p++;
-        for(;;) {
-            c = *p;
-            if (!isidnum_table[c-CH_EOF])
-                break;
+        while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
             h = TOK_HASH_FUNC(h, c);
-            p++;
-        }
+        len = p - p1;
         if (c != '\\') {
             TokenSym **pts;
-            int len;
 
             /* fast case : no stray found, so we have the full token
                and we have already hashed it */
-            len = p - p1;
             h &= (TOK_HASH_SIZE - 1);
             pts = &hash_ident[h];
@@ -2224,18 +2713,15 @@
                 pts = &(ts->hash_next);
             }
-            ts = tok_alloc_new(pts, p1, len);
+            ts = tok_alloc_new(pts, (char *) p1, len);
         token_found: ;
         } else {
             /* slower case */
             cstr_reset(&tokcstr);
-
-            while (p1 < p) {
-                cstr_ccat(&tokcstr, *p1);
-                p1++;
-            }
+            cstr_cat(&tokcstr, (char *) p1, len);
             p--;
             PEEKC(c, p);
         parse_ident_slow:
-            while (isidnum_table[c-CH_EOF]) {
+            while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+            {
                 cstr_ccat(&tokcstr, c);
                 PEEKC(c, p);
@@ -2262,39 +2748,55 @@
         }
         break;
+
     case '0': case '1': case '2': case '3':
     case '4': case '5': case '6': case '7':
     case '8': case '9':
-
-        cstr_reset(&tokcstr);
+        t = c;
+        PEEKC(c, p);
         /* after the first digit, accept digits, alpha, '.' or sign if
            prefixed by 'eEpP' */
     parse_num:
+        cstr_reset(&tokcstr);
         for(;;) {
+            cstr_ccat(&tokcstr, t);
+            if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+                  || c == '.'
+                  || ((c == '+' || c == '-')
+                      && (((t == 'e' || t == 'E')
+                            && !(parse_flags & PARSE_FLAG_ASM_FILE
+                                /* 0xe+1 is 3 tokens in asm */
+                                && ((char*)tokcstr.data)[0] == '0'
+                                && toup(((char*)tokcstr.data)[1]) == 'X'))
+                          || t == 'p' || t == 'P'))))
+                break;
             t = c;
-            cstr_ccat(&tokcstr, c);
             PEEKC(c, p);
-            if (!(isnum(c) || isid(c) || c == '.' ||
-                  ((c == '+' || c == '-') && 
-                   (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
-                break;
         }
         /* We add a trailing '\0' to ease parsing */
         cstr_ccat(&tokcstr, '\0');
-        tokc.cstr = &tokcstr;
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
         tok = TOK_PPNUM;
         break;
+
     case '.':
         /* special dot handling because it can also start a number */
         PEEKC(c, p);
         if (isnum(c)) {
-            cstr_reset(&tokcstr);
-            cstr_ccat(&tokcstr, '.');
+            t = '.';
             goto parse_num;
+        } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
+                   && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
+            *--p = c = '.';
+            goto parse_ident_fast;
         } else if (c == '.') {
             PEEKC(c, p);
-            if (c != '.')
-                expect("'.'");
-            PEEKC(c, p);
-            tok = TOK_DOTS;
+            if (c == '.') {
+                p++;
+                tok = TOK_DOTS;
+            } else {
+                *--p = '.'; /* may underflow into file->unget[] */
+                tok = '.';
+            }
         } else {
             tok = '.';
@@ -2305,46 +2807,14 @@
         is_long = 0;
     str_const:
-        {
-            CString str;
-            int sep;
-
-            sep = c;
-
-            /* parse the string */
-            cstr_new(&str);
-            p = parse_pp_string(p, sep, &str);
-            cstr_ccat(&str, '\0');
-            
-            /* eval the escape (should be done as TOK_PPNUM) */
-            cstr_reset(&tokcstr);
-            parse_escape_string(&tokcstr, str.data, is_long);
-            cstr_free(&str);
-
-            if (sep == '\'') {
-                int char_size;
-                /* XXX: make it portable */
-                if (!is_long)
-                    char_size = 1;
-                else
-                    char_size = sizeof(nwchar_t);
-                if (tokcstr.size <= char_size)
-                    tcc_error("empty character constant");
-                if (tokcstr.size > 2 * char_size)
-                    tcc_warning("multi-character character constant");
-                if (!is_long) {
-                    tokc.i = *(int8_t *)tokcstr.data;
-                    tok = TOK_CCHAR;
-                } else {
-                    tokc.i = *(nwchar_t *)tokcstr.data;
-                    tok = TOK_LCHAR;
-                }
-            } else {
-                tokc.cstr = &tokcstr;
-                if (!is_long)
-                    tok = TOK_STR;
-                else
-                    tok = TOK_LSTR;
-            }
-        }
+        cstr_reset(&tokcstr);
+        if (is_long)
+            cstr_ccat(&tokcstr, 'L');
+        cstr_ccat(&tokcstr, c);
+        p = parse_pp_string(p, c, &tokcstr);
+        cstr_ccat(&tokcstr, c);
+        cstr_ccat(&tokcstr, '\0');
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
+        tok = TOK_PPSTR;
         break;
 
@@ -2366,5 +2836,4 @@
         }
         break;
-        
     case '>':
         PEEKC(c, p);
@@ -2478,10 +2947,14 @@
     case '?':
     case '~':
-    case '$': /* only used in assembler */
-    case '@': /* dito */
+    case '@': /* only used in assembler */
+    parse_simple:
         tok = c;
         p++;
         break;
     default:
+        if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
+	    goto parse_ident_fast;
+        if (parse_flags & PARSE_FLAG_ASM_FILE)
+            goto parse_simple;
         tcc_error("unrecognized character \\x%02x", c);
         break;
@@ -2491,5 +2964,5 @@
     file->buf_ptr = p;
 #if defined(PARSE_DEBUG)
-    printf("token = %s\n", get_tok_str(tok, &tokc));
+    printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
 #endif
 }
@@ -2512,4 +2985,5 @@
         next_nomacro1();
     }
+    //printf("token = %s\n", get_tok_str(tok, &tokc));
 }
 
@@ -2518,11 +2992,19 @@
     do {
         next_nomacro_spc();
-    } while (is_space(tok));
+    } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
 }
  
-/* substitute args in macro_str and return allocated string */
+
+static void macro_subst(
+    TokenString *tok_str,
+    Sym **nested_list,
+    const int *macro_str
+    );
+
+/* substitute arguments in replacement lists in macro_str by the values in
+   args (field d) and return allocated string */
 static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
 {
-    int last_tok, t, spc;
+    int t, t0, t1, spc;
     const int *st;
     Sym *s;
@@ -2532,5 +3014,5 @@
 
     tok_str_new(&str);
-    last_tok = 0;
+    t0 = t1 = 0;
     while(1) {
         TOK_GET(&t, &macro_str, &cval);
@@ -2541,42 +3023,52 @@
             TOK_GET(&t, &macro_str, &cval);
             if (!t)
-                break;
+                goto bad_stringy;
             s = sym_find2(args, t);
             if (s) {
                 cstr_new(&cstr);
+                cstr_ccat(&cstr, '\"');
                 st = s->d;
                 spc = 0;
-                while (*st) {
+                while (*st >= 0) {
                     TOK_GET(&t, &st, &cval);
-                    if (!check_space(t, &spc))
-                        cstr_cat(&cstr, get_tok_str(t, &cval));
+                    if (t != TOK_PLCHLDR
+                     && t != TOK_NOSUBST
+                     && 0 == check_space(t, &spc)) {
+                        const char *s = get_tok_str(t, &cval);
+                        while (*s) {
+                            if (t == TOK_PPSTR && *s != '\'')
+                                add_char(&cstr, *s);
+                            else
+                                cstr_ccat(&cstr, *s);
+                            ++s;
+                        }
+                    }
                 }
                 cstr.size -= spc;
+                cstr_ccat(&cstr, '\"');
                 cstr_ccat(&cstr, '\0');
 #ifdef PP_DEBUG
-                printf("stringize: %s\n", (char *)cstr.data);
+                printf("\nstringize: <%s>\n", (char *)cstr.data);
 #endif
                 /* add string */
-                cval.cstr = &cstr;
-                tok_str_add2(&str, TOK_STR, &cval);
+                cval.str.size = cstr.size;
+                cval.str.data = cstr.data;
+                tok_str_add2(&str, TOK_PPSTR, &cval);
                 cstr_free(&cstr);
             } else {
-                tok_str_add2(&str, t, &cval);
+        bad_stringy:
+                expect("macro parameter after '#'");
             }
         } else if (t >= TOK_IDENT) {
             s = sym_find2(args, t);
             if (s) {
+                int l0 = str.len;
                 st = s->d;
                 /* if '##' is present before or after, no arg substitution */
-                if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
-                    /* special case for var arg macros : ## eats the
-                       ',' if empty VA_ARGS variable. */
-                    /* XXX: test of the ',' is not 100%
-                       reliable. should fix it to avoid security
-                       problems */
-                    if (gnu_ext && s->type.t &&
-                        last_tok == TOK_TWOSHARPS && 
-                        str.len >= 2 && str.str[str.len - 2] == ',') {
-                        if (*st == 0) {
+                if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
+                    /* special case for var arg macros : ## eats the ','
+                       if empty VA_ARGS variable. */
+                    if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
+                        if (*st <= 0) {
                             /* suppress ',' '##' */
                             str.len -= 2;
@@ -2586,19 +3078,30 @@
                             goto add_var;
                         }
-                    } else {
-                        int t1;
-                    add_var:
-                        for(;;) {
-                            TOK_GET(&t1, &st, &cval);
-                            if (!t1)
-                                break;
-                            tok_str_add2(&str, t1, &cval);
-                        }
                     }
                 } else {
-                    /* NOTE: the stream cannot be read when macro
-                       substituing an argument */
-                    macro_subst(&str, nested_list, st, NULL);
+            add_var:
+		    if (!s->next) {
+			/* Expand arguments tokens and store them.  In most
+			   cases we could also re-expand each argument if
+			   used multiple times, but not if the argument
+			   contains the __COUNTER__ macro.  */
+			TokenString str2;
+			sym_push2(&s->next, s->v, s->type.t, 0);
+			tok_str_new(&str2);
+			macro_subst(&str2, nested_list, st);
+			tok_str_add(&str2, 0);
+			s->next->d = str2.str;
+		    }
+		    st = s->next->d;
                 }
+                for(;;) {
+                    int t2;
+                    TOK_GET(&t2, &st, &cval);
+                    if (t2 <= 0)
+                        break;
+                    tok_str_add2(&str, t2, &cval);
+                }
+                if (str.len == l0) /* expanded to empty string */
+                    tok_str_add(&str, TOK_PLCHLDR);
             } else {
                 tok_str_add(&str, t);
@@ -2607,5 +3110,5 @@
             tok_str_add2(&str, t, &cval);
         }
-        last_tok = t;
+        t0 = t1, t1 = t;
     }
     tok_str_add(&str, 0);
@@ -2618,4 +3121,158 @@
     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 };
+
+static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
+{
+    CString cstr;
+    int n, ret = 1;
+
+    cstr_new(&cstr);
+    if (t1 != TOK_PLCHLDR)
+        cstr_cat(&cstr, get_tok_str(t1, v1), -1);
+    n = cstr.size;
+    if (t2 != TOK_PLCHLDR)
+        cstr_cat(&cstr, get_tok_str(t2, v2), -1);
+    cstr_ccat(&cstr, '\0');
+
+    tcc_open_bf(tcc_state, ":paste:", cstr.size);
+    memcpy(file->buffer, cstr.data, cstr.size);
+    tok_flags = 0;
+    for (;;) {
+        next_nomacro1();
+        if (0 == *file->buf_ptr)
+            break;
+        if (is_space(tok))
+            continue;
+        tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
+            " preprocessing token", n, cstr.data, (char*)cstr.data + n);
+        ret = 0;
+        break;
+    }
+    tcc_close();
+    //printf("paste <%s>\n", (char*)cstr.data);
+    cstr_free(&cstr);
+    return ret;
+}
+
+/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
+   return the resulting string (which must be freed). */
+static inline int *macro_twosharps(const int *ptr0)
+{
+    int t;
+    CValue cval;
+    TokenString macro_str1;
+    int start_of_nosubsts = -1;
+    const int *ptr;
+
+    /* we search the first '##' */
+    for (ptr = ptr0;;) {
+        TOK_GET(&t, &ptr, &cval);
+        if (t == TOK_PPJOIN)
+            break;
+        if (t == 0)
+            return NULL;
+    }
+
+    tok_str_new(&macro_str1);
+
+    //tok_print(" $$$", ptr0);
+    for (ptr = ptr0;;) {
+        TOK_GET(&t, &ptr, &cval);
+        if (t == 0)
+            break;
+        if (t == TOK_PPJOIN)
+            continue;
+        while (*ptr == TOK_PPJOIN) {
+            int t1; CValue cv1;
+            /* given 'a##b', remove nosubsts preceding 'a' */
+            if (start_of_nosubsts >= 0)
+                macro_str1.len = start_of_nosubsts;
+            /* given 'a##b', remove nosubsts preceding 'b' */
+            while ((t1 = *++ptr) == TOK_NOSUBST)
+                ;
+            if (t1 && t1 != TOK_PPJOIN) {
+                TOK_GET(&t1, &ptr, &cv1);
+                if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
+                    if (paste_tokens(t, &cval, t1, &cv1)) {
+                        t = tok, cval = tokc;
+                    } else {
+                        tok_str_add2(&macro_str1, t, &cval);
+                        t = t1, cval = cv1;
+                    }
+                }
+            }
+        }
+        if (t == TOK_NOSUBST) {
+            if (start_of_nosubsts < 0)
+                start_of_nosubsts = macro_str1.len;
+        } else {
+            start_of_nosubsts = -1;
+        }
+        tok_str_add2(&macro_str1, t, &cval);
+    }
+    tok_str_add(&macro_str1, 0);
+    //tok_print(" ###", macro_str1.str);
+    return macro_str1.str;
+}
+
+/* peek or read [ws_str == NULL] next token from function macro call,
+   walking up macro levels up to the file if necessary */
+static int next_argstream(Sym **nested_list, TokenString *ws_str)
+{
+    int t;
+    const int *p;
+    Sym *sa;
+
+    for (;;) {
+        if (macro_ptr) {
+            p = macro_ptr, t = *p;
+            if (ws_str) {
+                while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
+                    tok_str_add(ws_str, t), t = *++p;
+            }
+            if (t == 0) {
+                end_macro();
+                /* also, end of scope for nested defined symbol */
+                sa = *nested_list;
+                while (sa && sa->v == 0)
+                    sa = sa->prev;
+                if (sa)
+                    sa->v = 0;
+                continue;
+            }
+        } else {
+            ch = handle_eob();
+            if (ws_str) {
+                while (is_space(ch) || ch == '\n' || ch == '/') {
+                    if (ch == '/') {
+                        int c;
+                        uint8_t *p = file->buf_ptr;
+                        PEEKC(c, p);
+                        if (c == '*') {
+                            p = parse_comment(p);
+                            file->buf_ptr = p - 1;
+                        } else if (c == '/') {
+                            p = parse_line_comment(p);
+                            file->buf_ptr = p - 1;
+                        } else
+                            break;
+                        ch = ' ';
+                    }
+                    if (ch == '\n')
+                        file->line_num++;
+                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
+                        tok_str_add(ws_str, ch);
+                    cinp();
+                }
+            }
+            t = ch;
+        }
+
+        if (ws_str)
+            return t;
+        next_nomacro_spc();
+        return tok;
+    }
+}
 
 /* do macro substitution of current token with macro 's' and add
@@ -2623,10 +3280,11 @@
    macros we got inside to avoid recursing. Return non zero if no
    substitution needs to be done */
-static int macro_subst_tok(TokenString *tok_str,
-                           Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
+static int macro_subst_tok(
+    TokenString *tok_str,
+    Sym **nested_list,
+    Sym *s)
 {
     Sym *args, *sa, *sa1;
-    int mstr_allocated, parlevel, *mstr, t, t1, spc;
-    const int *p;
+    int parlevel, t, t1, spc;
     TokenString str;
     char *cstrval;
@@ -2634,9 +3292,10 @@
     CString cstr;
     char buf[32];
-    
+
     /* if symbol is a macro, prepare substitution */
     /* special macros */
-    if (tok == TOK___LINE__) {
-        snprintf(buf, sizeof(buf), "%d", file->line_num);
+    if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
+        t = tok == TOK___LINE__ ? file->line_num : pp_counter++;
+        snprintf(buf, sizeof(buf), "%d", t);
         cstrval = buf;
         t1 = TOK_PPNUM;
@@ -2663,67 +3322,55 @@
     add_cstr1:
         cstr_new(&cstr);
-        cstr_cat(&cstr, cstrval);
-        cstr_ccat(&cstr, '\0');
-        cval.cstr = &cstr;
+        cstr_cat(&cstr, cstrval, 0);
+        cval.str.size = cstr.size;
+        cval.str.data = cstr.data;
         tok_str_add2(tok_str, t1, &cval);
         cstr_free(&cstr);
-    } else {
-        mstr = s->d;
-        mstr_allocated = 0;
+    } else if (s->d) {
+        int saved_parse_flags = parse_flags;
+	int *joined_str = NULL;
+        int *mstr = s->d;
+
         if (s->type.t == MACRO_FUNC) {
-            /* NOTE: we do not use next_nomacro to avoid eating the
-               next token. XXX: find better solution */
-        redo:
-            if (macro_ptr) {
-                p = macro_ptr;
-                while (is_space(t = *p) || TOK_LINEFEED == t) 
-                    ++p;
-                if (t == 0 && can_read_stream) {
-                    /* end of macro stream: we must look at the token
-                       after in the file */
-                    struct macro_level *ml = *can_read_stream;
-                    macro_ptr = NULL;
-                    if (ml)
-                    {
-                        macro_ptr = ml->p;
-                        ml->p = NULL;
-                        *can_read_stream = ml -> prev;
-                    }
-                    /* also, end of scope for nested defined symbol */
-                    (*nested_list)->v = -1;
-                    goto redo;
+            /* whitespace between macro name and argument list */
+            TokenString ws_str;
+            tok_str_new(&ws_str);
+
+            spc = 0;
+            parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
+                | PARSE_FLAG_ACCEPT_STRAYS;
+
+            /* get next token from argument stream */
+            t = next_argstream(nested_list, &ws_str);
+            if (t != '(') {
+                /* not a macro substitution after all, restore the
+                 * macro token plus all whitespace we've read.
+                 * whitespace is intentionally not merged to preserve
+                 * newlines. */
+                parse_flags = saved_parse_flags;
+                tok_str_add(tok_str, tok);
+                if (parse_flags & PARSE_FLAG_SPACES) {
+                    int i;
+                    for (i = 0; i < ws_str.len; i++)
+                        tok_str_add(tok_str, ws_str.str[i]);
                 }
+                tok_str_free_str(ws_str.str);
+                return 0;
             } else {
-                ch = file->buf_ptr[0];
-                while (is_space(ch) || ch == '\n' || ch == '/')
-		  {
-		    if (ch == '/')
-		      {
-			int c;
-			uint8_t *p = file->buf_ptr;
-			PEEKC(c, p);
-			if (c == '*') {
-			    p = parse_comment(p);
-			    file->buf_ptr = p - 1;
-			} else if (c == '/') {
-			    p = parse_line_comment(p);
-			    file->buf_ptr = p - 1;
-			} else
-			  break;
-		      }
-		    cinp();
-		  }
-                t = ch;
-            }
-            if (t != '(') /* no macro subst */
-                return -1;
-                    
+                tok_str_free_str(ws_str.str);
+            }
+	    do {
+		next_nomacro(); /* eat '(' */
+	    } while (tok == TOK_PLCHLDR);
+
             /* argument macro */
-            next_nomacro();
-            next_nomacro();
             args = NULL;
             sa = s->next;
             /* NOTE: empty args are allowed, except if no args */
             for(;;) {
+                do {
+                    next_argstream(nested_list, NULL);
+                } while (is_space(tok) || TOK_LINEFEED == tok);
+    empty_arg:
                 /* handle '()' case */
                 if (!args && !sa && tok == ')')
@@ -2737,6 +3384,7 @@
                 while ((parlevel > 0 || 
                         (tok != ')' && 
-                         (tok != ',' || sa->type.t))) && 
-                       tok != -1) {
+                         (tok != ',' || sa->type.t)))) {
+                    if (tok == TOK_EOF || tok == 0)
+                        break;
                     if (tok == '(')
                         parlevel++;
@@ -2747,7 +3395,10 @@
                     if (!check_space(tok, &spc))
                         tok_str_add2(&str, tok, &tokc);
-                    next_nomacro_spc();
+                    next_argstream(nested_list, NULL);
                 }
+                if (parlevel)
+                    expect(")");
                 str.len -= spc;
+                tok_str_add(&str, -1);
                 tok_str_add(&str, 0);
                 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
@@ -2758,11 +3409,9 @@
                        var arg argument if it is omitted */
                     if (sa && sa->type.t && gnu_ext)
-                        continue;
-                    else
-                        break;
+                        goto empty_arg;
+                    break;
                 }
                 if (tok != ',')
                     expect(",");
-                next_nomacro();
             }
             if (sa) {
@@ -2770,4 +3419,6 @@
                       get_tok_str(s->v, 0));
             }
+
+            parse_flags = saved_parse_flags;
 
             /* now subst each arg */
@@ -2777,135 +3428,56 @@
             while (sa) {
                 sa1 = sa->prev;
-                tok_str_free(sa->d);
+                tok_str_free_str(sa->d);
+                if (sa->next) {
+                    tok_str_free_str(sa->next->d);
+                    sym_free(sa->next);
+                }
                 sym_free(sa);
                 sa = sa1;
             }
-            mstr_allocated = 1;
-        }
+        }
+
         sym_push2(nested_list, s->v, 0, 0);
-        macro_subst(tok_str, nested_list, mstr, can_read_stream);
+        parse_flags = saved_parse_flags;
+        joined_str = macro_twosharps(mstr);
+        macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr);
+
         /* pop nested defined symbol */
         sa1 = *nested_list;
         *nested_list = sa1->prev;
         sym_free(sa1);
-        if (mstr_allocated)
-            tok_str_free(mstr);
+	if (joined_str)
+	    tok_str_free_str(joined_str);
+        if (mstr != s->d)
+            tok_str_free_str(mstr);
     }
     return 0;
 }
-
-/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
-   return the resulting string (which must be freed). */
-static inline int *macro_twosharps(const int *macro_str)
-{
-    const int *ptr;
-    int t;
-    TokenString macro_str1;
-    CString cstr;
-    int n, start_of_nosubsts;
-
-    /* we search the first '##' */
-    for(ptr = macro_str;;) {
-        CValue cval;
-        TOK_GET(&t, &ptr, &cval);
-        if (t == TOK_TWOSHARPS)
-            break;
-        /* nothing more to do if end of string */
-        if (t == 0)
-            return NULL;
-    }
-
-    /* we saw '##', so we need more processing to handle it */
-    start_of_nosubsts = -1;
-    tok_str_new(&macro_str1);
-    for(ptr = macro_str;;) {
-        TOK_GET(&tok, &ptr, &tokc);
-        if (tok == 0)
-            break;
-        if (tok == TOK_TWOSHARPS)
-            continue;
-        if (tok == TOK_NOSUBST && start_of_nosubsts < 0)
-            start_of_nosubsts = macro_str1.len;
-        while (*ptr == TOK_TWOSHARPS) {
-            /* given 'a##b', remove nosubsts preceding 'a' */
-            if (start_of_nosubsts >= 0)
-                macro_str1.len = start_of_nosubsts;
-            /* given 'a##b', skip '##' */
-            t = *++ptr;
-            /* given 'a##b', remove nosubsts preceding 'b' */
-            while (t == TOK_NOSUBST)
-                t = *++ptr;
-            if (t && t != TOK_TWOSHARPS) {
-                CValue cval;
-                TOK_GET(&t, &ptr, &cval);
-                /* We concatenate the two tokens */
-                cstr_new(&cstr);
-                cstr_cat(&cstr, get_tok_str(tok, &tokc));
-                n = cstr.size;
-                cstr_cat(&cstr, get_tok_str(t, &cval));
-                cstr_ccat(&cstr, '\0');
-
-                tcc_open_bf(tcc_state, ":paste:", cstr.size);
-                memcpy(file->buffer, cstr.data, cstr.size);
-                for (;;) {
-                    next_nomacro1();
-                    if (0 == *file->buf_ptr)
-                        break;
-                    tok_str_add2(&macro_str1, tok, &tokc);
-                    tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid preprocessing token",
-                        n, cstr.data, (char*)cstr.data + n);
-                }
-                tcc_close();
-                cstr_free(&cstr);
-            }
-        }
-        if (tok != TOK_NOSUBST) 
-            start_of_nosubsts = -1;
-        tok_str_add2(&macro_str1, tok, &tokc);
-    }
-    tok_str_add(&macro_str1, 0);
-    return macro_str1.str;
-}
-
 
 /* do macro substitution of macro_str and add result to
    (tok_str,tok_len). 'nested_list' is the list of all macros we got
    inside to avoid recursing. */
-static void macro_subst(TokenString *tok_str, Sym **nested_list, 
-                        const int *macro_str, struct macro_level ** can_read_stream)
+static void macro_subst(
+    TokenString *tok_str,
+    Sym **nested_list,
+    const int *macro_str
+    )
 {
     Sym *s;
-    int *macro_str1;
-    const int *ptr;
-    int t, ret, spc;
+    int t, spc, nosubst;
     CValue cval;
-    struct macro_level ml;
-    int force_blank;
     
-    /* first scan for '##' operator handling */
-    ptr = macro_str;
-    macro_str1 = macro_twosharps(ptr);
-
-    if (macro_str1) 
-        ptr = macro_str1;
-    spc = 0;
-    force_blank = 0;
+    spc = nosubst = 0;
 
     while (1) {
-        /* NOTE: ptr == NULL can only happen if tokens are read from
-           file stream due to a macro function call */
-        if (ptr == NULL)
+        TOK_GET(&t, &macro_str, &cval);
+        if (t <= 0)
             break;
-        TOK_GET(&t, &ptr, &cval);
-        if (t == 0)
-            break;
-        if (t == TOK_NOSUBST) {
-            /* following token has already been subst'd. just copy it on */
-            tok_str_add2(tok_str, TOK_NOSUBST, NULL);
-            TOK_GET(&t, &ptr, &cval);
-            goto no_subst;
-        }
-        s = define_find(t);
-        if (s != NULL) {
+
+        if (t >= TOK_IDENT && 0 == nosubst) {
+            s = define_find(t);
+            if (s == NULL)
+                goto no_subst;
+
             /* if nested substitution, do nothing */
             if (sym_find2(*nested_list, t)) {
@@ -2914,31 +3486,42 @@
                 goto no_subst;
             }
-            ml.p = macro_ptr;
-            if (can_read_stream)
-                ml.prev = *can_read_stream, *can_read_stream = &ml;
-            macro_ptr = (int *)ptr;
-            tok = t;
-            ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
-            ptr = (int *)macro_ptr;
-            macro_ptr = ml.p;
-            if (can_read_stream && *can_read_stream == &ml)
-                *can_read_stream = ml.prev;
-            if (ret != 0)
-                goto no_subst;
-            if (parse_flags & PARSE_FLAG_SPACES)
-                force_blank = 1;
+
+            {
+                TokenString str;
+                str.str = (int*)macro_str;
+                begin_macro(&str, 2);
+
+                tok = t;
+                macro_subst_tok(tok_str, nested_list, s);
+
+                if (str.alloc == 3) {
+                    /* already finished by reading function macro arguments */
+                    break;
+                }
+
+                macro_str = macro_ptr;
+                end_macro ();
+            }
+            if (tok_str->len)
+                spc = is_space(t = tok_str->str[tok_str->lastlen]);
         } else {
-        no_subst:
-            if (force_blank) {
-                tok_str_add(tok_str, ' ');
-                spc = 1;
-                force_blank = 0;
-            }
-            if (!check_space(t, &spc)) 
+            if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+                tcc_error("stray '\\' in program");
+no_subst:
+            if (!check_space(t, &spc))
                 tok_str_add2(tok_str, t, &cval);
-        }
-    }
-    if (macro_str1)
-        tok_str_free(macro_str1);
+
+            if (nosubst) {
+                if (nosubst > 1 && (spc || (++nosubst == 3 && t == '(')))
+                    continue;
+                nosubst = 0;
+            }
+            if (t == TOK_NOSUBST)
+                nosubst = 1;
+        }
+        /* GCC supports 'defined' as result of a macro substitution */
+        if (t == TOK_DEFINED && pp_expr)
+            nosubst = 2;
+    }
 }
 
@@ -2946,8 +3529,4 @@
 ST_FUNC void next(void)
 {
-    Sym *nested_list, *s;
-    TokenString str;
-    struct macro_level *ml;
-
  redo:
     if (parse_flags & PARSE_FLAG_SPACES)
@@ -2955,47 +3534,34 @@
     else
         next_nomacro();
-    if (!macro_ptr) {
-        /* if not reading from macro substituted string, then try
-           to substitute macros */
-        if (tok >= TOK_IDENT &&
-            (parse_flags & PARSE_FLAG_PREPROCESS)) {
-            s = define_find(tok);
-            if (s) {
-                /* we have a macro: we try to substitute */
-                tok_str_new(&str);
-                nested_list = NULL;
-                ml = NULL;
-                if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
-                    /* substitution done, NOTE: maybe empty */
-                    tok_str_add(&str, 0);
-                    macro_ptr = str.str;
-                    macro_ptr_allocated = str.str;
-                    goto redo;
-                }
-            }
-        }
-    } else {
-        if (tok == 0) {
-            /* end of macro or end of unget buffer */
-            if (unget_buffer_enabled) {
-                macro_ptr = unget_saved_macro_ptr;
-                unget_buffer_enabled = 0;
-            } else {
-                /* end of macro string: free it */
-                tok_str_free(macro_ptr_allocated);
-                macro_ptr_allocated = NULL;
-                macro_ptr = NULL;
-            }
+
+    if (macro_ptr) {
+        if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
+        /* discard preprocessor markers */
             goto redo;
-        } else if (tok == TOK_NOSUBST) {
-            /* discard preprocessor's nosubst markers */
+        } else if (tok == 0) {
+            /* end of macro or unget token string */
+            end_macro();
             goto redo;
         }
-    }
-    
+    } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
+        Sym *s;
+        /* if reading from file, try to substitute macros */
+        s = define_find(tok);
+        if (s) {
+            Sym *nested_list = NULL;
+            tokstr_buf.len = 0;
+            macro_subst_tok(&tokstr_buf, &nested_list, s);
+            tok_str_add(&tokstr_buf, 0);
+            begin_macro(&tokstr_buf, 2);
+            goto redo;
+        }
+    }
     /* convert preprocessor tokens into C tokens */
-    if (tok == TOK_PPNUM &&
-        (parse_flags & PARSE_FLAG_TOK_NUM)) {
-        parse_number((char *)tokc.cstr->data);
+    if (tok == TOK_PPNUM) {
+        if  (parse_flags & PARSE_FLAG_TOK_NUM)
+            parse_number((char *)tokc.str.data);
+    } else if (tok == TOK_PPSTR) {
+        if (parse_flags & PARSE_FLAG_TOK_STR)
+            parse_string((char *)tokc.str.data, tokc.str.size - 1);
     }
 }
@@ -3005,54 +3571,95 @@
 ST_INLN void unget_tok(int last_tok)
 {
-    int i, n;
-    int *q;
-    if (unget_buffer_enabled)
-      {
-        /* assert(macro_ptr == unget_saved_buffer + 1);
-	   assert(*macro_ptr == 0);  */
-      }
-    else
-      {
-	unget_saved_macro_ptr = macro_ptr;
-	unget_buffer_enabled = 1;
-      }
-    q = unget_saved_buffer;
-    macro_ptr = q;
-    *q++ = tok;
-    n = tok_ext_size(tok) - 1;
-    for(i=0;i<n;i++)
-        *q++ = tokc.tab[i];
-    *q = 0; /* end of token string */
+
+    TokenString *str = tok_str_alloc();
+    tok_str_add2(str, tok, &tokc);
+    tok_str_add(str, 0);
+    begin_macro(str, 1);
     tok = last_tok;
 }
 
-
-/* better than nothing, but needs extension to handle '-E' option
-   correctly too */
-ST_FUNC void preprocess_init(TCCState *s1)
-{
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
+{
+    CString cstr;
+    int i;
+
     s1->include_stack_ptr = s1->include_stack;
-    /* XXX: move that before to avoid having to initialize
-       file->ifdef_stack_ptr ? */
     s1->ifdef_stack_ptr = s1->ifdef_stack;
     file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
-
-    vtop = vstack - 1;
+    pp_expr = 0;
+    pp_counter = 0;
+    pp_debug_tok = pp_debug_symv = 0;
+    pp_once++;
+    pvtop = vtop = vstack - 1;
     s1->pack_stack[0] = 0;
     s1->pack_stack_ptr = s1->pack_stack;
-}
-
-ST_FUNC void preprocess_new(void)
+
+    set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
+    set_idnum('.', is_asm ? IS_ID : 0);
+
+    cstr_new(&cstr);
+    cstr_cat(&cstr, "\"", -1);
+    cstr_cat(&cstr, file->filename, -1);
+    cstr_cat(&cstr, "\"", 0);
+    tcc_define_symbol(s1, "__BASE_FILE__", cstr.data);
+
+    cstr_reset(&cstr);
+    for (i = 0; i < s1->nb_cmd_include_files; i++) {
+        cstr_cat(&cstr, "#include \"", -1);
+        cstr_cat(&cstr, s1->cmd_include_files[i], -1);
+        cstr_cat(&cstr, "\"\n", -1);
+    }
+    if (cstr.size) {
+        *s1->include_stack_ptr++ = file;
+	tcc_open_bf(s1, "<command line>", cstr.size);
+	memcpy(file->buffer, cstr.data, cstr.size);
+    }
+    cstr_free(&cstr);
+
+    if (is_asm)
+        tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
+
+    parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+/* cleanup from error/setjmp */
+ST_FUNC void preprocess_end(TCCState *s1)
+{
+    while (macro_stack)
+        end_macro();
+    macro_ptr = NULL;
+}
+
+ST_FUNC void tccpp_new(TCCState *s)
 {
     int i, c;
     const char *p, *r;
 
+    /* might be used in error() before preprocess_start() */
+    s->include_stack_ptr = s->include_stack;
+    s->ppfp = stdout;
+
     /* init isid table */
-    for(i=CH_EOF;i<256;i++)
-        isidnum_table[i-CH_EOF] = isid(i) || isnum(i);
-
-    /* add all tokens */
-    table_ident = NULL;
+    for(i = CH_EOF; i<128; i++)
+        set_idnum(i,
+            is_space(i) ? IS_SPC
+            : isid(i) ? IS_ID
+            : isnum(i) ? IS_NUM
+            : 0);
+
+    for(i = 128; i<256; i++)
+        set_idnum(i, IS_ID);
+
+    /* init allocators */
+    tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
+    tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
+    tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE);
+
     memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
+    cstr_new(&cstr_buf);
+    cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
+    tok_str_new(&tokstr_buf);
+    tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
     
     tok_ident = TOK_IDENT;
@@ -3070,59 +3677,227 @@
 }
 
+ST_FUNC void tccpp_delete(TCCState *s)
+{
+    int i, n;
+
+    /* free -D and compiler defines */
+    free_defines(NULL);
+
+    /* free tokens */
+    n = tok_ident - TOK_IDENT;
+    for(i = 0; i < n; i++)
+        tal_free(toksym_alloc, table_ident[i]);
+    tcc_free(table_ident);
+    table_ident = NULL;
+
+    /* free static buffers */
+    cstr_free(&tokcstr);
+    cstr_free(&cstr_buf);
+    cstr_free(&macro_equal_buf);
+    tok_str_free_str(tokstr_buf.str);
+
+    /* free allocators */
+    tal_delete(toksym_alloc);
+    toksym_alloc = NULL;
+    tal_delete(tokstr_alloc);
+    tokstr_alloc = NULL;
+    tal_delete(cstr_alloc);
+    cstr_alloc = NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+/* tcc -E [-P[1]] [-dD} support */
+
+static void tok_print(const char *msg, const int *str)
+{
+    FILE *fp;
+    int t, s = 0;
+    CValue cval;
+
+    fp = tcc_state->ppfp;
+    fprintf(fp, "%s", msg);
+    while (str) {
+	TOK_GET(&t, &str, &cval);
+	if (!t)
+	    break;
+	fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
+    }
+    fprintf(fp, "\n");
+}
+
+static void pp_line(TCCState *s1, BufferedFile *f, int level)
+{
+    int d = f->line_num - f->line_ref;
+
+    if (s1->dflag & 4)
+	return;
+
+    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
+        ;
+    } else if (level == 0 && f->line_ref && d < 8) {
+	while (d > 0)
+	    fputs("\n", s1->ppfp), --d;
+    } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
+	fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
+    } else {
+	fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
+	    level > 0 ? " 1" : level < 0 ? " 2" : "");
+    }
+    f->line_ref = f->line_num;
+}
+
+static void define_print(TCCState *s1, int v)
+{
+    FILE *fp;
+    Sym *s;
+
+    s = define_find(v);
+    if (NULL == s || NULL == s->d)
+        return;
+
+    fp = s1->ppfp;
+    fprintf(fp, "#define %s", get_tok_str(v, NULL));
+    if (s->type.t == MACRO_FUNC) {
+        Sym *a = s->next;
+        fprintf(fp,"(");
+        if (a)
+            for (;;) {
+                fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
+                if (!(a = a->next))
+                    break;
+                fprintf(fp,",");
+            }
+        fprintf(fp,")");
+    }
+    tok_print("", s->d);
+}
+
+static void pp_debug_defines(TCCState *s1)
+{
+    int v, t;
+    const char *vs;
+    FILE *fp;
+
+    t = pp_debug_tok;
+    if (t == 0)
+        return;
+
+    file->line_num--;
+    pp_line(s1, file, 0);
+    file->line_ref = ++file->line_num;
+
+    fp = s1->ppfp;
+    v = pp_debug_symv;
+    vs = get_tok_str(v, NULL);
+    if (t == TOK_DEFINE) {
+        define_print(s1, v);
+    } else if (t == TOK_UNDEF) {
+        fprintf(fp, "#undef %s\n", vs);
+    } else if (t == TOK_push_macro) {
+        fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
+    } else if (t == TOK_pop_macro) {
+        fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
+    }
+    pp_debug_tok = 0;
+}
+
+static void pp_debug_builtins(TCCState *s1)
+{
+    int v;
+    for (v = TOK_IDENT; v < tok_ident; ++v)
+        define_print(s1, v);
+}
+
+/* Add a space between tokens a and b to avoid unwanted textual pasting */
+static int pp_need_space(int a, int b)
+{
+    return 'E' == a ? '+' == b || '-' == b
+        : '+' == a ? TOK_INC == b || '+' == b
+        : '-' == a ? TOK_DEC == b || '-' == b
+        : a >= TOK_IDENT ? b >= TOK_IDENT
+	: a == TOK_PPNUM ? b >= TOK_IDENT
+        : 0;
+}
+
+/* maybe hex like 0x1e */
+static int pp_check_he0xE(int t, const char *p)
+{
+    if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
+        return 'E';
+    return t;
+}
+
 /* Preprocess the current file */
 ST_FUNC int tcc_preprocess(TCCState *s1)
 {
-    Sym *define_start;
-
-    BufferedFile *file_ref, **iptr, **iptr_new;
-    int token_seen, line_ref, d;
-    const char *s;
-
-    preprocess_init(s1);
-    define_start = define_stack;
-    ch = file->buf_ptr[0];
-    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
-    parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
-        PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
-    token_seen = 0;
-    line_ref = 0;
-    file_ref = NULL;
-    iptr = s1->include_stack_ptr;
-
+    BufferedFile **iptr;
+    int token_seen, spcs, level;
+    const char *p;
+    char white[400];
+
+    parse_flags = PARSE_FLAG_PREPROCESS
+                | (parse_flags & PARSE_FLAG_ASM_FILE)
+                | PARSE_FLAG_LINEFEED
+                | PARSE_FLAG_SPACES
+                | PARSE_FLAG_ACCEPT_STRAYS
+                ;
+    /* Credits to Fabrice Bellard's initial revision to demonstrate its
+       capability to compile and run itself, provided all numbers are
+       given as decimals. tcc -E -P10 will do. */
+    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
+        parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;
+
+#ifdef PP_BENCH
+    /* for PP benchmarks */
+    do next(); while (tok != TOK_EOF);
+    return 0;
+#endif
+
+    if (s1->dflag & 1) {
+        pp_debug_builtins(s1);
+        s1->dflag &= ~1;
+    }
+
+    token_seen = TOK_LINEFEED, spcs = 0;
+    pp_line(s1, file, 0);
     for (;;) {
+        iptr = s1->include_stack_ptr;
         next();
-        if (tok == TOK_EOF) {
+        if (tok == TOK_EOF)
             break;
-        } else if (file != file_ref) {
-            goto print_line;
+
+        level = s1->include_stack_ptr - iptr;
+        if (level) {
+            if (level > 0)
+                pp_line(s1, *iptr, 0);
+            pp_line(s1, file, level);
+        }
+        if (s1->dflag & 7) {
+            pp_debug_defines(s1);
+            if (s1->dflag & 4)
+                continue;
+        }
+
+        if (is_space(tok)) {
+            if (spcs < sizeof white - 1)
+                white[spcs++] = tok;
+            continue;
         } else if (tok == TOK_LINEFEED) {
-            if (!token_seen)
+            spcs = 0;
+            if (token_seen == TOK_LINEFEED)
                 continue;
-            ++line_ref;
-            token_seen = 0;
-        } else if (!token_seen) {
-            d = file->line_num - line_ref;
-            if (file != file_ref || d < 0 || d >= 8) {
-print_line:
-                iptr_new = s1->include_stack_ptr;
-                s = iptr_new > iptr ? " 1"
-                  : iptr_new < iptr ? " 2"
-                  : iptr_new > s1->include_stack ? " 3"
-                  : ""
-                  ;
-                iptr = iptr_new;
-                fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
-            } else {
-                while (d)
-                    fputs("\n", s1->ppfp), --d;
-            }
-            line_ref = (file_ref = file)->line_num;
-            token_seen = tok != TOK_LINEFEED;
-            if (!token_seen)
-                continue;
-        }
-        fputs(get_tok_str(tok, &tokc), s1->ppfp);
-    }
-    free_defines(define_start);
+            ++file->line_ref;
+        } else if (token_seen == TOK_LINEFEED) {
+            pp_line(s1, file, 0);
+        } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
+            white[spcs++] = ' ';
+        }
+
+        white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
+        fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
+        token_seen = pp_check_he0xE(tok, p);
+    }
     return 0;
 }
+
+/* ------------------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tccrun.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c	(revision 331)
@@ -24,22 +24,31 @@
 #ifdef TCC_IS_NATIVE
 
+#ifndef _WIN32
+# include <sys/mman.h>
+#endif
+
 #ifdef CONFIG_TCC_BACKTRACE
+# ifndef _WIN32
+#  include <signal.h>
+#  ifndef __OpenBSD__
+#   include <sys/ucontext.h>
+#  endif
+# else
+#  define ucontext_t CONTEXT
+# endif
 ST_DATA int rt_num_callers = 6;
 ST_DATA const char **rt_bound_error_msg;
 ST_DATA void *rt_prog_main;
-#endif
-
-#ifdef _WIN32
-#define ucontext_t CONTEXT
-#endif
-
-static void set_pages_executable(void *ptr, unsigned long length);
-static void set_exception_handler(void);
 static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
 static void rt_error(ucontext_t *uc, const char *fmt, ...);
-static int tcc_relocate_ex(TCCState *s1, void *ptr);
+static void set_exception_handler(void);
+#endif
+
+static void set_pages_executable(void *ptr, unsigned long length);
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
 
 #ifdef _WIN64
-static void win64_add_function_table(TCCState *s1);
+static void *win64_add_function_table(TCCState *s1);
+static void win64_del_function_table(void *);
 #endif
 
@@ -50,41 +59,56 @@
 LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
 {
-    int ret;
+    int size;
+    addr_t ptr_diff = 0;
 
     if (TCC_RELOCATE_AUTO != ptr)
-        return tcc_relocate_ex(s1, ptr);
-
-    ret = tcc_relocate_ex(s1, NULL);
-    if (ret < 0)
-        return ret;
+        return tcc_relocate_ex(s1, ptr, 0);
+
+    size = tcc_relocate_ex(s1, NULL, 0);
+    if (size < 0)
+        return -1;
 
 #ifdef HAVE_SELINUX
-    {   /* Use mmap instead of malloc for Selinux.  Ref:
-           http://www.gnu.org/s/libc/manual/html_node/File-Size.html */
-
-        char tmpfname[] = "/tmp/.tccrunXXXXXX";
-        int fd = mkstemp (tmpfname);
-
-        s1->mem_size = ret;
-        unlink (tmpfname);
-        ftruncate (fd, s1->mem_size);
-
-        s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE,
-            MAP_SHARED, fd, 0);
-        if (s1->write_mem == MAP_FAILED)
-            tcc_error("/tmp not writeable");
-
-        s1->runtime_mem = mmap (NULL, ret, PROT_READ|PROT_EXEC,
-            MAP_SHARED, fd, 0);
-        if (s1->runtime_mem == MAP_FAILED)
-            tcc_error("/tmp not executable");
-
-        ret = tcc_relocate_ex(s1, s1->write_mem);
-    }
-#else
-    s1->runtime_mem = tcc_malloc(ret);
-    ret = tcc_relocate_ex(s1, s1->runtime_mem);
-#endif
-    return ret;
+{
+    /* Using mmap instead of malloc */
+    void *prx;
+    char tmpfname[] = "/tmp/.tccrunXXXXXX";
+    int fd = mkstemp(tmpfname);
+    unlink(tmpfname);
+    ftruncate(fd, size);
+
+    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+    if (ptr == MAP_FAILED || prx == MAP_FAILED)
+	tcc_error("tccrun: could not map memory");
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
+    ptr_diff = (char*)prx - (char*)ptr;
+}
+#else
+    ptr = tcc_malloc(size);
+#endif
+    tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
+    return 0;
+}
+
+ST_FUNC void tcc_run_free(TCCState *s1)
+{
+    int i;
+
+    for (i = 0; i < s1->nb_runtime_mem; ++i) {
+#ifdef HAVE_SELINUX
+        unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
+        munmap(s1->runtime_mem[i++], size);
+        munmap(s1->runtime_mem[i], size);
+#else
+#ifdef _WIN64
+        win64_del_function_table(*(void**)s1->runtime_mem[i]);
+#endif
+        tcc_free(s1->runtime_mem[i]);
+#endif
+    }
+    tcc_free(s1->runtime_mem);
 }
 
@@ -93,10 +117,11 @@
 {
     int (*prog_main)(int, char **);
-    int ret;
-
+
+    s1->runtime_main = "main";
+    if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
+        return 0;
     if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
         return -1;
-
-    prog_main = tcc_get_symbol_err(s1, "main");
+    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
 
 #ifdef CONFIG_TCC_BACKTRACE
@@ -107,8 +132,14 @@
 #endif
 
+    errno = 0; /* clean errno value */
+
 #ifdef CONFIG_TCC_BCHECK
     if (s1->do_bounds_check) {
         void (*bound_init)(void);
         void (*bound_exit)(void);
+        void (*bound_new_region)(void *p, addr_t size);
+        int  (*bound_delete_region)(void *p);
+        int i, ret;
+
         /* set error function */
         rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
@@ -116,21 +147,39 @@
         bound_init = tcc_get_symbol_err(s1, "__bound_init");
         bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
+        bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
+        bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");
+
         bound_init();
+        /* mark argv area as valid */
+        bound_new_region(argv, argc*sizeof(argv[0]));
+        for (i=0; i<argc; ++i)
+            bound_new_region(argv[i], strlen(argv[i]) + 1);
+
         ret = (*prog_main)(argc, argv);
+
+        /* unmark argv area */
+        for (i=0; i<argc; ++i)
+            bound_delete_region(argv[i]);
+        bound_delete_region(argv);
         bound_exit();
-    } else
-#endif
-        ret = (*prog_main)(argc, argv);
-    return ret;
-}
+        return ret;
+    }
+#endif
+    return (*prog_main)(argc, argv);
+}
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ #define RUN_SECTION_ALIGNMENT 63
+#else
+ #define RUN_SECTION_ALIGNMENT 15
+#endif
 
 /* relocate code. Return -1 on error, required size if ptr is NULL,
    otherwise copy code into buffer passed by the caller */
-static int tcc_relocate_ex(TCCState *s1, void *ptr)
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
 {
     Section *s;
-    unsigned long offset, length;
+    unsigned offset, length, fill, i, k;
     addr_t mem;
-    int i;
 
     if (NULL == ptr) {
@@ -140,6 +189,5 @@
 #else
         tcc_add_runtime(s1);
-        relocate_common_syms();
-        tcc_add_linker_symbols(s1);
+	resolve_common_syms(s1);
         build_got_entries(s1);
 #endif
@@ -149,4 +197,58 @@
 
     offset = 0, mem = (addr_t)ptr;
+    fill = -mem & RUN_SECTION_ALIGNMENT;
+#ifdef _WIN64
+    offset += sizeof (void*);
+#endif
+    for (k = 0; k < 2; ++k) {
+        for(i = 1; i < s1->nb_sections; i++) {
+            s = s1->sections[i];
+            if (0 == (s->sh_flags & SHF_ALLOC))
+                continue;
+            if (k != !(s->sh_flags & SHF_EXECINSTR))
+                continue;
+            offset += fill;
+            if (!mem)
+                s->sh_addr = 0;
+            else if (s->sh_flags & SHF_EXECINSTR)
+                s->sh_addr = mem + offset + ptr_diff;
+            else
+                s->sh_addr = mem + offset;
+#if 0
+            if (mem)
+                printf("%-16s +%02lx %p %04x\n",
+                    s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
+#endif
+            offset += s->data_offset;
+            fill = -(mem + offset) & 15;
+        }
+#if RUN_SECTION_ALIGNMENT > 15
+        /* To avoid that x86 processors would reload cached instructions each time
+           when data is written in the near, we need to make sure that code and data
+           do not share the same 64 byte unit */
+        fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
+#endif
+    }
+
+    /* relocate symbols */
+    relocate_syms(s1, s1->symtab, 1);
+    if (s1->nb_errors)
+        return -1;
+
+    if (0 == mem)
+        return offset + RUN_SECTION_ALIGNMENT;
+
+#ifdef TCC_TARGET_PE
+    s1->pe_imagebase = mem;
+#endif
+
+    /* relocate each section */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->reloc)
+            relocate_section(s1, s);
+    }
+    relocate_plt(s1);
+
     for(i = 1; i < s1->nb_sections; i++) {
         s = s1->sections[i];
@@ -154,39 +256,7 @@
             continue;
         length = s->data_offset;
-        s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0;
-        offset = (offset + length + 15) & ~15;
-    }
-    offset += 16;
-
-    /* relocate symbols */
-    relocate_syms(s1, 1);
-    if (s1->nb_errors)
-        return -1;
-
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-    s1->runtime_plt_and_got_offset = 0;
-    s1->runtime_plt_and_got = (char *)(mem + offset);
-    /* double the size of the buffer for got and plt entries
-       XXX: calculate exact size for them? */
-    offset *= 2;
-#endif
-
-    if (0 == mem)
-        return offset;
-
-    /* relocate each section */
-    for(i = 1; i < s1->nb_sections; i++) {
-        s = s1->sections[i];
-        if (s->reloc)
-            relocate_section(s1, s);
-    }
-
-    for(i = 1; i < s1->nb_sections; i++) {
-        s = s1->sections[i];
-        if (0 == (s->sh_flags & SHF_ALLOC))
-            continue;
-        length = s->data_offset;
-        // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
         ptr = (void*)s->sh_addr;
+        if (s->sh_flags & SHF_EXECINSTR)
+            ptr = (char*)ptr - ptr_diff;
         if (NULL == s->data || s->sh_type == SHT_NOBITS)
             memset(ptr, 0, length);
@@ -195,15 +265,11 @@
         /* mark executable sections as executable in memory */
         if (s->sh_flags & SHF_EXECINSTR)
-            set_pages_executable(ptr, length);
-    }
-
-#ifdef TCC_HAS_RUNTIME_PLTGOT
-    set_pages_executable(s1->runtime_plt_and_got,
-                         s1->runtime_plt_and_got_offset);
-#endif
+            set_pages_executable((char*)ptr + ptr_diff, length);
+    }
 
 #ifdef _WIN64
-    win64_add_function_table(s1);
-#endif
+    *(void**)mem = win64_add_function_table(s1);
+#endif
+
     return 0;
 }
@@ -218,14 +284,45 @@
     VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
 #else
-#ifndef PAGESIZE
-# define PAGESIZE 4096
-#endif
+    void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
     addr_t start, end;
+#  ifndef PAGESIZE
+#   define PAGESIZE 4096
+#  endif
     start = (addr_t)ptr & ~(PAGESIZE - 1);
     end = (addr_t)ptr + length;
     end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
-    mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
-#endif
-}
+    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
+        tcc_error("mprotect failed: did you mean to configure --with-selinux?");
+# endif
+# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
+    __clear_cache(ptr, (char *)ptr + length);
+# endif
+#endif
+}
+
+#ifdef _WIN64
+static void *win64_add_function_table(TCCState *s1)
+{
+    void *p = NULL;
+    if (s1->uw_pdata) {
+        p = (void*)s1->uw_pdata->sh_addr;
+        RtlAddFunctionTable(
+            (RUNTIME_FUNCTION*)p,
+            s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
+            s1->pe_imagebase
+            );
+        s1->uw_pdata = NULL;
+    }
+    return p;
+}
+
+static void win64_del_function_table(void *p)
+{
+    if (p) {
+        RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
+    }
+}
+#endif
 
 /* ------------------------------------------------------------- */
@@ -254,5 +351,5 @@
         stab_len = stab_section->data_offset;
         stab_sym = (Stab_Sym *)stab_section->data;
-        stab_str = stabstr_section->data;
+        stab_str = (char *) stabstr_section->data;
     }
 
@@ -347,5 +444,5 @@
                     wanted_pc < sym->st_value + sym->st_size) {
                     pstrcpy(last_func_name, sizeof(last_func_name),
-                            strtab_section->data + sym->st_name);
+                            (char *) symtab_section->link->data + sym->st_name);
                     func_addr = sym->st_value;
                     goto found;
@@ -453,6 +550,5 @@
        runtime errors */
     sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
-    /*sigact.sa_sigaction = sig_error;*/
-	sigact.sa_handler = sig_error;
+    sigact.sa_sigaction = sig_error;
     sigemptyset(&sigact.sa_mask);
     sigaction(SIGFPE, &sigact, NULL);
@@ -481,8 +577,12 @@
 #if defined(__APPLE__)
         *paddr = uc->uc_mcontext->__ss.__eip;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
         *paddr = uc->uc_mcontext.mc_eip;
 #elif defined(__dietlibc__)
         *paddr = uc->uc_mcontext.eip;
+#elif defined(__NetBSD__)
+        *paddr = uc->uc_mcontext.__gregs[_REG_EIP];
+#elif defined(__OpenBSD__)
+        *paddr = uc->sc_eip;
 #else
         *paddr = uc->uc_mcontext.gregs[REG_EIP];
@@ -492,8 +592,12 @@
 #if defined(__APPLE__)
         fp = uc->uc_mcontext->__ss.__ebp;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
         fp = uc->uc_mcontext.mc_ebp;
 #elif defined(__dietlibc__)
         fp = uc->uc_mcontext.ebp;
+#elif defined(__NetBSD__)
+        fp = uc->uc_mcontext.__gregs[_REG_EBP];
+#elif defined(__OpenBSD__)
+        *paddr = uc->sc_ebp;
 #else
         fp = uc->uc_mcontext.gregs[REG_EBP];
@@ -523,6 +627,8 @@
 #if defined(__APPLE__)
         *paddr = uc->uc_mcontext->__ss.__rip;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
         *paddr = uc->uc_mcontext.mc_rip;
+#elif defined(__NetBSD__)
+        *paddr = uc->uc_mcontext.__gregs[_REG_RIP];
 #else
         *paddr = uc->uc_mcontext.gregs[REG_RIP];
@@ -532,6 +638,8 @@
 #if defined(__APPLE__)
         fp = uc->uc_mcontext->__ss.__rbp;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
         fp = uc->uc_mcontext.mc_rbp;
+#elif defined(__NetBSD__)
+        fp = uc->uc_mcontext.__gregs[_REG_RBP];
 #else
         fp = uc->uc_mcontext.gregs[REG_RBP];
@@ -587,4 +695,25 @@
         /* XXX: check address validity with program info */
         *paddr = ((addr_t *)fp)[-1];
+        return 0;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__aarch64__)
+
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    if (level < 0)
+        return -1;
+    else if (level == 0) {
+        *paddr = uc->uc_mcontext.pc;
+        return 0;
+    }
+    else {
+        addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29];
+        int i;
+        for (i = 1; i < level; i++)
+            fp = (addr_t *)fp[0];
+        *paddr = fp[1];
         return 0;
     }
@@ -635,15 +764,4 @@
 }
 
-#ifdef _WIN64
-static void win64_add_function_table(TCCState *s1)
-{
-    RtlAddFunctionTable(
-        (RUNTIME_FUNCTION*)s1->uw_pdata->sh_addr,
-        s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
-        text_section->sh_addr
-        );
-}
-#endif
-
 /* return the PC at frame level 'level'. Return non zero if not found */
 static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
@@ -696,4 +814,50 @@
 } TCCSyms;
 
+#if !defined(CONFIG_TCCBOOT)
+extern int __environ;
+extern int __expand_heap;
+extern int __get_handler_set;
+extern int __get_locale;
+extern int __gmt;
+extern int __h_errno_location;
+extern int __hwcap;
+extern int __init_tls;
+extern int __libc;
+extern int __libc_sigaction;
+extern int __libc_start_main;
+extern int __malloc0;
+extern int __ofl_lock;
+extern int __ofl_unlock;
+extern int __progname;
+extern int __progname_full;
+extern int __secs_to_zone;
+extern int __sigaction;
+extern int __sysinfo;
+extern int __tm_to_tzname;
+//extern int atexit;
+//extern int environ;
+//extern int free;
+extern int gethostbyname2;
+//extern int getopt;
+extern int getpwnam;
+//extern int gmtime;
+//extern int localtime;
+//extern int malloc;
+extern int mbrtowc;
+//extern int optarg;
+extern int optind;
+//extern int rand;
+//extern int realloc;
+//extern int setenv;
+extern int setlocale;
+//extern int sigaction;
+//extern int srand;
+//extern int stderr;
+//extern int stdin;
+//extern int stdout;
+//extern int strtok;
+extern int syslog;
+extern int vsyslog;
+#endif
 
 /* add the symbol you want here if no dynamic linking is done */
@@ -701,8 +865,48 @@
 #if !defined(CONFIG_TCCBOOT)
 #define TCCSYM(a) { #a, &a, },
-    TCCSYM(printf)
-    TCCSYM(fprintf)
-    TCCSYM(fopen)
-    TCCSYM(fclose)
+    TCCSYM(__environ)
+    TCCSYM(__expand_heap)
+    TCCSYM(__get_handler_set)
+    TCCSYM(__get_locale)
+    TCCSYM(__gmt)
+    TCCSYM(__h_errno_location)
+    TCCSYM(__hwcap)
+    TCCSYM(__init_tls)
+    TCCSYM(__libc)
+    TCCSYM(__libc_sigaction)
+    TCCSYM(__libc_start_main)
+    TCCSYM(__malloc0)
+    TCCSYM(__ofl_lock)
+    TCCSYM(__ofl_unlock)
+    TCCSYM(__progname)
+    TCCSYM(__progname_full)
+    TCCSYM(__secs_to_zone)
+    TCCSYM(__sigaction)
+    TCCSYM(__sysinfo)
+    TCCSYM(__tm_to_tzname)
+    TCCSYM(atexit)
+    TCCSYM(environ)
+    TCCSYM(free)
+    TCCSYM(gethostbyname2)
+    TCCSYM(getopt)
+    TCCSYM(getpwnam)
+    TCCSYM(gmtime)
+    TCCSYM(localtime)
+    TCCSYM(malloc)
+    TCCSYM(mbrtowc)
+    TCCSYM(optarg)
+    TCCSYM(optind)
+    TCCSYM(rand)
+    TCCSYM(realloc)
+    TCCSYM(setenv)
+    TCCSYM(setlocale)
+    TCCSYM(sigaction)
+    TCCSYM(srand)
+    TCCSYM(stderr)
+    TCCSYM(stdin)
+    TCCSYM(stdout)
+    TCCSYM(strtok)
+    TCCSYM(syslog)
+    TCCSYM(vsyslog)
 #undef TCCSYM
 #endif
@@ -710,5 +914,5 @@
 };
 
-ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol)
+ST_FUNC void *dlsym(void *handle, const char *symbol)
 {
     TCCSyms *p;
@@ -722,11 +926,4 @@
 }
 
-#elif !defined(_WIN32)
-
-ST_FUNC void *resolve_sym(TCCState *s1, const char *sym)
-{
-    return dlsym(RTLD_DEFAULT, sym);
-}
-
 #endif /* CONFIG_TCC_STATIC */
 #endif /* TCC_IS_NATIVE */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tcctok.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h	(revision 331)
@@ -37,5 +37,7 @@
      DEF(TOK_RESTRICT3, "__restrict__")
      DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
-     
+
+     DEF(TOK_GENERIC, "_Generic")
+
      DEF(TOK_FLOAT, "float")
      DEF(TOK_DOUBLE, "double")
@@ -59,4 +61,8 @@
      DEF(TOK_ASM2, "__asm")
      DEF(TOK_ASM3, "__asm__")
+
+#ifdef TCC_TARGET_ARM64
+     DEF(TOK_UINT128, "__uint128_t")
+#endif
 
 /*********************************************************************/
@@ -82,4 +88,5 @@
      DEF(TOK___FUNCTION__, "__FUNCTION__")
      DEF(TOK___VA_ARGS__, "__VA_ARGS__")
+     DEF(TOK___COUNTER__, "__COUNTER__")
 
 /* special identifiers */
@@ -114,20 +121,36 @@
      DEF(TOK_FASTCALL2, "__fastcall")
      DEF(TOK_FASTCALL3, "__fastcall__")
+     DEF(TOK_REGPARM1, "regparm")
+     DEF(TOK_REGPARM2, "__regparm__")
+
      DEF(TOK_MODE, "__mode__")
+     DEF(TOK_MODE_QI, "__QI__")
      DEF(TOK_MODE_DI, "__DI__")
      DEF(TOK_MODE_HI, "__HI__")
      DEF(TOK_MODE_SI, "__SI__")
+     DEF(TOK_MODE_word, "__word__")
+
      DEF(TOK_DLLEXPORT, "dllexport")
      DEF(TOK_DLLIMPORT, "dllimport")
      DEF(TOK_NORETURN1, "noreturn")
      DEF(TOK_NORETURN2, "__noreturn__")
+     DEF(TOK_VISIBILITY1, "visibility")
+     DEF(TOK_VISIBILITY2, "__visibility__")
+
      DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
+     DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
      DEF(TOK_builtin_constant_p, "__builtin_constant_p")
      DEF(TOK_builtin_frame_address, "__builtin_frame_address")
-#ifdef TCC_TARGET_X86_64
+     DEF(TOK_builtin_return_address, "__builtin_return_address")
+     DEF(TOK_builtin_expect, "__builtin_expect")
+     /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+     DEF(TOK_builtin_va_start, "__builtin_va_start")
+#elif defined TCC_TARGET_X86_64
      DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
-#endif
-     DEF(TOK_REGPARM1, "regparm")
-     DEF(TOK_REGPARM2, "__regparm__")
+#elif defined TCC_TARGET_ARM64
+     DEF(TOK___va_start, "__va_start")
+     DEF(TOK___va_arg, "__va_arg")
+#endif
 
 /* pragma */
@@ -138,15 +161,15 @@
      DEF(TOK_ASM_pop, "pop")
 #endif
+     DEF(TOK_comment, "comment")
+     DEF(TOK_lib, "lib")
+     DEF(TOK_push_macro, "push_macro")
+     DEF(TOK_pop_macro, "pop_macro")
+     DEF(TOK_once, "once")
+     DEF(TOK_option, "option")
 
 /* builtin functions or variables */
-#ifdef TCC_ARM_EABI
-     DEF(TOK_memcpy, "__aeabi_memcpy")
-     DEF(TOK_memcpy4, "__aeabi_memcpy4")
-     DEF(TOK_memcpy8, "__aeabi_memcpy8")
-     DEF(TOK_memset, "__aeabi_memset")
-     DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
-     DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
-#else
+#ifndef TCC_ARM_EABI
      DEF(TOK_memcpy, "memcpy")
+     DEF(TOK_memmove, "memmove")
      DEF(TOK_memset, "memset")
      DEF(TOK___divdi3, "__divdi3")
@@ -154,7 +177,26 @@
      DEF(TOK___udivdi3, "__udivdi3")
      DEF(TOK___umoddi3, "__umoddi3")
-#endif
-#if defined(TCC_TARGET_ARM)
-#ifdef TCC_ARM_EABI
+     DEF(TOK___ashrdi3, "__ashrdi3")
+     DEF(TOK___lshrdi3, "__lshrdi3")
+     DEF(TOK___ashldi3, "__ashldi3")
+     DEF(TOK___floatundisf, "__floatundisf")
+     DEF(TOK___floatundidf, "__floatundidf")
+# ifndef TCC_ARM_VFP
+     DEF(TOK___floatundixf, "__floatundixf")
+     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
+# endif
+     DEF(TOK___fixunssfdi, "__fixunssfdi")
+     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
+#endif
+
+#if defined TCC_TARGET_ARM
+# ifdef TCC_ARM_EABI
+     DEF(TOK_memcpy, "__aeabi_memcpy")
+     DEF(TOK_memcpy4, "__aeabi_memcpy4")
+     DEF(TOK_memcpy8, "__aeabi_memcpy8")
+     DEF(TOK_memmove, "__aeabi_memmove")
+     DEF(TOK_memset, "__aeabi_memset")
+     DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
+     DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
      DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
      DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
@@ -165,34 +207,4 @@
      DEF(TOK___fixsfdi, "__aeabi_f2lz")
      DEF(TOK___fixdfdi, "__aeabi_d2lz")
-#else
-     DEF(TOK___modsi3, "__modsi3")
-     DEF(TOK___umodsi3, "__umodsi3")
-     DEF(TOK___divsi3, "__divsi3")
-     DEF(TOK___udivsi3, "__udivsi3")
-     DEF(TOK___floatdisf, "__floatdisf")
-     DEF(TOK___floatdidf, "__floatdidf")
-#ifndef TCC_ARM_VFP
-     DEF(TOK___floatdixf, "__floatdixf")
-     DEF(TOK___fixunssfsi, "__fixunssfsi")
-     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
-     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
-     DEF(TOK___fixxfdi, "__fixxfdi")
-#endif
-     DEF(TOK___fixsfdi, "__fixsfdi")
-     DEF(TOK___fixdfdi, "__fixdfdi")
-#endif
-#elif defined(TCC_TARGET_C67)
-     DEF(TOK__divi, "_divi")
-     DEF(TOK__divu, "_divu")
-     DEF(TOK__divf, "_divf")
-     DEF(TOK__divd, "_divd")
-     DEF(TOK__remi, "_remi")
-     DEF(TOK__remu, "_remu")
-#endif
-#ifdef TCC_TARGET_I386
-     DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
-     DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
-#endif
-#ifdef TCC_ARM_EABI
      DEF(TOK___ashrdi3, "__aeabi_lasr")
      DEF(TOK___lshrdi3, "__aeabi_llsr")
@@ -202,19 +214,69 @@
      DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
      DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
-#else
-     DEF(TOK___ashrdi3, "__ashrdi3")
-     DEF(TOK___lshrdi3, "__lshrdi3")
-     DEF(TOK___ashldi3, "__ashldi3")
-     DEF(TOK___floatundisf, "__floatundisf")
-     DEF(TOK___floatundidf, "__floatundidf")
-#ifndef TCC_ARM_VFP
-     DEF(TOK___floatundixf, "__floatundixf")
-     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
-#endif
-     DEF(TOK___fixunssfdi, "__fixunssfdi")
-     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
-#endif
-#ifdef TCC_TARGET_PE
+# else
+     DEF(TOK___modsi3, "__modsi3")
+     DEF(TOK___umodsi3, "__umodsi3")
+     DEF(TOK___divsi3, "__divsi3")
+     DEF(TOK___udivsi3, "__udivsi3")
+     DEF(TOK___floatdisf, "__floatdisf")
+     DEF(TOK___floatdidf, "__floatdidf")
+#  ifndef TCC_ARM_VFP
+     DEF(TOK___floatdixf, "__floatdixf")
+     DEF(TOK___fixunssfsi, "__fixunssfsi")
+     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
+     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
+     DEF(TOK___fixxfdi, "__fixxfdi")
+#  endif
+     DEF(TOK___fixsfdi, "__fixsfdi")
+     DEF(TOK___fixdfdi, "__fixdfdi")
+# endif
+#endif
+
+#if defined TCC_TARGET_C67
+     DEF(TOK__divi, "_divi")
+     DEF(TOK__divu, "_divu")
+     DEF(TOK__divf, "_divf")
+     DEF(TOK__divd, "_divd")
+     DEF(TOK__remi, "_remi")
+     DEF(TOK__remu, "_remu")
+#endif
+
+#if defined TCC_TARGET_I386
+     DEF(TOK___fixsfdi, "__fixsfdi")
+     DEF(TOK___fixdfdi, "__fixdfdi")
+     DEF(TOK___fixxfdi, "__fixxfdi")
+#endif
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+     DEF(TOK_alloca, "alloca")
+#endif
+
+#if defined TCC_TARGET_PE
      DEF(TOK___chkstk, "__chkstk")
+#endif
+#ifdef TCC_TARGET_ARM64
+     DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
+     DEF(TOK___addtf3, "__addtf3")
+     DEF(TOK___subtf3, "__subtf3")
+     DEF(TOK___multf3, "__multf3")
+     DEF(TOK___divtf3, "__divtf3")
+     DEF(TOK___extendsftf2, "__extendsftf2")
+     DEF(TOK___extenddftf2, "__extenddftf2")
+     DEF(TOK___trunctfsf2, "__trunctfsf2")
+     DEF(TOK___trunctfdf2, "__trunctfdf2")
+     DEF(TOK___fixtfsi, "__fixtfsi")
+     DEF(TOK___fixtfdi, "__fixtfdi")
+     DEF(TOK___fixunstfsi, "__fixunstfsi")
+     DEF(TOK___fixunstfdi, "__fixunstfdi")
+     DEF(TOK___floatsitf, "__floatsitf")
+     DEF(TOK___floatditf, "__floatditf")
+     DEF(TOK___floatunsitf, "__floatunsitf")
+     DEF(TOK___floatunditf, "__floatunditf")
+     DEF(TOK___eqtf2, "__eqtf2")
+     DEF(TOK___netf2, "__netf2")
+     DEF(TOK___lttf2, "__lttf2")
+     DEF(TOK___letf2, "__letf2")
+     DEF(TOK___gttf2, "__gttf2")
+     DEF(TOK___getf2, "__getf2")
 #endif
 
@@ -228,7 +290,8 @@
      DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
      DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
+     DEF(TOK___bound_main_arg, "__bound_main_arg")
      DEF(TOK___bound_local_new, "__bound_local_new")
      DEF(TOK___bound_local_delete, "__bound_local_delete")
-#ifdef TCC_TARGET_PE
+# ifdef TCC_TARGET_PE
      DEF(TOK_malloc, "malloc")
      DEF(TOK_free, "free")
@@ -236,41 +299,50 @@
      DEF(TOK_memalign, "memalign")
      DEF(TOK_calloc, "calloc")
-#endif
-     DEF(TOK_memmove, "memmove")
+# endif
      DEF(TOK_strlen, "strlen")
      DEF(TOK_strcpy, "strcpy")
 #endif
-#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
-     DEF(TOK_alloca, "alloca")
-#endif
 
 /* Tiny Assembler */
- DEF_ASM(byte)
- DEF_ASM(word)
- DEF_ASM(align)
- DEF_ASM(skip)
- DEF_ASM(space)
- DEF_ASM(string)
- DEF_ASM(asciz)
- DEF_ASM(ascii)
- DEF_ASM(file)
- DEF_ASM(globl)
- DEF_ASM(global)
- DEF_ASM(ident)
- DEF_ASM(size)
- DEF_ASM(type)
- DEF_ASM(text)
- DEF_ASM(data)
- DEF_ASM(bss)
- DEF_ASM(previous)
- DEF_ASM(fill)
- DEF_ASM(org)
- DEF_ASM(quad)
+ DEF_ASMDIR(byte)              /* must be first directive */
+ DEF_ASMDIR(word)
+ DEF_ASMDIR(align)
+ DEF_ASMDIR(balign)
+ DEF_ASMDIR(p2align)
+ DEF_ASMDIR(set)
+ DEF_ASMDIR(skip)
+ DEF_ASMDIR(space)
+ DEF_ASMDIR(string)
+ DEF_ASMDIR(asciz)
+ DEF_ASMDIR(ascii)
+ DEF_ASMDIR(file)
+ DEF_ASMDIR(globl)
+ DEF_ASMDIR(global)
+ DEF_ASMDIR(weak)
+ DEF_ASMDIR(hidden)
+ DEF_ASMDIR(ident)
+ DEF_ASMDIR(size)
+ DEF_ASMDIR(type)
+ DEF_ASMDIR(text)
+ DEF_ASMDIR(data)
+ DEF_ASMDIR(bss)
+ DEF_ASMDIR(previous)
+ DEF_ASMDIR(pushsection)
+ DEF_ASMDIR(popsection)
+ DEF_ASMDIR(fill)
+ DEF_ASMDIR(rept)
+ DEF_ASMDIR(endr)
+ DEF_ASMDIR(org)
+ DEF_ASMDIR(quad)
 #if defined(TCC_TARGET_I386)
- DEF_ASM(code16)
- DEF_ASM(code32)
+ DEF_ASMDIR(code16)
+ DEF_ASMDIR(code32)
 #elif defined(TCC_TARGET_X86_64)
- DEF_ASM(code64)
-#endif
+ DEF_ASMDIR(code64)
+#endif
+ DEF_ASMDIR(short)
+ DEF_ASMDIR(long)
+ DEF_ASMDIR(int)
+ DEF_ASMDIR(section)            /* must be last directive */
 
 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c	(revision 331)
@@ -0,0 +1,546 @@
+/* -------------------------------------------------------------- */
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  tcctools.c - extra tools and and -m32/64 support
+ *
+ */
+
+/* -------------------------------------------------------------- */
+/*
+ * This program is for making libtcc1.a without ar
+ * tiny_libmaker - tiny elf lib maker
+ * usage: tiny_libmaker [lib] files...
+ * Copyright (c) 2007 Timppa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "tcc.h"
+
+//#define ARMAG  "!<arch>\n"
+#define ARFMAG "`\n"
+
+typedef struct {
+    char ar_name[16];
+    char ar_date[12];
+    char ar_uid[6];
+    char ar_gid[6];
+    char ar_mode[8];
+    char ar_size[10];
+    char ar_fmag[2];
+} ArHdr;
+
+static unsigned long le2belong(unsigned long ul) {
+    return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
+        ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
+}
+
+/* Returns 1 if s contains any of the chars of list, else 0 */
+static int contains_any(const char *s, const char *list) {
+  const char *l;
+  for (; *s; s++) {
+      for (l = list; *l; l++) {
+          if (*s == *l)
+              return 1;
+      }
+  }
+  return 0;
+}
+
+static int ar_usage(int ret) {
+    fprintf(stderr, "usage: tcc -ar [rcsv] lib file...\n");
+    fprintf(stderr, "create library ([abdioptxN] not supported).\n");
+    return ret;
+}
+
+ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
+{
+    static ArHdr arhdr = {
+        "/               ",
+        "            ",
+        "0     ",
+        "0     ",
+        "0       ",
+        "          ",
+        ARFMAG
+        };
+
+    static ArHdr arhdro = {
+        "                ",
+        "            ",
+        "0     ",
+        "0     ",
+        "0       ",
+        "          ",
+        ARFMAG
+        };
+
+    FILE *fi, *fh = NULL, *fo = NULL;
+    ElfW(Ehdr) *ehdr;
+    ElfW(Shdr) *shdr;
+    ElfW(Sym) *sym;
+    int i, fsize, i_lib, i_obj;
+    char *buf, *shstr, *symtab = NULL, *strtab = NULL;
+    int symtabsize = 0;//, strtabsize = 0;
+    char *anames = NULL;
+    int *afpos = NULL;
+    int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
+    char tfile[260], stmp[20];
+    char *file, *name;
+    int ret = 2;
+    const char *ops_conflict = "habdioptxN";  // unsupported but destructive if ignored.
+    int verbose = 0;
+
+    i_lib = 0; i_obj = 0;  // will hold the index of the lib and first obj
+    for (i = 1; i < argc; i++) {
+        const char *a = argv[i];
+        if (*a == '-' && strstr(a, "."))
+            ret = 1; // -x.y is always invalid (same as gnu ar)
+        if ((*a == '-') || (i == 1 && !strstr(a, "."))) {  // options argument
+            if (contains_any(a, ops_conflict))
+                ret = 1;
+            if (strstr(a, "v"))
+                verbose = 1;
+        } else {  // lib or obj files: don't abort - keep validating all args.
+            if (!i_lib)  // first file is the lib
+                i_lib = i;
+            else if (!i_obj)  // second file is the first obj
+                i_obj = i;
+        }
+    }
+
+    if (!i_obj)  // i_obj implies also i_lib. we require both.
+        ret = 1;
+
+    if (ret == 1)
+        return ar_usage(ret);
+
+    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
+    {
+        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
+        goto the_end;
+    }
+
+    sprintf(tfile, "%s.tmp", argv[i_lib]);
+    if ((fo = fopen(tfile, "wb+")) == NULL)
+    {
+        fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile);
+        goto the_end;
+    }
+
+    funcmax = 250;
+    afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
+    memcpy(&arhdro.ar_mode, "100666", 6);
+
+    // i_obj = first input object file
+    while (i_obj < argc)
+    {
+        if (*argv[i_obj] == '-') {  // by now, all options start with '-'
+            i_obj++;
+            continue;
+        }
+        if ((fi = fopen(argv[i_obj], "rb")) == NULL) {
+            fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]);
+            goto the_end;
+        }
+        if (verbose)
+            printf("a - %s\n", argv[i_obj]);
+
+        fseek(fi, 0, SEEK_END);
+        fsize = ftell(fi);
+        fseek(fi, 0, SEEK_SET);
+        buf = tcc_malloc(fsize + 1);
+        fread(buf, fsize, 1, fi);
+        fclose(fi);
+
+        // elf header
+        ehdr = (ElfW(Ehdr) *)buf;
+        if (ehdr->e_ident[4] != ELFCLASSW)
+        {
+            fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]);
+            goto the_end;
+        }
+
+        shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
+        shstr = (char *)(buf + shdr->sh_offset);
+        for (i = 0; i < ehdr->e_shnum; i++)
+        {
+            shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
+            if (!shdr->sh_offset)
+                continue;
+            if (shdr->sh_type == SHT_SYMTAB)
+            {
+                symtab = (char *)(buf + shdr->sh_offset);
+                symtabsize = shdr->sh_size;
+            }
+            if (shdr->sh_type == SHT_STRTAB)
+            {
+                if (!strcmp(shstr + shdr->sh_name, ".strtab"))
+                {
+                    strtab = (char *)(buf + shdr->sh_offset);
+                    //strtabsize = shdr->sh_size;
+                }
+            }
+        }
+
+        if (symtab && symtabsize)
+        {
+            int nsym = symtabsize / sizeof(ElfW(Sym));
+            //printf("symtab: info size shndx name\n");
+            for (i = 1; i < nsym; i++)
+            {
+                sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym)));
+                if (sym->st_shndx &&
+                    (sym->st_info == 0x10
+                    || sym->st_info == 0x11
+                    || sym->st_info == 0x12
+                    )) {
+                    //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
+                    istrlen = strlen(strtab + sym->st_name)+1;
+                    anames = tcc_realloc(anames, strpos+istrlen);
+                    strcpy(anames + strpos, strtab + sym->st_name);
+                    strpos += istrlen;
+                    if (++funccnt >= funcmax) {
+                        funcmax += 250;
+                        afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
+                    }
+                    afpos[funccnt] = fpos;
+                }
+            }
+        }
+
+        file = argv[i_obj];
+        for (name = strchr(file, 0);
+             name > file && name[-1] != '/' && name[-1] != '\\';
+             --name);
+        istrlen = strlen(name);
+        if (istrlen >= sizeof(arhdro.ar_name))
+            istrlen = sizeof(arhdro.ar_name) - 1;
+        memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name));
+        memcpy(arhdro.ar_name, name, istrlen);
+        arhdro.ar_name[istrlen] = '/';
+        sprintf(stmp, "%-10d", fsize);
+        memcpy(&arhdro.ar_size, stmp, 10);
+        fwrite(&arhdro, sizeof(arhdro), 1, fo);
+        fwrite(buf, fsize, 1, fo);
+        tcc_free(buf);
+        i_obj++;
+        fpos += (fsize + sizeof(arhdro));
+    }
+    hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
+    fpos = 0;
+    if ((hofs & 1)) // align
+        hofs++, fpos = 1;
+    // write header
+    fwrite("!<arch>\n", 8, 1, fh);
+    sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int)));
+    memcpy(&arhdr.ar_size, stmp, 10);
+    fwrite(&arhdr, sizeof(arhdr), 1, fh);
+    afpos[0] = le2belong(funccnt);
+    for (i=1; i<=funccnt; i++)
+        afpos[i] = le2belong(afpos[i] + hofs);
+    fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
+    fwrite(anames, strpos, 1, fh);
+    if (fpos)
+        fwrite("", 1, 1, fh);
+    // write objects
+    fseek(fo, 0, SEEK_END);
+    fsize = ftell(fo);
+    fseek(fo, 0, SEEK_SET);
+    buf = tcc_malloc(fsize + 1);
+    fread(buf, fsize, 1, fo);
+    fwrite(buf, fsize, 1, fh);
+    tcc_free(buf);
+    ret = 0;
+the_end:
+    if (anames)
+        tcc_free(anames);
+    if (afpos)
+        tcc_free(afpos);
+    if (fh)
+        fclose(fh);
+    if (fo)
+        fclose(fo), remove(tfile);
+    return ret;
+}
+
+/* -------------------------------------------------------------- */
+/*
+ * tiny_impdef creates an export definition file (.def) from a dll
+ * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
+ *
+ *  Copyright (c) 2005,2007 grischka
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef TCC_TARGET_PE
+
+ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv)
+{
+    int ret, v, i;
+    char infile[260];
+    char outfile[260];
+
+    const char *file;
+    char *p, *q;
+    FILE *fp, *op;
+
+#ifdef _WIN32
+    char path[260];
+#endif
+
+    infile[0] = outfile[0] = 0;
+    fp = op = NULL;
+    ret = 1;
+    p = NULL;
+    v = 0;
+
+    for (i = 1; i < argc; ++i) {
+        const char *a = argv[i];
+        if ('-' == a[0]) {
+            if (0 == strcmp(a, "-v")) {
+                v = 1;
+            } else if (0 == strcmp(a, "-o")) {
+                if (++i == argc)
+                    goto usage;
+                strcpy(outfile, argv[i]);
+            } else
+                goto usage;
+        } else if (0 == infile[0])
+            strcpy(infile, a);
+        else
+            goto usage;
+    }
+
+    if (0 == infile[0]) {
+usage:
+        fprintf(stderr,
+            "usage: tcc -impdef library.dll [-v] [-o outputfile]\n"
+            "create export definition file (.def) from dll\n"
+            );
+        goto the_end;
+    }
+
+    if (0 == outfile[0]) {
+        strcpy(outfile, tcc_basename(infile));
+        q = strrchr(outfile, '.');
+        if (NULL == q)
+            q = strchr(outfile, 0);
+        strcpy(q, ".def");
+    }
+
+    file = infile;
+#ifdef _WIN32
+    if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL))
+        file = path;
+#endif
+    ret = tcc_get_dllexports(file, &p);
+    if (ret || !p) {
+        fprintf(stderr, "tcc: impdef: %s '%s'\n",
+            ret == -1 ? "can't find file" :
+            ret ==  1 ? "can't read symbols" :
+            ret ==  0 ? "no symbols found in" :
+            "unknown file type", file);
+        ret = 1;
+        goto the_end;
+    }
+
+    if (v)
+        printf("-> %s\n", file);
+
+    op = fopen(outfile, "wb");
+    if (NULL == op) {
+        fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile);
+        goto the_end;
+    }
+
+    fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file));
+    for (q = p, i = 0; *q; ++i) {
+        fprintf(op, "%s\n", q);
+        q += strlen(q) + 1;
+    }
+
+    if (v)
+        printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]);
+
+    ret = 0;
+
+the_end:
+    /* cannot free memory received from tcc_get_dllexports
+       if it came from a dll */
+    /* if (p)
+        tcc_free(p); */
+    if (fp)
+        fclose(fp);
+    if (op)
+        fclose(op);
+    return ret;
+}
+
+#endif /* TCC_TARGET_PE */
+
+/* -------------------------------------------------------------- */
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
+
+#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option)
+{
+    tcc_error("-m%d not implemented.", option);
+}
+
+#else
+#ifdef _WIN32
+#include <process.h>
+
+static char *str_replace(const char *str, const char *p, const char *r)
+{
+    const char *s, *s0;
+    char *d, *d0;
+    int sl, pl, rl;
+
+    sl = strlen(str);
+    pl = strlen(p);
+    rl = strlen(r);
+    for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) {
+        for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) {
+            if (d) {
+                memcpy(d, s0, sl = s - s0), d += sl;
+                memcpy(d, r, rl), d += rl;
+            } else
+                sl += rl - pl;
+        }
+        if (d) {
+            strcpy(d, s0);
+            return d0;
+        }
+    }
+}
+
+static int execvp_win32(const char *prog, char **argv)
+{
+    int ret; char **p;
+    /* replace all " by \" */
+    for (p = argv; *p; ++p)
+        if (strchr(*p, '"'))
+            *p = str_replace(*p, "\"", "\\\"");
+    ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
+    if (-1 == ret)
+        return ret;
+    _cwait(&ret, ret, WAIT_CHILD);
+    exit(ret);
+}
+#define execvp execvp_win32
+#endif /* _WIN32 */
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target)
+{
+    char program[4096];
+    char *a0 = argv[0];
+    int prefix = tcc_basename(a0) - a0;
+
+    snprintf(program, sizeof program,
+        "%.*s%s"
+#ifdef TCC_TARGET_PE
+        "-win32"
+#endif
+        "-tcc"
+#ifdef _WIN32
+        ".exe"
+#endif
+        , prefix, a0, target == 64 ? "x86_64" : "i386");
+
+    if (strcmp(a0, program))
+        execvp(argv[0] = program, argv);
+    tcc_error("could not run '%s'", program);
+}
+
+#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
+/* -------------------------------------------------------------- */
+/* enable commandline wildcard expansion (tcc -o x.exe *.c) */
+
+#ifdef _WIN32
+int _CRT_glob = 1;
+#ifndef _CRT_glob
+int _dowildcard = 1;
+#endif
+#endif
+
+/* -------------------------------------------------------------- */
+/* generate xxx.d file */
+
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
+{
+    FILE *depout;
+    char buf[1024];
+    int i;
+
+    if (!filename) {
+        /* compute filename automatically: dir/file.o -> dir/file.d */
+        snprintf(buf, sizeof buf, "%.*s.d",
+            (int)(tcc_fileextension(target) - target), target);
+        filename = buf;
+    }
+
+    if (s->verbose)
+        printf("<- %s\n", filename);
+
+    /* XXX return err codes instead of error() ? */
+    depout = fopen(filename, "w");
+    if (!depout)
+        tcc_error("could not open '%s'", filename);
+
+    fprintf(depout, "%s: \\\n", target);
+    for (i=0; i<s->nb_target_deps; ++i)
+        fprintf(depout, " %s \\\n", s->target_deps[i]);
+    fprintf(depout, "\n");
+    fclose(depout);
+}
+
+/* -------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h	(revision 331)
@@ -0,0 +1,13 @@
+/* This file is to test compute #include directives.  It's named so
+   that it starts with a pre-processing number which isn't a valid
+   number (42test.h).  Including this must work.  */
+#ifndef INC42_FIRST
+int have_included_42test_h;
+#define INC42_FIRST
+#elif !defined INC42_SECOND
+#define INC42_SECOND
+int have_included_42test_h_second;
+#else
+#define INC42_THIRD
+int have_included_42test_h_third;
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tests/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile	(revision 331)
@@ -5,5 +5,6 @@
 TOP = ..
 include $(TOP)/Makefile
-VPATH = $(top_srcdir)/tests
+VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
+CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS)
 
 # what tests to run
@@ -13,114 +14,138 @@
  libtest \
  test3 \
- moretests
+ memtest \
+ dlltest \
+ abitest \
+ asm-c-connect-test \
+ vla_test-run \
+ cross-test \
+ tests2-dir \
+ pp-dir
+
+BTESTS = test1b test3b btest
 
 # test4 -- problem with -static
-# asmtest -- minor differences with gcc
+# asmtest / asmtest2 -- minor differences with gcc
 # btest -- works on i386 (including win32)
-# test3 -- win32 does not know how to printf long doubles
 
 # bounds-checking is supported only on i386
 ifneq ($(ARCH),i386)
- TESTS := $(filter-out btest,$(TESTS))
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
 endif
 ifdef CONFIG_WIN32
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
+endif
+ifdef CONFIG_OSX # -run only
+ TESTS := hello-run libtest tests2-dir pp-dir
+endif
+ifeq (,$(filter arm64 i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out vla_test-run,$(TESTS))
+endif
+ifeq ($(CONFIG_arm_eabi),yes)
  TESTS := $(filter-out test3,$(TESTS))
 endif
-ifeq ($(TARGETOS),Darwin)
- TESTS := $(filter-out hello-exe test3 btest,$(TESTS))
-endif
-
-ifdef DISABLE_STATIC
- export LD_LIBRARY_PATH:=$(CURDIR)/..
-endif
-
-ifeq ($(TARGETOS),Darwin)
- CFLAGS+=-Wl,-flat_namespace,-undefined,warning
- export MACOSX_DEPLOYMENT_TARGET:=10.2
- NATIVE_DEFINES+=-D_ANSI_SOURCE
-endif
-
-# run local version of tcc with local libraries and includes
-TCCFLAGS = -B$(TOP)
-ifdef CONFIG_WIN32
- TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/include -L$(TOP)
-endif
-
-TCC = $(TOP)/tcc $(TCCFLAGS)
-RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(TOP)/tcc.c $(TCCFLAGS)
-
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS))
+endif
+ifndef CONFIG_cross
+ TESTS := $(filter-out cross-%,$(TESTS))
+endif
+
+ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
+ PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH)
+endif
+
+RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
 DISAS = objdump -d
-
-# libtcc test
-ifdef LIBTCC1
- LIBTCC1:=$(TOP)/$(LIBTCC1)
-endif
-
-all test : $(TESTS)
+DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)
+
+all test : clean-s $(TESTS)
 
 hello-exe: ../examples/ex1.c
 	@echo ------------ $@ ------------
-	$(TCC) $< -o hello$(EXESUF) || ($(TOP)/tcc -vv; exit 1) && ./hello$(EXESUF)
+	$(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
 
 hello-run: ../examples/ex1.c
 	@echo ------------ $@ ------------
-	$(TCC) -run $<
-
-libtest: libtcc_test$(EXESUF) $(LIBTCC1)
-	@echo ------------ $@ ------------
-	./libtcc_test$(EXESUF) lib_path=..
-
-libtcc_test$(EXESUF): libtcc_test.c $(top_builddir)/$(LIBTCC)
-	$(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS)
-
-moretests:
-	@echo ------------ $@ ------------
-	$(MAKE) -C tests2
-
-# test.ref - generate using gcc
-# copy only tcclib.h so GCC's stddef and stdarg will be used
+	$(TCC) -run $< || $(DUMPTCC)
+
+libtest: libtcc_test$(EXESUF)
+	@echo ------------ $@ ------------
+	./libtcc_test$(EXESUF) $(TCCFLAGS)
+
+libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
+%-dir:
+	@echo ------------ $@ ------------
+	$(MAKE) -k -C $*
+
+# test.ref - generate using cc
 test.ref: tcctest.c
-	cp ../include/tcclib.h .
-	gcc -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS)
+	$(CC) -o tcctest.gcc $< $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
 	./tcctest.gcc > $@
 
 # auto test
-test1: test.ref
-	@echo ------------ $@ ------------
-	$(TCC) -run tcctest.c > test.out1
-	@if diff -u test.ref test.out1 ; then echo "Auto Test OK"; fi
+test1 test1b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) -run $< > test.out1
+	@diff -u test.ref test.out1 && echo "Auto Test OK"
 
 # iterated test2 (compile tcc then compile tcctest.c !)
-test2: test.ref
-	@echo ------------ $@ ------------
-	$(TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out2
-	@if diff -u test.ref test.out2 ; then echo "Auto Test2 OK"; fi
+test2 test2b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2
+	@diff -u test.ref test.out2 && echo "Auto Test2 OK"
 
 # iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
-test3: test.ref
-	@echo ------------ $@ ------------
-	$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run tcctest.c > test.out3
-	@if diff -u test.ref test.out3 ; then echo "Auto Test3 OK"; fi
+test3 test3b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
+	@diff -u test.ref test.out3 && echo "Auto Test3 OK"
+
+test%b : TCCFLAGS += -b
 
 # binary output test
-test4: test.ref
+test4: tcctest.c test.ref
 	@echo ------------ $@ ------------
 # object + link output
-	$(TCC) -c -o tcctest3.o tcctest.c
+	$(TCC) -c -o tcctest3.o $<
 	$(TCC) -o tcctest3 tcctest3.o
 	./tcctest3 > test3.out
 	@if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
 # dynamic output
-	$(TCC) -o tcctest1 tcctest.c
+	$(TCC) -o tcctest1 $<
 	./tcctest1 > test1.out
 	@if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
 # dynamic output + bound check
-	$(TCC) -b -o tcctest4 tcctest.c
+	$(TCC) -b -o tcctest4 $<
 	./tcctest4 > test4.out
 	@if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
 # static output
-	$(TCC) -static -o tcctest2 tcctest.c
+	$(TCC) -static -o tcctest2 $<
 	./tcctest2 > test2.out
 	@if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
+
+# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them
+dlltest:
+	@echo ------------ $@ ------------
+	$(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
+	$(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+	./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+ifndef CONFIG_WIN32
+	@echo ------------ $@ with PIC ------------
+	$(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
+	$(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)
+	$(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+	./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+endif
+	@rm tcc2$(EXESUF) libtcc2$(DLLSUF)
+
+memtest:
+	@echo ------------ $@ ------------
+	$(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
+	./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS)
+	./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c
+
 
 # memory and bound check auto test
@@ -132,6 +157,6 @@
 	@for i in $(BOUNDS_OK); do \
 	   echo ; echo --- boundtest $$i ---; \
-	   if $(TCC) -b -run boundtest.c $$i ; then \
-	       echo succeded as expected; \
+	   if $(TCC) -b -run $< $$i ; then \
+	       echo succeeded as expected; \
 	   else\
 	       echo Failed positive test $$i ; exit 1 ; \
@@ -140,5 +165,5 @@
 	for i in $(BOUNDS_FAIL); do \
 	   echo ; echo --- boundtest $$i ---; \
-	   if $(TCC) -b -run boundtest.c $$i ; then \
+	   if $(TCC) -b -run $< $$i ; then \
 	       echo Failed negative test $$i ; exit 1 ;\
 	   else\
@@ -152,17 +177,17 @@
 	@echo ------------ $@ ------------
 	time ./ex2 1238 2 3 4 10 13 4
-	time $(TCC) -run $(top_srcdir)/examples/ex2.c 1238 2 3 4 10 13 4
+	time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4
 	time ./ex3 35
-	time $(TCC) -run $(top_srcdir)/examples/ex3.c 35
-
-weaktest: test.ref
-	$(TCC) -c tcctest.c -o weaktest.tcc.o $(CPPFLAGS) $(CFLAGS)
-	 $(CC) -c tcctest.c -o weaktest.gcc.o -I. $(CPPFLAGS) -w $(CFLAGS)
+	time $(TCC) -run $(TOPSRC)/examples/ex3.c 35
+
+weaktest: tcctest.c test.ref
+	$(TCC) -c $< -o weaktest.tcc.o
+	$(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
 	objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt
 	objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt
 	diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
 
-ex%: $(top_srcdir)/examples/ex%.c
-	$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
+ex%: $(TOPSRC)/examples/ex%.c
+	$(CC) -o $@ $< $(CFLAGS)
 
 # tiny assembler testing
@@ -171,9 +196,68 @@
 	objdump -D asmtest.ref.o > asmtest.ref
 
-asmtest: asmtest.ref
-	@echo ------------ $@ ------------
-	$(TCC) -c asmtest.S
+asmtest asmtest2: asmtest.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(MAYBE_RUN_TCC) -c asmtest.S
 	objdump -D asmtest.o > asmtest.out
 	@if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
+
+# test assembler with tcc compiled by itself
+asmtest2: MAYBE_RUN_TCC = $(RUN_TCC)
+
+# Check that code generated by libtcc is binary compatible with
+# that generated by CC
+abitest-cc$(EXESUF): abitest.c $(LIBTCC)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w
+
+abitest-tcc$(EXESUF): abitest.c libtcc.c
+	$(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS)
+
+ABITESTS := abitest-cc$(EXESUF)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ ABITESTS += abitest-tcc$(EXESUF)
+endif
+
+abitest: $(ABITESTS)
+	@echo ------------ $@ ------------
+	./abitest-cc$(EXESUF) $(TCCFLAGS)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+	./abitest-tcc$(EXESUF) $(TCCFLAGS)
+endif
+
+vla_test$(EXESUF): vla_test.c
+	$(TCC) -o $@ $^
+
+vla_test-run: vla_test$(EXESUF)
+	@echo ------------ $@ ------------
+	./vla_test$(EXESUF)
+
+asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
+	$(TCC) -o $@ $^
+
+asm-c-connect-%.o: asm-c-connect-%.c
+	$(TCC) -c -o $@ $<
+
+asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o
+	$(TCC) -o $@ $^
+
+asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF)
+	@echo ------------ $@ ------------
+	./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1
+	./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2
+	@diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok"
+
+cross-test :
+	@echo ------------ $@ ------------
+	$(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+	$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+	$(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
 
 # targets for development
@@ -194,6 +278,12 @@
 # clean
 clean:
-	$(MAKE) -C tests2 $@
-	rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.gcc *.exe \
-	   hello libtcc_test tcctest[1234] ex? tcc_g tcclib.h
-
+	rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc
+	rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234]
+	rm -f asm-c-connect$(EXESUF)
+	rm -f ex? tcc_g weaktest.*.txt *.def
+	@$(MAKE) -C tests2 $@
+	@$(MAKE) -C pp $@
+
+# silent clean, used before running tests
+clean-s:
+	@$(MAKE) -s --no-print-directory clean
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c	(revision 331)
@@ -0,0 +1,691 @@
+#include <libtcc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
+#endif
+
+static int g_argc;
+static char **g_argv;
+
+static void set_options(TCCState *s, int argc, char **argv)
+{
+    int i;
+    for (i = 1; i < argc; ++i) {
+        char *a = argv[i];
+        if (a[0] == '-') {
+            if (a[1] == 'B')
+                tcc_set_lib_path(s, a+2);
+            else if (a[1] == 'I')
+                tcc_add_include_path(s, a+2);
+            else if (a[1] == 'L')
+                tcc_add_library_path(s, a+2);
+        }
+    }
+}
+
+typedef int (*callback_type) (void*);
+
+/*
+ * Compile source code and call a callback with a pointer to the symbol "f".
+ */
+static int run_callback(const char *src, callback_type callback) {
+  TCCState *s;
+  int result;
+  void *ptr;
+  
+  s = tcc_new();
+  if (!s)
+    return -1;
+
+  set_options(s, g_argc, g_argv);
+
+  if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1)
+    return -1;
+  if (tcc_compile_string(s, src) == -1)
+    return -1;
+  if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
+    return -1;
+  
+  ptr = tcc_get_symbol(s, "f");
+  if (!ptr)
+    return -1;
+  result = callback(ptr);
+  
+  tcc_delete(s);
+  
+  return result;
+}
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+
+#define RET_PRIMITIVE_TEST(name, type, val) \
+  static int ret_ ## name ## _test_callback(void *ptr) { \
+    type (*callback) (type) = (type(*)(type))ptr; \
+    type x = val; \
+    type y = callback(x); \
+    return (y == x+x) ? 0 : -1; \
+  } \
+  \
+  static int ret_ ## name ## _test(void) { \
+    const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \
+    return run_callback(src, ret_ ## name ## _test_callback); \
+  }
+
+RET_PRIMITIVE_TEST(int, int, 70000)
+RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
+RET_PRIMITIVE_TEST(float, float, 63.0)
+RET_PRIMITIVE_TEST(double, double, 14789798.0)
+RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
+
+/*
+ * ret_2float_test:
+ * 
+ * On x86-64, a struct with 2 floats should be packed into a single
+ * SSE register (VT_DOUBLE is used for this purpose).
+ */
+typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;
+typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type);
+
+static int ret_2float_test_callback(void *ptr) {
+  ret_2float_test_function_type f = (ret_2float_test_function_type)ptr;
+  ret_2float_test_type a = {10, 35};
+  ret_2float_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2float_test(void) {
+  const char *src =
+  "typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;"
+  "ret_2float_test_type f(ret_2float_test_type a) {\n"
+  "  ret_2float_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_2float_test_callback);
+}
+
+/*
+ * ret_2double_test:
+ * 
+ * On x86-64, a struct with 2 doubles should be passed in two SSE
+ * registers.
+ */
+typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;
+typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type);
+
+static int ret_2double_test_callback(void *ptr) {
+  ret_2double_test_function_type f = (ret_2double_test_function_type)ptr;
+  ret_2double_test_type a = {10, 35};
+  ret_2double_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2double_test(void) {
+  const char *src =
+  "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+  "ret_2double_test_type f(ret_2double_test_type a) {\n"
+  "  ret_2double_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_2double_test_callback);
+}
+
+/*
+ * ret_8plus2double_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 7
+ * arguments fit into registers, the 8th doesn't, but the 9th argument
+ * fits into the 8th XMM register.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the double at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double);
+
+static int ret_8plus2double_test_callback(void *ptr) {
+  ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr;
+  ret_2double_test_type a = {10, 35};
+  ret_2double_test_type r;
+  r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38);
+  return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_8plus2double_test(void) {
+  const char *src =
+  "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+  "ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n"
+  "  ret_2double_test_type r = { x8, x8 };\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_8plus2double_test_callback);
+}
+
+/*
+ * ret_mixed_test:
+ *
+ * On x86-64, a struct with a double and a 64-bit integer should be
+ * passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;
+typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type);
+
+static int ret_mixed_test_callback(void *ptr) {
+  ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr;
+  ret_mixed_test_type a = {10, 35};
+  ret_mixed_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed_test(void) {
+  const char *src =
+  "typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;"
+  "ret_mixed_test_type f(ret_mixed_test_type a) {\n"
+  "  ret_mixed_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed_test_callback);
+}
+
+/*
+ * ret_mixed2_test:
+ *
+ * On x86-64, a struct with two floats and two 32-bit integers should
+ * be passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type;
+typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type);
+
+static int ret_mixed2_test_callback(void *ptr) {
+  ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr;
+  ret_mixed2_test_type a = {10, 5, 35, 7 };
+  ret_mixed2_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed2_test(void) {
+  const char *src =
+  "typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;"
+  "ret_mixed2_test_type f(ret_mixed2_test_type a) {\n"
+  "  ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed2_test_callback);
+}
+
+/*
+ * ret_mixed3_test:
+ *
+ * On x86-64, this struct should be passed in two integer registers.
+ */
+typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;
+typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type);
+
+static int ret_mixed3_test_callback(void *ptr) {
+  ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr;
+  ret_mixed3_test_type a = {10, 5, 35, 7 };
+  ret_mixed3_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed3_test(void) {
+  const char *src =
+  "typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;"
+  "ret_mixed3_test_type f(ret_mixed3_test_type a) {\n"
+  "  ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed3_test_callback);
+}
+
+/*
+ * reg_pack_test: return a small struct which should be packed into
+ * registers (Win32) during return.
+ */
+typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;
+typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type);
+
+static int reg_pack_test_callback(void *ptr) {
+  reg_pack_test_function_type f = (reg_pack_test_function_type)ptr;
+  reg_pack_test_type a = {10, 35};
+  reg_pack_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_test(void) {
+  const char *src =
+  "typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;"
+  "reg_pack_test_type f(reg_pack_test_type a) {\n"
+  "  reg_pack_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, reg_pack_test_callback);
+}
+
+/*
+ * reg_pack_longlong_test: return a small struct which should be packed into
+ * registers (x86-64) during return.
+ */
+typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;
+typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type);
+
+static int reg_pack_longlong_test_callback(void *ptr) {
+  reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr;
+  reg_pack_longlong_test_type a = {10, 35};
+  reg_pack_longlong_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_longlong_test(void) {
+  const char *src =
+  "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+  "reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n"
+  "  reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, reg_pack_longlong_test_callback);
+}
+
+/*
+ * ret_6plus2longlong_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 5
+ * arguments fit into registers, the 6th doesn't, but the 7th argument
+ * fits into the 6th argument integer register, %r9.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the longlong at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long);
+
+static int ret_6plus2longlong_test_callback(void *ptr) {
+  ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr;
+  reg_pack_longlong_test_type a = {10, 35};
+  reg_pack_longlong_test_type r;
+  r = f(0, 0, 0, 0, 0, a, 37, 38);
+  return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_6plus2longlong_test(void) {
+  const char *src =
+  "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+  "reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n"
+  "  reg_pack_longlong_test_type r = { x8, x8 };\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_6plus2longlong_test_callback);
+}
+
+/*
+ * sret_test: Create a struct large enough to be returned via sret
+ * (hidden pointer as first function argument)
+ */
+typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;
+typedef sret_test_type (*sret_test_function_type) (sret_test_type);
+
+static int sret_test_callback(void *ptr) {
+  sret_test_function_type f = (sret_test_function_type)(ptr);
+  sret_test_type x = {5436LL, 658277698LL, 43878957LL};
+  sret_test_type r = f(x);
+  return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1;
+}
+
+static int sret_test(void) {
+  const char *src =
+  "typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n"
+  "sret_test_type f(sret_test_type x) {\n"
+  "  sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, sret_test_callback);
+}
+
+/*
+ * one_member_union_test:
+ * 
+ * In the x86-64 ABI a union should always be passed on the stack. However
+ * it appears that a single member union is treated by GCC as its member.
+ */
+typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;
+typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type);
+
+static int one_member_union_test_callback(void *ptr) {
+  one_member_union_test_function_type f = (one_member_union_test_function_type)ptr;
+  one_member_union_test_type a, b;
+  a.x = 34;
+  b = f(a);
+  return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int one_member_union_test(void) {
+  const char *src =
+  "typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n"
+  "one_member_union_test_type f(one_member_union_test_type a) {\n"
+  "  one_member_union_test_type b;\n"
+  "  b.x = a.x * 2;\n"
+  "  return b;\n"
+  "}\n";
+  return run_callback(src, one_member_union_test_callback);
+}
+
+/*
+ * two_member_union_test:
+ * 
+ * In the x86-64 ABI a union should always be passed on the stack.
+ */
+typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
+typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type);
+
+static int two_member_union_test_callback(void *ptr) {
+  two_member_union_test_function_type f = (two_member_union_test_function_type)ptr;
+  two_member_union_test_type a, b;
+  a.x = 34;
+  b = f(a);
+  return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int two_member_union_test(void) {
+  const char *src =
+  "typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n"
+  "two_member_union_test_type f(two_member_union_test_type a) {\n"
+  "  two_member_union_test_type b;\n"
+  "  b.x = a.x * 2;\n"
+  "  return b;\n"
+  "}\n";
+  return run_callback(src, two_member_union_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
+typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
+ 
+static int many_struct_test_callback(void *ptr) {
+  many_struct_test_function_type f = (many_struct_test_function_type)ptr;
+  many_struct_test_type v = {1, 2, 3};
+  many_struct_test_type r = f(v,v,v,v,v,v);
+  return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1;
+}
+
+static int many_struct_test(void) {
+  const char *src =
+  "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n"
+  "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n"
+  "  many_struct_test_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
+typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
+ 
+static int many_struct_test_2_callback(void *ptr) {
+  many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
+  many_struct_test_2_type v = {1,2};
+  many_struct_test_2_type r = f(v,v,v,v,v,v);
+  return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_2(void) {
+  const char *src =
+  "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n"
+  "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n"
+  "  many_struct_test_2_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_2_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;
+typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...);
+typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type;
+
+static void many_struct_test_3_dummy(double d, ...)
+{
+  volatile double x = d;
+}
+
+static int many_struct_test_3_callback(void *ptr) {
+  many_struct_test_3_struct_type s = { ptr, };
+  many_struct_test_3_struct_type *s2 = &s;
+  s2->f2 = &s2->f;
+  many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2);
+  many_struct_test_3_function_type f = *(s2->f2);
+  many_struct_test_3_type v = {1,2};
+  many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0);
+  return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_3(void) {
+  const char *src =
+  "typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n"
+  "many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n"
+  "  many_struct_test_3_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_3_callback);
+}
+
+/*
+ * stdarg_test: Test variable argument list ABI
+ */
+
+typedef struct {long long a, b, c;} stdarg_test_struct_type;
+typedef void (*stdarg_test_function_type) (int,int,int,...);
+
+static int stdarg_test_callback(void *ptr) {
+  stdarg_test_function_type f = (stdarg_test_function_type)ptr;
+  int x;
+  double y;
+  stdarg_test_struct_type z = {1, 2, 3}, w;
+  f(10, 10, 5,
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x,
+    1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y,
+    z, z, z, z, z, &w);
+  return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1;
+}
+
+static int stdarg_test(void) {
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n"
+  "void f(int n_int, int n_float, int n_struct, ...) {\n"
+  "  int i, ti = 0;\n"
+  "  double td = 0.0;\n"
+  "  stdarg_test_struct_type ts = {0,0,0}, tmp;\n"
+  "  va_list ap;\n"
+  "  va_start(ap, n_struct);\n"
+  "  for (i = 0, ti = 0; i < n_int; ++i)\n"
+  "    ti += va_arg(ap, int);\n"
+  "  *va_arg(ap, int*) = ti;\n"
+  "  for (i = 0, td = 0; i < n_float; ++i)\n"
+  "    td += va_arg(ap, double);\n"
+  "  *va_arg(ap, double*) = td;\n"
+  "  for (i = 0; i < n_struct; ++i) {\n"
+  "    tmp = va_arg(ap, stdarg_test_struct_type);\n"
+  "    ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;"
+  "  }\n"
+  "  *va_arg(ap, stdarg_test_struct_type*) = ts;\n"
+  "  va_end(ap);"
+  "}\n";
+  return run_callback(src, stdarg_test_callback);
+}
+
+typedef struct {long long a, b;} stdarg_many_test_struct_type;
+typedef void (*stdarg_many_test_function_type) (int, int, int, int, int,
+						stdarg_many_test_struct_type,
+						int, int, ...);
+
+static int stdarg_many_test_callback(void *ptr)
+{
+  stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr;
+  int x;
+  stdarg_many_test_struct_type l = {10, 11};
+  f(1, 2, 3, 4, 5, l, 6, 7, &x, 44);
+  return x == 44 ? 0 : -1;
+}
+
+static int stdarg_many_test(void)
+{
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n"
+  "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n"
+  "  va_list ap;\n"
+  "  int *p;\n"
+  "  va_start (ap, g);\n"
+  "  p = va_arg(ap, int*);\n"
+  "  *p = va_arg(ap, int);\n"
+  "  va_end (ap);\n"
+  "}\n";
+  return run_callback(src, stdarg_many_test_callback);
+}
+
+/*
+ * Test Win32 stdarg handling, since the calling convention will pass a pointer
+ * to the struct and the stdarg pointer must point to that pointer initially.
+ */
+
+typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;
+typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...);
+
+static int stdarg_struct_test_callback(void *ptr) {
+  stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr;
+  stdarg_struct_test_struct_type v = {10, 35, 99};
+  int x = f(v, 234);
+  return (x == 378) ? 0 : -1;
+}
+
+static int stdarg_struct_test(void) {
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n"
+  "int f(stdarg_struct_test_struct_type a, ...) {\n"
+  "  va_list ap;\n"
+  "  va_start(ap, a);\n"
+  "  int z = va_arg(ap, int);\n"
+  "  va_end(ap);\n"
+  "  return z + a.a + a.b + a.c;\n"
+  "}\n";
+  return run_callback(src, stdarg_struct_test_callback);
+}
+
+/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */
+
+typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE);
+
+static int arg_align_test_callback(void *ptr) {
+  arg_align_test_callback_type f = (arg_align_test_callback_type)ptr;
+  long double x = f(12, 0, 25, 0, 37);
+  return (x == 74) ? 0 : -1;
+}
+
+static int arg_align_test(void) {
+  const char *src = 
+  "long double f(long double a, int b, long double c, int d, long double e) {\n"
+  "  return a + c + e;\n"
+  "}\n";
+  return run_callback(src, arg_align_test_callback);
+}
+
+#define RUN_TEST(t) \
+  if (!testname || (strcmp(#t, testname) == 0)) { \
+    fputs(#t "... ", stdout); \
+    fflush(stdout); \
+    if (t() == 0) { \
+      fputs("success\n", stdout); \
+    } else { \
+      fputs("failure\n", stdout); \
+      retval = EXIT_FAILURE; \
+    } \
+  }
+
+int main(int argc, char **argv) {
+  int i;
+  const char *testname = NULL;
+  int retval = EXIT_SUCCESS;
+  
+  /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+  for (i = 1; i < argc; ++i) {
+    if (!memcmp(argv[i], "run_test=", 9))
+      testname = argv[i] + 9;
+  }
+
+  g_argv = argv, g_argc = argc;
+
+  RUN_TEST(ret_int_test);
+  RUN_TEST(ret_longlong_test);
+  RUN_TEST(ret_float_test);
+  RUN_TEST(ret_double_test);
+  RUN_TEST(ret_longdouble_test);
+  RUN_TEST(ret_2float_test);
+  RUN_TEST(ret_2double_test);
+  RUN_TEST(ret_8plus2double_test);
+  RUN_TEST(ret_6plus2longlong_test);
+#if !defined __x86_64__ || defined _WIN32
+  /* currently broken on x86_64 linux */
+  RUN_TEST(ret_mixed_test);
+  RUN_TEST(ret_mixed2_test);
+#endif
+  RUN_TEST(ret_mixed3_test);
+  RUN_TEST(reg_pack_test);
+  RUN_TEST(reg_pack_longlong_test);
+  RUN_TEST(sret_test);
+  RUN_TEST(one_member_union_test);
+  RUN_TEST(two_member_union_test);
+  RUN_TEST(many_struct_test);
+  RUN_TEST(many_struct_test_2);
+  RUN_TEST(many_struct_test_3);
+  RUN_TEST(stdarg_test);
+  RUN_TEST(stdarg_many_test);
+  RUN_TEST(stdarg_struct_test);
+  RUN_TEST(arg_align_test);
+  return retval;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c	(revision 331)
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+static int x1_c(void)
+{
+    printf(" x1");
+    return 1;
+}
+
+asm(".text;"_"x1: call "_"x1_c; ret");
+
+void callx4(void);
+void callx5_again(void);
+
+void x6()
+{
+    printf(" x6-1");
+}
+
+int main(int argc, char *argv[])
+{
+    printf("*");
+    asm("call "_"x1");
+    asm("call "_"x2");
+    asm("call "_"x3");
+    callx4();
+    asm("call "_"x5");
+    callx5_again();
+    x6();
+    printf(" *\n");
+    return 0;
+}
+
+static
+int x2(void)
+{
+    printf(" x2");
+    return 2;
+}
+
+extern int x3(void);
+
+void x4(void)
+{
+    printf(" x4");
+}
+
+void x5(void);
+void x5(void)
+{
+    printf(" x5");
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c	(revision 331)
@@ -0,0 +1,36 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+int x3(void)
+{
+    printf(" x3");
+    return 3;
+}
+
+/* That callx4 is defined globally (as if ".globl callx4")
+   is a TCC extension.  GCC doesn't behave like this.  */
+void callx4(void);
+__asm__(_"callx4: call "_"x4; ret;"
+#ifndef __TINYC__
+    " .global "_"callx4"
+#endif
+);
+
+extern void x5(void);
+
+void callx5_again(void);
+void callx5_again(void)
+{
+    x5();
+    asm("call "_"x6");
+}
+
+static void x6()
+{
+    printf(" x6-2");
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tests/asmtest.S	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S	(revision 331)
@@ -12,12 +12,20 @@
    .byte 1
 /* .align 16, 0x90 gas is too clever for us with 0x90 fill */
+   .balign 4, 0x92
    .align 16, 0x91 /* 0x91 tests the non-clever behaviour */
    .skip 3
    .skip 15, 0x90
    .string "hello\0world"
-
+/* Macro expansion should work like with C, the #n shouldn't be parsed
+   as asm line comment */
+#define __stringify(n) #n
+#define stringify(n) __stringify(n)
+   .skip 8,0x90
+   .asciz stringify(BLA)
+   .skip 8,0x90
+
+# 28 "asmtest.S"        # a line directive (and a line comment)
+        movl %eax, %ebx # some more asm comment
 /* some label tests */
-
-        movl %eax, %ebx
 L1:
         movl %eax, %ebx
@@ -39,5 +47,5 @@
 mov $1, %edx
 mov $1, %dx
-mov $1, %dl
+mov $1, %cl
 movb $2, 0x100(%ebx,%edx,2)
 movw $2, 0x100(%ebx,%edx,2)
@@ -47,6 +55,19 @@
 movw %ax, 0x100(%ebx,%edx,2)
 
+movw $0x1122,%si
+movl $0x112233,%edx
+movl $0x80000000, %esi
+movl $-0x7fffffff, %edi
+#ifdef __x86_64__
+mov $0x11223344,%rbx
+movq $0x11223344,%rbx
+mov $0x1122334455,%rbx
+movq $0x1122334455,%rbx
+movl $0x11334455,(%rbx)
+#endif
+
 mov %eax, 0x12(,%edx,2)
         
+#ifdef __i386__
 mov %cr3, %edx
 mov %ecx, %cr3
@@ -55,6 +76,31 @@
 movl %db3, %ebx
 movl %dr6, %eax
+#else
+mov %cr3, %rdx
+mov %rcx, %cr3
+movq %cr3, %rax
+movq %db3, %rbx
+movq %dr6, %rax
+mov %cr8, %rsi
+mov %rdi, %cr8
+#endif
 movl %fs, %ecx
 movl %ebx, %fs
+
+#ifdef __x86_64__
+movq %r8, %r9
+movq %r10, %r11
+movq %r12, %r13
+movq %r14, %r15
+movq %rax, %r9
+movq %r15, %rsi
+inc %r9b
+dec %r10w
+not %r11d
+negq %r12
+decb %r13b
+incw %r14w
+notl %r15d
+#endif
 
      movsbl 0x1000, %eax
@@ -69,17 +115,45 @@
      movzb 0x1000, %ax
                 
+     mov $0x12345678,%eax
+
+#ifdef __x86_64__
+     movzb 0x1000, %rax
+     movzbq 0x1000, %rbx
+     movsbq 0x1000, %rdx
+     movzwq 0x1000, %rdi
+     movswq 0x1000, %rdx
+     movslq %eax, %rcx
+     mov $0x12345678,%rax
+     mov $0x12345678,%rdx
+     mov $0x12345678,%r10
+     mov $0x123456789abcdef0,%rax
+     mov $0x123456789abcdef0,%rcx
+     mov $0x123456789abcdef0,%r11
+#endif
         
+#ifdef __i386__
   pushl %eax
-  pushw %ax
   push %eax
   push %cs
+#else
+  pushq %rax
+  push %rax
+#endif
+  pushw %ax
   push %gs
   push $1
   push $100
+  push 0x42(%eax)
+  pop 0x43(%esi)
                                                 
+#ifdef __i386__
   popl %eax
-  popw %ax
   pop %eax
   pop %ds
+#else
+  popq %rax
+  pop %rax
+#endif
+  popw %ax
   pop %fs
           
@@ -112,12 +186,32 @@
   lea 0x1000(%ebx), %ecx
 
+#ifdef __i386__
   les 0x2000, %eax
   lds 0x2000, %ebx
+  lss 0x2000, %edx
+#endif
   lfs 0x2000, %ecx
   lgs 0x2000, %edx
-  lss 0x2000, %edx
 
 addl $0x123, %eax
 add $0x123, %ebx
+add $-16, %ecx
+add $-0x123, %esi
+add $1, %bx
+add $1, %ebx
+add $-1, %bx
+add $-1, %ebx
+add $127, %bx
+addl $127, %ebx
+addl $-128, %ebx
+addl $-128, %ebx
+addl $-129, %ebx
+addl $128, %ebx
+addl $255, %ebx
+addl $256, %ebx
+andb $0xf, %ah
+andb $-15, %cl
+xorb $127, %dh
+cmpb $42, (%eax)
 addl $0x123, 0x100
 addl $0x123, 0x100(%ebx)
@@ -128,4 +222,22 @@
 addl $0x123, (%esp)
 cmpl $0x123, (%esp)
+
+#ifdef __x86_64__
+xor %bl,%ah
+xor %bl,%r8b
+xor %r9b,%bl
+xor %sil,%cl
+add %eax,(%r8d)
+add %ebx,(%r9)
+add %edx,(%r10d,%r11d)
+add %ecx,(%r12,%r13)
+add %esi,(%r14,%r15,4)
+add %edi,0x1000(%rbx,%r12,8)
+add %r11,0x1000(%ebp,%r9d,8)
+movb $12, %ah
+movb $13, %bpl
+movb $14, %dil
+movb $15, %r12b
+#endif
 
 add %eax, (%ebx)
@@ -180,4 +292,6 @@
     div %ecx, %eax
 
+and $15,%bx
+and $-20,%edx
 
 shl %edx
@@ -196,5 +310,9 @@
 call 0x1000
 call L4
+#ifdef __i386__
 call *%eax
+#else
+call *%rax
+#endif
 call *0x1000
 call func1
@@ -205,17 +323,38 @@
 L6:
 
+#ifdef __i386__
 lcall $0x100, $0x1000
+#else
+lcall *0x100
+lcall *(%rax)
+#endif
 
 jmp 0x1000
+jmp *(%edi)
+#ifdef __i386__
 jmp *%eax
+#else
+jmp *%rax
+#endif
 jmp *0x1000
 
+#ifdef __i386__
 ljmp $0x100, $0x1000
+#else
+ljmp *0x100
+ljmp *(%rdi)
+ljmpl *(%esi)
+ljmpw *(%esi)
+#endif
 
 ret
+ret $10
+#ifdef __i386__
 retl
-
-ret $10
 retl $10
+#else
+retq
+retq $10
+#endif
 
 lret
@@ -245,4 +384,6 @@
         
  seto %al
+ setc %al
+ setcb %al
  setnp 0x1000
  setl 0xaaaa
@@ -402,4 +543,5 @@
 
 bswap %edx
+bswapl %ecx
 xadd %ecx, %edx
 xaddb %dl, 0x1000
@@ -412,4 +554,8 @@
 invlpg 0x1000
 cmpxchg8b 0x1002
+#ifdef __x86_64__
+cmpxchg16b (%rax)
+cmpxchg16b (%r10,%r11)
+#endif
 
 fcmovb %st(5), %st
@@ -431,12 +577,23 @@
  cmovs 0x1000, %eax
  cmovns %edx, %edi
+ cmovne %ax, %si
+ cmovbw %ax, %di
+ cmovnbel %edx, %ecx
+#ifdef __x86_64__
+ bswapq %rsi
+ bswapq %r10
+ cmovz %rdi,%rbx
+ cmovpeq %rsi, %rdx
+#endif
 
 int $3
 int $0x10
 
+#ifdef __i386__
     pusha
     popa
-    clc
-    cld
+#endif
+    clc # another comment
+    cld # a comment with embedded ' tick
     cli
     clts
@@ -444,6 +601,11 @@
     lahf
     sahf
+#ifdef __i386__
     pushfl
     popfl
+#else
+    pushfq
+    popfq
+#endif
     pushf
     popf
@@ -451,4 +613,5 @@
     std
     sti
+#ifdef __i386__
     aaa
     aas
@@ -457,4 +620,6 @@
     aad
     aam
+    into
+#endif
     cbw
     cwd
@@ -467,5 +632,4 @@
     leave
     int3
-    into
     iret
     rsm
@@ -512,5 +676,32 @@
     rdpmc
     ud2
-
+#ifdef __x86_64__
+    syscall
+    sysret
+    sysretq
+    lfence
+    mfence
+    sfence
+    prefetchnta 0x18(%rdx)
+    prefetcht0 (%rcx)
+    prefetcht1 (%rsi)
+    prefetcht2 (%rdi)
+    prefetchw (%rdi)
+    clflush 0x1000(%rax,%rcx)
+    fxsaveq (%rdx)
+    fxsaveq (%r11)
+    fxrstorq (%rcx)
+    fxrstorq (%r10)
+
+#endif
+
+    lar %ax,%dx
+    lar %eax,%dx
+    lar %ax,%edx
+    lar %eax,%edx
+#ifdef __x86_64__
+    lar %ax,%rdx
+    lar %eax,%rdx
+#endif
     emms
     movd %edx, %mm3
@@ -557,25 +748,42 @@
         
         
+#ifdef __i386__
     boundl %edx, 0x10000
     boundw %bx, 0x1000
-    
+
     arpl %bx, 0x1000
+#endif
     lar 0x1000, %eax
     lgdt 0x1000
     lidt 0x1000
     lldt 0x1000
+    sgdt 0x1000
+    sidt 0x1000
+    sldt 0x1000
+#ifdef __x86_64__
+    lgdtq 0x1000
+    lidtq 0x1000
+    sgdtq 0x1000
+    sidtq 0x1000
+
+    swapgs
+
+    str %rdx
+    str %r9
+#endif
+
     lmsw 0x1000
     lsl 0x1000, %ecx
     ltr 0x1000
-    
-    sgdt 0x1000
-    sidt 0x1000
-    sldt 0x1000
+    ltr %si
     smsw 0x1000
     str 0x1000
+    str %ecx
+    str %dx
     
     verr 0x1000
     verw 0x1000
   
+#ifdef __i386__
     push %ds
     pushw %ds
@@ -584,7 +792,12 @@
     popw %ds
     popl %ds
+#endif
     fxsave 1(%ebx)
     fxrstor 1(%ecx)
+#ifdef __i386__
     pushl $1
+#else
+    pushq $1
+#endif
     pushw $1
     push $1
@@ -594,4 +807,5 @@
 #endif
 
+#ifndef _WIN32
 ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9:
     xor %eax, %eax
@@ -606,4 +820,159 @@
 .type ft7,%function
 .type ft8,"function"
+#endif
 
     pause
+.rept 6
+    nop
+.endr
+.fill 4,1,0x90
+
+.section .text.one,"ax"
+nop
+.previous
+.pushsection .text.one,"ax"
+nop
+.pushsection .text.two,"ax"
+nop
+.popsection
+.popsection
+
+1: ud2
+.pushsection __bug_table,"a"
+.align 8
+2: .long 1b - 2b
+   .long 0x600000 - 2b
+   .long 1b + 42
+   .long 43 + 1b
+   .long 2b + 144
+   .long 145 + 2b
+   .word 164, 0
+   .org 2b+32
+#ifdef __x86_64__
+   .quad 1b
+#else
+   .long 1b
+#endif
+.popsection
+3: mov %eax,%ecx
+4:
+.pushsection .text.three, "ax"
+nop
+.skip (-((4b-3b) > 0) * 2) , 0x90
+.popsection
+
+.globl overrideme
+.weak overrideme
+  nop
+.globl notimplemented
+notimplemented:
+  ret
+.set overrideme, notimplemented
+overrideme = notimplemented
+overrideme:
+  ret
+
+    movd %esi, %mm1
+    movd %edi, %xmm2
+    movd (%ebx), %mm3
+    movd (%ebx), %xmm3
+    movd %mm1, %esi
+    movd %xmm2, %edi
+    movd %mm3, (%edx)
+    movd %xmm3, (%edx)
+#ifdef __x86_64__
+    movd %rsi, %mm1
+    movd %rdi, %xmm2
+    movd (%rbx), %mm3
+    movd (%rbx), %xmm3
+    movd %mm1, %r12
+    movd %xmm2, %rdi
+    movd %mm3, (%r8)
+    movd %xmm3, (%r13)
+#endif
+
+    movq (%ebp), %mm1
+    movq %mm2, (%edi)
+    movq (%edi), %xmm3
+    movq %mm4, %mm5
+#ifdef __x86_64__
+    movq %rcx, %mm1
+    movq %rdx, %xmm2
+    movq %r13, %xmm3
+    /* movq mem64->xmm is encoded as f30f7e by GAS, but as
+       660f6e by tcc (which really is a movd and would need 
+       a REX.W prefix to be movq).  */
+    movq (%rsi), %xmm3
+    movq %mm1, %rdx
+    movq %xmm3, %rcx
+    movq %xmm4, (%rsi)
+#endif
+
+#define TEST_MMX_SSE(insn) \
+    insn %mm1, %mm2; \
+    insn %xmm2, %xmm3; \
+    insn (%ebx), %xmm3;
+#define TEST_MMX_SSE_I8(insn) \
+    TEST_MMX_SSE(insn) \
+    insn $0x42, %mm4; \
+    insn $0x42, %xmm4;
+
+    TEST_MMX_SSE(packssdw)
+    TEST_MMX_SSE(packsswb)
+    TEST_MMX_SSE(packuswb)
+    TEST_MMX_SSE(paddb)
+    TEST_MMX_SSE(paddw)
+    TEST_MMX_SSE(paddd)
+    TEST_MMX_SSE(paddsb)
+    TEST_MMX_SSE(paddsw)
+    TEST_MMX_SSE(paddusb)
+    TEST_MMX_SSE(paddusw)
+    TEST_MMX_SSE(pand)
+    TEST_MMX_SSE(pandn)
+    TEST_MMX_SSE(pcmpeqb)
+    TEST_MMX_SSE(pcmpeqw)
+    TEST_MMX_SSE(pcmpeqd)
+    TEST_MMX_SSE(pcmpgtb)
+    TEST_MMX_SSE(pcmpgtw)
+    TEST_MMX_SSE(pcmpgtd)
+    TEST_MMX_SSE(pmaddwd)
+    TEST_MMX_SSE(pmulhw)
+    TEST_MMX_SSE(pmullw)
+    TEST_MMX_SSE(por)
+    TEST_MMX_SSE(psllw)
+TEST_MMX_SSE_I8(psllw)
+    TEST_MMX_SSE(pslld)
+TEST_MMX_SSE_I8(pslld)
+    TEST_MMX_SSE(psllq)
+TEST_MMX_SSE_I8(psllq)
+    TEST_MMX_SSE(psraw)
+TEST_MMX_SSE_I8(psraw)
+    TEST_MMX_SSE(psrad)
+TEST_MMX_SSE_I8(psrad)
+    TEST_MMX_SSE(psrlw)
+TEST_MMX_SSE_I8(psrlw)
+    TEST_MMX_SSE(psrld)
+TEST_MMX_SSE_I8(psrld)
+    TEST_MMX_SSE(psrlq)
+TEST_MMX_SSE_I8(psrlq)
+    TEST_MMX_SSE(psubb)
+    TEST_MMX_SSE(psubw)
+    TEST_MMX_SSE(psubd)
+    TEST_MMX_SSE(psubsb)
+    TEST_MMX_SSE(psubsw)
+    TEST_MMX_SSE(psubusb)
+    TEST_MMX_SSE(psubusw)
+    TEST_MMX_SSE(punpckhbw)
+    TEST_MMX_SSE(punpckhwd)
+    TEST_MMX_SSE(punpckhdq)
+    TEST_MMX_SSE(punpcklbw)
+    TEST_MMX_SSE(punpcklwd)
+    TEST_MMX_SSE(punpckldq)
+    TEST_MMX_SSE(pxor)
+
+    cvtpi2ps %mm1, %xmm2
+    cvtpi2ps (%ebx), %xmm2
+    TEST_MMX_SSE(pmaxsw)
+    TEST_MMX_SSE(pmaxub)
+    TEST_MMX_SSE(pminsw)
+    TEST_MMX_SSE(pminub)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tests/boundtest.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c	(revision 331)
@@ -1,4 +1,5 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #define NB_ITS 1000000
@@ -50,4 +51,6 @@
     int *tab4;
 
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
     tab4 = malloc(20 * sizeof(int));
     for(i=0;i<20;i++) {
@@ -56,4 +59,5 @@
     free(tab4);
 
+    fprintf(stderr, "%s end\n", __FUNCTION__);
     return sum;
 }
@@ -64,4 +68,6 @@
     int i, sum = 0;
     int *tab4;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
 
     tab4 = malloc(20 * sizeof(int));
@@ -71,4 +77,5 @@
     free(tab4);
 
+    fprintf(stderr, "%s end\n", __FUNCTION__);
     return sum;
 }
@@ -187,6 +194,41 @@
 }
 
+/* ok */
+int test16()
+{
+    char *demo = "This is only a test.";
+    char *p;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    p = alloca(16);
+    strcpy(p,"12345678901234");
+    printf("alloca: p is %s\n", p);
+
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
+/* error */
+int test17()
+{
+    char *demo = "This is only a test.";
+    char *p;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    p = alloca(16);
+    strcpy(p,"12345678901234");
+    printf("alloca: p is %s\n", p);
+
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
 int (*table_test[])(void) = {
-    test1,
     test1,
     test2,
@@ -204,4 +246,6 @@
     test14,
     test15,
+    test16,
+    test17,
 };
 
@@ -210,9 +254,11 @@
     int index;
     int (*ftest)(void);
+    int index_max = sizeof(table_test)/sizeof(table_test[0]);
 
     if (argc < 2) {
-        printf("usage: boundtest n\n"
-               "test TCC bound checking system\n"
-               );
+        printf(
+    	    "test TCC bound checking system\n"
+	    "usage: boundtest N\n"
+            "  1 <= N <= %d\n", index_max);
         exit(1);
     }
@@ -220,5 +266,11 @@
     index = 0;
     if (argc >= 2)
-        index = atoi(argv[1]);
+        index = atoi(argv[1]) - 1;
+
+    if ((index < 0) || (index >= index_max)) {
+        printf("N is outside of the valid range (%d)\n", index);
+        exit(2);
+    }
+
     /* well, we also use bounds on this ! */
     ftest = table_test[index];
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tests/libtcc_test.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c	(revision 331)
@@ -16,5 +16,14 @@
 }
 
+/* this strinc is referenced by the generated code */
+const char hello[] = "Hello World!";
+
 char my_program[] =
+"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
+"extern int add(int a, int b);\n"
+"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
+" __attribute__((dllimport))\n"
+"#endif\n"
+"extern const char hello[];\n"
 "int fib(int n)\n"
 "{\n"
@@ -27,5 +36,5 @@
 "int foo(int n)\n"
 "{\n"
-"    printf(\"Hello World!\\n\");\n"
+"    printf(\"%s\\n\", hello);\n"
 "    printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
 "    printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
@@ -36,4 +45,5 @@
 {
     TCCState *s;
+    int i;
     int (*func)(int);
 
@@ -45,6 +55,15 @@
 
     /* if tcclib.h and libtcc1.a are not installed, where can we find them */
-    if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
-        tcc_set_lib_path(s, argv[1]+9);
+    for (i = 1; i < argc; ++i) {
+        char *a = argv[i];
+        if (a[0] == '-') {
+            if (a[1] == 'B')
+                tcc_set_lib_path(s, a+2);
+            else if (a[1] == 'I')
+                tcc_add_include_path(s, a+2);
+            else if (a[1] == 'L')
+                tcc_add_library_path(s, a+2);
+        }
+    }
 
     /* MUST BE CALLED before any compilation */
@@ -54,7 +73,8 @@
         return 1;
 
-    /* as a test, we add a symbol that the compiled program can use.
+    /* as a test, we add symbols that the compiled program can use.
        You may also open a dll with tcc_add_dll() and use symbols from that */
     tcc_add_symbol(s, "add", add);
+    tcc_add_symbol(s, "hello", hello);
 
     /* relocate the code */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c	(revision 331)
@@ -0,0 +1,6 @@
+#define hash_hash # ## #
+#define mkstr(a) # a
+#define in_between(a) mkstr(a)
+#define join(c, d) in_between(c hash_hash d)
+char p[] = join(x, y);
+// char p[] = "x ## y";
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect	(revision 331)
@@ -0,0 +1,1 @@
+char p[] = "x ## y";
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c	(revision 331)
@@ -0,0 +1,28 @@
+#define x 3
+#define f(a) f(x * (a))
+#undef x
+#define x 2
+#define g f
+#define z z[0]
+#define h g(~
+#define m(a) a(w)
+#define w 0,1
+#define t(a) a
+#define p() int
+#define q(x) x
+#define r(x,y) x ## y
+#define str(x) # x
+f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+g(x+(3,4)-w) | h 5) & m
+(f)^m(m);
+char c[2][6] = { str(hello), str() };
+/*
+ * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+ * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+ * char c[2][6] = { "hello", "" };
+ */
+#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+#define L22 g(x+(3,4)-w) | h 5) & m\
+(f)^m(m);
+L21
+L22
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect	(revision 331)
@@ -0,0 +1,5 @@
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+char c[2][6] = { "hello", "" };
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c	(revision 331)
@@ -0,0 +1,15 @@
+#define str(s) # s
+#define xstr(s) str(s)
+#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
+	x ## s, x ## t)
+#define INCFILE(n) vers ## n
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+debug(1, 2);
+fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
+	== 0) str(: @\n), s);
+\#include xstr(INCFILE(2).h)
+glue(HIGH, LOW);
+xglue(HIGH, LOW)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect	(revision 331)
@@ -0,0 +1,5 @@
+printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
+fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
+\#include "vers2.h"
+"hello";
+"hello" ", world"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c	(revision 331)
@@ -0,0 +1,4 @@
+#define foobar 1
+#define C(x,y) x##y
+#define D(x) (C(x,bar))
+D(foo)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect	(revision 331)
@@ -0,0 +1,1 @@
+(1)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c	(revision 331)
@@ -0,0 +1,7 @@
+#define t(x,y,z) x ## y ## z
+#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \
+        t(10,,), t(,11,), t(,,12), t(,,) };
+
+int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
+	t(10,,), t(,11,), t(,,12), t(,,) };
+xxx(j)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect	(revision 331)
@@ -0,0 +1,3 @@
+int j[] = { 123, 45, 67, 89,
+ 10, 11, 12, };
+int j[] = { 123, 45, 67, 89, 10, 11, 12, };
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c	(revision 331)
@@ -0,0 +1,5 @@
+#define X(a,b, \
+	c,d) \
+	foo
+
+X(1,2,3,4)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect	(revision 331)
@@ -0,0 +1,1 @@
+foo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c	(revision 331)
@@ -0,0 +1,4 @@
+#define a() YES
+#define b() a
+b()
+b()()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect	(revision 331)
@@ -0,0 +1,2 @@
+a
+YES
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c	(revision 331)
@@ -0,0 +1,4 @@
+// test macro expansion in arguments
+#define s_pos              s_s.s_pos
+#define foo(x) (x)
+foo(hej.s_pos)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect	(revision 331)
@@ -0,0 +1,1 @@
+(hej.s_s.s_pos)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c	(revision 331)
@@ -0,0 +1,4 @@
+#define C(a,b,c) a##b##c
+#define N(x,y) C(x,_,y)
+#define A_O aaaaoooo
+N(A,O)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect	(revision 331)
@@ -0,0 +1,1 @@
+aaaaoooo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c	(revision 331)
@@ -0,0 +1,10 @@
+#define f(x) x
+#define g(x) f(x) f(x
+#define i(x) g(x)) g(x
+#define h(x) i(x))) i(x
+#define k(x) i(x))) i(x))))
+f(x)
+g(x))
+i(x)))
+h(x))))
+k(x))))
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect	(revision 331)
@@ -0,0 +1,5 @@
+x
+x x
+x x x x
+x x x x x x x x
+x x x x x x x x))))
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c	(revision 331)
@@ -0,0 +1,31 @@
+#define D1(s, ...) s
+#define D2(s, ...) s D1(__VA_ARGS__)
+#define D3(s, ...) s D2(__VA_ARGS__)
+#define D4(s, ...) s D3(__VA_ARGS__)
+
+D1(a)
+D2(a, b)
+D3(a, b, c)
+D4(a, b, c, d)
+
+x D4(a, b, c, d) y
+x D4(a, b, c) y
+x D4(a, b) y
+x D4(a) y
+x D4() y
+
+#define GNU_COMMA(X,Y...) X,## Y
+
+x GNU_COMMA(A,B,C) y
+x GNU_COMMA(A,B) y
+x GNU_COMMA(A) y
+x GNU_COMMA() y
+
+#define __sun_attr___noreturn__ __attribute__((__noreturn__))
+#define ___sun_attr_inner(__a) __sun_attr_##__a
+#define __sun_attr__(__a) ___sun_attr_inner __a
+#define __NORETURN __sun_attr__((__noreturn__))
+__NORETURN
+#define X(...)
+#define Y(...)  1 __VA_ARGS__ 2
+Y(X X() ())
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect	(revision 331)
@@ -0,0 +1,15 @@
+a
+a b
+a b c
+a b c d
+x a b c d y
+x a b c y
+x a b y
+x a y
+x y
+x A,B,C y
+x A,B y
+x A y
+x y
+__attribute__((__noreturn__))
+1 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S	(revision 331)
@@ -0,0 +1,8 @@
+#define SRC(y...)                       \
+        9999: y;                        \
+        .section __ex_table, "a";       \
+        .long 9999b, 6001f      ;       \
+        // .previous
+
+    SRC(1: movw (%esi), %bx)
+6001:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect	(revision 331)
@@ -0,0 +1,2 @@
+    9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ;
+6001:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S	(revision 331)
@@ -0,0 +1,6 @@
+# `modelist' label. Each video mode record looks like:
+#ifdef AAA
+# modelist' label. Each video mode record looks like:
+#endif
+.text
+endtext:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect	(revision 331)
@@ -0,0 +1,2 @@
+.text
+endtext:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c	(revision 331)
@@ -0,0 +1,13 @@
+#define W Z
+#define Z(X) W(X,2)
+#define Y(X) Z(X)
+#define X Y
+return X(X(1));
+
+#define P Q
+#define Q(n) P(n,2)
+return P(1);
+
+#define A (B * B)
+#define B (A + A)
+return A + B;
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect	(revision 331)
@@ -0,0 +1,3 @@
+return Z(Z(1,2),2);
+return Q(1,2);
+return ((A + A) * (A + A)) + ((B * B) + (B * B));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c	(revision 331)
@@ -0,0 +1,18 @@
+// insert a space between two tokens if otherwise they
+// would form a single token when read back
+
+#define n(x) x
+
+return (n(long)n(double))d;
+return n(A)n(++)n(+)n(B);
+return n(A)n(+)n(++)n(B);
+return n(A)n(++)n(+)n(+)n(B);
+
+// not a hex float
+return n(0x1E)n(-1);
+
+// unlike gcc but correct
+// XXX: return n(x)+n(x)-n(1)+n(1)-2;
+
+// unlike gcc, but cannot appear in valid C
+// XXX: return n(x)n(x)n(1)n(2)n(x);
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect	(revision 331)
@@ -0,0 +1,5 @@
+return (long double)d;
+return A+++B;
+return A+ ++B;
+return A+++ +B;
+return 0x1E -1;
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c	(revision 331)
@@ -0,0 +1,3 @@
+/* The following should warn */
+#define A ...
+#define A <<=
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect	(revision 331)
@@ -0,0 +1,2 @@
+
+16.c:3: warning: A redefined
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c	(revision 331)
@@ -0,0 +1,14 @@
+#define STR1(u) # u
+#define pass(a) a
+#define __ASM_REG(reg)         STR1(one##reg)
+#define _ASM_DX         __ASM_REG(tok)
+X162 pass(__ASM_REG(tok))
+X161 pass(_ASM_DX)
+X163 pass(STR1(one##tok))
+
+X170 pass(x ## y)
+X171 pass(x pass(##) y)
+
+#define Y(x) Z(x)
+#define X Y
+X180 return X(X(1));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect	(revision 331)
@@ -0,0 +1,6 @@
+X162 "onetok"
+X161 "onetok"
+X163 "one##tok"
+X170 x ## y
+X171 x ## y
+X180 return Z(Z(1));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c	(revision 331)
@@ -0,0 +1,15 @@
+#define M_RETI_ARG27(x,y,z,aa, ...)    aa
+#define M_RET_ARG27(...)        M_RETI_ARG27(__VA_ARGS__)
+#define M_COMMA_P(...)          M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless)
+#define M_EMPTYI_DETECT(...)    0, 1,
+#define M_EMPTYI_P_C1(...)      M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () )
+#define EX
+#define empty(x)
+#define fnlike(x) yeah x
+/* If the following macro is called with empty arg (X183), the use
+   of 'x' between fnlike and '(' doesn't hinder the recognition of this
+   being a further fnlike macro invocation.  */
+#define usefnlike(x) fnlike x (x)
+X181 M_EMPTYI_P_C1()
+X182 M_EMPTYI_P_C1(x)
+X183 usefnlike()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect	(revision 331)
@@ -0,0 +1,3 @@
+X181 1
+X182 0
+X183 yeah
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c	(revision 331)
@@ -0,0 +1,101 @@
+#define M_C2I(a, ...)       a ## __VA_ARGS__
+#define M_C(a, ...)         M_C2I(a, __VA_ARGS__)
+#define M_C3I(a, b, ...)    a ## b ## __VA_ARGS__
+#define M_C3(a, b, ...)     M_C3I(a ,b, __VA_ARGS__)
+
+#define M_RETI_ARG2(a, b, ...)  b
+#define M_RET_ARG2(...)         M_RETI_ARG2(__VA_ARGS__)
+#define M_RETI_ARG27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa, ...)    aa
+#define M_RET_ARG27(...)        M_RETI_ARG27(__VA_ARGS__)
+
+#define M_TOBOOLI_0                 1, 0,
+#define M_BOOL(x)                   M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless)
+
+#define M_IFI_0(true_macro, ...)    __VA_ARGS__
+#define M_IFI_1(true_macro, ...)    true_macro
+#define M_IF(c)                     M_C(M_IFI_, M_BOOL(c))
+
+#define M_FLAT(...)                 __VA_ARGS__
+#define M_INVI_0                    1
+#define M_INVI_1                    0
+#define M_INV(x)                    M_C(M_INVI_, x)
+
+#define M_ANDI_00                   0
+#define M_ANDI_01                   0
+#define M_ANDI_10                   0
+#define M_ANDI_11                   1
+#define M_AND(x,y)                  M_C3(M_ANDI_, x, y)
+
+#define M_ORI_00                    0
+#define M_ORI_01                    1
+#define M_ORI_10                    1
+#define M_ORI_11                    1
+#define M_OR(x,y)                   M_C3(M_ORI_, x, y)
+
+#define M_COMMA_P(...)              M_RET_ARG27(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless)
+
+#define M_EMPTYI_DETECT(...)        0, 1,
+#define M_EMPTYI_P_C1(...)          M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ())
+#define M_EMPTYI_P_C2(...)          M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__)
+#define M_EMPTYI_P_C3(...)          M_COMMA_P(__VA_ARGS__ () )
+#define M_EMPTY_P(...)              M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__))))
+#define M_APPLY_FUNC2B(func, arg1, arg2)        \
+  M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2))
+#define M_MAP2B_0(func, data, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,...) \
+  M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \
+  M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \
+  M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \
+  M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \
+  M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \
+  M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \
+  M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \
+  M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \
+  M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z)
+#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , )
+#define M_INIT_INIT(a)           ,a,
+
+#define M_GET_METHOD(method, method_default, ...)                       \
+  M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,)
+
+#define M_TEST_METHOD_P(method, oplist)                         \
+  M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist))
+
+#define TRUE 1
+#define TEST1(n)                                \
+  M_IF(n)(ok,nok)
+#define TEST2(op)                               \
+  M_TEST_METHOD_P(INIT, op)
+#define TEST3(op)                               \
+  M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok)
+#define TEST4(op) \
+  TEST1(TEST2(op))
+#define KO(a) ((void)1)
+
+/* This checks that the various expansions that ultimately lead to
+   something like 'KO(arg,arg)', where 'KO' comes from a macro
+   expansion reducing from a large macro chain do not are regarded
+   as funclike macro invocation of KO.  E.g. X93 and X94 expand to 'KO',
+   but X95 must not consume the (a,b) arguments outside the M_IF()
+   invocation to reduce the 'KO' macro to an invocation.  Instead
+   X95 should reduce via M_IF(KO)(a,b) to 'a'. 
+   
+   The other lines here are variations on this scheme, with X1 to
+   X6 coming from the bug report at
+   http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */
+X92 M_IF(KO)
+X93 M_GET_METHOD(INIT, 0, INIT(KO))
+X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))
+X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b)
+X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))
+X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok)
+X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+// test begins
+X1 TEST1(TRUE)          // ==> expect ok, get ok
+// First test with a token which is not a macro
+X2 TEST2((INIT(ok)))    // ==> expect 1, get 1
+X3 TEST3((INIT(ok)))    // ==> expect ok, get ok
+// Then test with a token which is a macro, but should not be expanded.
+X4 TEST2((INIT(KO)))    // ==> expect 1, get 1
+X5 TEST4(INIT(KO))
+X6 TEST3((INIT(KO)))    // ==> expect ok, get "error: macro 'KO' used with too many args"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect	(revision 331)
@@ -0,0 +1,14 @@
+X92 M_IFI_1
+X93 KO
+X94 KO
+X95 a
+X96 M_IFI_1
+X97 ok
+X98 (1)(ok, nok)
+X99 ok
+X1 ok
+X2 1
+X3 ok
+X4 1
+X5 nok
+X6 ok
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c	(revision 331)
@@ -0,0 +1,13 @@
+/* Various things I encountered while hacking the pre processor */
+#define wrap(x) x
+#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__)
+#define pr_warn(x,y) pr_warning(x,y)
+#define net_ratelimited_function(function, ...) function(__VA_ARGS__)
+X1 net_ratelimited_function(pr_warn, "pipapo", bla);
+X2 net_ratelimited_function(wrap(pr_warn), "bla", foo);
+#define two m n
+#define chain4(a,b,c,d) a ## b ## c ## d
+X2 chain4(two,o,p,q)
+X3 chain4(o,two,p,q)
+X4 chain4(o,p,two,q)
+X5 chain4(o,p,q,two)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect	(revision 331)
@@ -0,0 +1,6 @@
+X1 printk(KERN_WARNING "pipapo",bla);
+X2 printk(KERN_WARNING "bla",foo);
+X2 twoopq
+X3 otwopq
+X4 optwoq
+X5 opqtwo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c	(revision 331)
@@ -0,0 +1,36 @@
+/* accept 'defined' as result of substitution */
+
+----- 1 ------
+#define AAA 2
+#define BBB
+#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB)
+#if !CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 2 ------
+#undef BBB
+#if CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 3 ------
+#define DEFINED defined
+#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB)
+#if (DDD)
+OK
+#else
+NOT OK
+#endif
+
+----- 4 ------
+#undef AAA
+#if !(DDD)
+OK
+#else
+NOT OK
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect	(revision 331)
@@ -0,0 +1,8 @@
+----- 1 ------
+OK
+----- 2 ------
+OK
+----- 3 ------
+OK
+----- 4 ------
+OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile	(revision 331)
@@ -0,0 +1,49 @@
+#
+# credits: 01..13.c from the pcc cpp-tests suite
+#
+
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/pp
+VPATH = $(SRC)
+
+files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1)))
+TESTS = $(call files,c) $(call files,S)
+
+all test : $(sort $(TESTS))
+
+DIFF_OPTS = -Nu -b -B
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+
+%.test: %.c %.expect
+	@echo PPTest $* ...
+	-@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+	    && rm -f $*.output
+
+%.test: %.S %.expect
+	@echo PPTest $* ...
+	-@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+	    && rm -f $*.output
+
+# automatically generate .expect files with gcc:
+%.expect: # %.c
+	gcc -E -P $*.[cS] >$*.expect 2>&1
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+clean:
+	rm -f *.output
+
+02.test : DIFF_OPTS += -w
+# 15.test : DIFF_OPTS += -I"^XXX:"
+
+# diff options:
+# -b ighore space changes
+# -w ighore all whitespace
+# -B ignore blank lines
+# -I <RE> ignore lines matching RE
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c	(revision 331)
@@ -0,0 +1,27 @@
+X1 __COUNTER__
+X2 __COUNTER__
+#if __COUNTER__
+X3 __COUNTER__
+#endif
+#define pass(x) x
+#define a x __COUNTER__ y
+#define a2 pass(__COUNTER__)
+#define f(c) c __COUNTER__
+#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__
+#define _paste(a,b) a ## b
+#define paste(a,b) _paste(a,b)
+#define _paste3(a,b,c) a ## b ## c
+#define doublepaste(a,b) _paste3(a,b,b)
+#define str(x) #x
+X4 a
+X5 f(a)
+X6 f(b)
+X7 f(__COUNTER__)
+X8 apply(a)
+X9 apply(f(a))
+X10 apply(__COUNTER__)
+X11 apply(a2)
+X12 str(__COUNTER__)
+X13 paste(x,__COUNTER__)
+X14 _paste(x,__COUNTER__)
+X15 doublepaste(x,__COUNTER__)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect	(revision 331)
@@ -0,0 +1,15 @@
+X1 0
+X2 1
+X3 3
+X4 x 4 y
+X5 x 5 y 6
+X6 b 7
+X7 8 9
+X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13
+X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18
+X10 19 19 20 x2 19 21 y2 22
+X11 23 23 24 x2 23 25 y2 26
+X12 "__COUNTER__"
+X13 x27
+X14 x__COUNTER__
+X15 x2828
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/tests/tcctest.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c	(revision 331)
@@ -2,5 +2,5 @@
  * TCC auto test program
  */
-#include "../config.h"
+#include "config.h"
 
 #if GCC_MAJOR >= 3
@@ -15,4 +15,21 @@
 #define CORRECT_CR_HANDLING
 
+#endif
+
+#if defined(_WIN32)
+#define LONG_LONG_FORMAT "%lld"
+#define ULONG_LONG_FORMAT "%llu"
+#else
+#define LONG_LONG_FORMAT "%Ld"
+#define ULONG_LONG_FORMAT "%Lu"
+#endif
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
 #endif
 
@@ -28,5 +45,5 @@
 #define TCCLIB_INC1 <tcclib
 #define TCCLIB_INC2 h>
-#define TCCLIB_INC3 "tcclib"
+#define TCCLIB_INC3 "tcclib.h"
 
 #include TCCLIB_INC
@@ -36,6 +53,5 @@
 #include TCCLIB_INC1.h>
 
-/* gcc 3.2 does not accept that (bug ?) */
-//#include TCCLIB_INC3 ".h"
+#include TCCLIB_INC3
 
 #include <tcclib.h>
@@ -43,4 +59,18 @@
 #include "tcclib.h"
 
+#include "tcctest.h"
+
+/* Test two more ways to include a file named like a pp-number */
+#define INC(name) <tests/name.h>
+#define funnyname 42test.h
+#define incdir tests/
+#define incname < incdir funnyname >
+#define __stringify(x) #x
+#define stringify(x) __stringify(x)
+#include INC(42test)
+#include incname
+#include stringify(funnyname)
+
+void intdiv_test();
 void string_test();
 void expr_test();
@@ -59,4 +89,5 @@
 void expr_ptr_test();
 void bool_test();
+void optimize_out();
 void expr2_test();
 void constant_expr_test();
@@ -91,4 +122,5 @@
 void callsave_test(void);
 void builtin_frame_address_test(void);
+void attrib_test(void);
 
 int fib(int n);
@@ -96,4 +128,11 @@
 void forward_ref(void);
 int isid(int c);
+
+/* Line joining happens before tokenization, so the following
+   must be parsed as ellipsis.  */
+void funny_line_continuation (int, ..\
+. );
+
+char via_volatile (char);
 
 #define A 2
@@ -138,4 +177,9 @@
 #endif
 
+#ifdef __TINYC__
+/* We try to handle this syntax.  Make at least sure it doesn't segfault.  */
+char invalid_function_def()[] {}
+#endif
+
 #define __INT64_C(c)	c ## LL
 #define INT64_MIN	(-__INT64_C(9223372036854775807)-1)
@@ -150,4 +194,69 @@
 #define wq_spin_lock spin_lock
 #define TEST2() wq_spin_lock(a)
+
+#define UINT_MAX ((unsigned) -1)
+
+void intdiv_test(void)
+{
+    printf("18/21=%u\n", 18/21);
+    printf("18%%21=%u\n", 18%21);
+    printf("41/21=%u\n", 41/21);
+    printf("41%%21=%u\n", 41%21);
+    printf("42/21=%u\n", 42/21);
+    printf("42%%21=%u\n", 42%21);
+    printf("43/21=%u\n", 43/21);
+    printf("43%%21=%u\n", 43%21);
+    printf("126/21=%u\n", 126/21);
+    printf("126%%21=%u\n", 126%21);
+    printf("131/21=%u\n", 131/21);
+    printf("131%%21=%u\n", 131%21);
+    printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
+    printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
+
+    printf("18/-21=%u\n", 18/-21);
+    printf("18%%-21=%u\n", 18%-21);
+    printf("41/-21=%u\n", 41/-21);
+    printf("41%%-21=%u\n", 41%-21);
+    printf("42/-21=%u\n", 42/-21);
+    printf("42%%-21=%u\n", 42%-21);
+    printf("43/-21=%u\n", 43/-21);
+    printf("43%%-21=%u\n", 43%-21);
+    printf("126/-21=%u\n", 126/-21);
+    printf("126%%-21=%u\n", 126%-21);
+    printf("131/-21=%u\n", 131/-21);
+    printf("131%%-21=%u\n", 131%-21);
+    printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
+    printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
+
+    printf("-18/21=%u\n", -18/21);
+    printf("-18%%21=%u\n", -18%21);
+    printf("-41/21=%u\n", -41/21);
+    printf("-41%%21=%u\n", -41%21);
+    printf("-42/21=%u\n", -42/21);
+    printf("-42%%21=%u\n", -42%21);
+    printf("-43/21=%u\n", -43/21);
+    printf("-43%%21=%u\n", -43%21);
+    printf("-126/21=%u\n", -126/21);
+    printf("-126%%21=%u\n", -126%21);
+    printf("-131/21=%u\n", -131/21);
+    printf("-131%%21=%u\n", -131%21);
+    printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
+    printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
+
+    printf("-18/-21=%u\n", -18/-21);
+    printf("-18%%-21=%u\n", -18%-21);
+    printf("-41/-21=%u\n", -41/-21);
+    printf("-41%%-21=%u\n", -41%-21);
+    printf("-42/-21=%u\n", -42/-21);
+    printf("-42%%-21=%u\n", -42%-21);
+    printf("-43/-21=%u\n", -43/-21);
+    printf("-43%%-21=%u\n", -43%-21);
+    printf("-126/-21=%u\n", -126/-21);
+    printf("-126%%-21=%u\n", -126%-21);
+    printf("-131/-21=%u\n", -131/-21);
+    printf("-131%%-21=%u\n", -131%-21);
+    printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
+    printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
+}
 
 void macro_test(void)
@@ -236,4 +345,5 @@
     printf("__LINE__=%d __FILE__=%s\n",
            __LINE__, __FILE__);
+#if 0
 #line 200
     printf("__LINE__=%d __FILE__=%s\n",
@@ -243,4 +353,5 @@
            __LINE__, __FILE__);
 #line 227 "tcctest.c"
+#endif
 
     /* not strictly preprocessor, but we test it there */
@@ -257,5 +368,5 @@
 
     /* complicated macros in glibc */
-    printf("INT64_MIN=%Ld\n", INT64_MIN);
+    printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
     {
         int a;
@@ -276,5 +387,5 @@
     MF_t("hi");
     
-    /* test macro substituion inside args (should not eat stream) */
+    /* test macro substitution inside args (should not eat stream) */
     printf("qq=%d\n", qq(qq)(2));
 
@@ -296,7 +407,17 @@
     TEST2();
 
-    /* And again when the name and parenthes are separated by a
+    /* And again when the name and parentheses are separated by a
        comment.  */
     TEST2 /* the comment */ ();
+
+    printf("%s\n", get_basefile_from_header());
+    printf("%s\n", __BASE_FILE__);
+    printf("%s\n", get_file_from_header());
+    printf("%s\n", __FILE__);
+
+    /* Check that funnily named include was in fact included */
+    have_included_42test_h = 1;
+    have_included_42test_h_second = 1;
+    have_included_42test_h_third = 1;
 }
 
@@ -490,11 +611,46 @@
 };
 
+struct S_enum {
+    enum {E6 = 42, E7, E8} e:8;
+};
+
+enum ELong {
+    /* This is either 0 on L32 machines, or a large number
+       on L64 machines.  We should be able to store this.  */
+    EL_large = ((unsigned long)0xf000 << 31) << 1,
+};
+
+enum { BIASU = -1U<<31 };
+enum { BIASS = -1 << 31 };
+
+static int getint(int i)
+{
+  if (i)
+    return 0;
+  else
+    return (int)(-1U << 31);
+}
+
 void enum_test()
 {
     enum test b1;
+    /* The following should give no warning */
+    unsigned *p = &b1;
+    struct S_enum s = {E7};
+    printf("enum: %d\n", s.e);
     printf("enum:\n%d %d %d %d %d %d\n",
            E0, E1, E2, E3, E4, E5);
     b1 = 1;
     printf("b1=%d\n", b1);
+    printf("enum large: %ld\n", EL_large);
+
+    if (getint(0) == BIASU)
+      printf("enum unsigned: ok\n");
+    else
+      printf("enum unsigned: wrong\n");
+    if (getint(0) == BIASS)
+      printf("enum unsigned: ok\n");
+    else
+      printf("enum unsigned: wrong\n");
 }
 
@@ -552,4 +708,9 @@
 
 struct struct1 st1, st2;
+
+struct empty_mem {
+    /* nothing */ ;
+    int x;
+};
 
 int main(int argc, char **argv)
@@ -571,4 +732,5 @@
     expr_ptr_test();
     bool_test();
+    optimize_out();
     expr2_test();
     constant_expr_test();
@@ -605,4 +767,8 @@
     callsave_test();
     builtin_frame_address_test();
+    intdiv_test();
+    if (via_volatile (42) != 42)
+      printf ("via_volatile broken\n");
+    attrib_test();
     return 0; 
 }
@@ -816,4 +982,10 @@
         printf("%d\n", sp[j].i);
     }
+#ifdef __LP64__
+    i = 1;
+    p = (int*)0x100000000UL + i;
+    i = ((long)p) >> 32;
+    printf("largeptr: %p %d\n", p, i);
+#endif
 }
 
@@ -862,8 +1034,82 @@
 };
 
+struct __attribute__((aligned(16))) aligntest5
+{
+    int i;
+};
+struct aligntest6
+{
+    int i;
+} __attribute__((aligned(16)));
+struct aligntest7
+{
+    int i;
+};
+struct aligntest5 altest5[2];
+struct aligntest6 altest6[2];
+int pad1;
+/* altest7 is correctly aligned to 16 bytes also with TCC,
+   but __alignof__ returns the wrong result (4) because we
+   can't store the alignment yet when specified on symbols
+   directly (it's stored in the type so we'd need to make
+   a copy of it). -- FIXED */
+struct aligntest7 altest7[2] __attribute__((aligned(16)));
+
+struct aligntest8
+{
+  int i;
+} __attribute__((aligned(4096)));
+
+struct Large {
+    unsigned long flags;
+    union {
+	void *u1;
+	int *u2;
+    };
+
+    struct {
+	union {
+	    unsigned long index;
+	    void *freelist;
+	};
+	union {
+	    unsigned long counters;
+	    struct {
+		int bla;
+	    };
+	};
+    };
+
+    union {
+	struct {
+	    long u3;
+	    long u4;
+	};
+	void *u5;
+	struct {
+	    unsigned long compound_head;
+	    unsigned int compound_dtor;
+	    unsigned int compound_order;
+	};
+    };
+} __attribute__((aligned(2 * sizeof(long))));
+
+typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
+
+struct aligntest9 {
+    unsigned int buf_nr;
+    unaligned_u64 start_lba;
+};
+
+struct aligntest10 {
+    unsigned int buf_nr;
+    unsigned long long start_lba;
+};
+
 void struct_test()
 {
     struct1 *s;
     union union2 u;
+    struct Large ls;
 
     printf("struct:\n");
@@ -873,4 +1119,5 @@
            sizeof(union union1),
            sizeof(union union2));
+    printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
     st1.f1 = 1;
     st1.f2 = 2;
@@ -901,8 +1148,31 @@
     printf("aligntest4 sizeof=%d alignof=%d\n",
            sizeof(struct aligntest4), __alignof__(struct aligntest4));
+    printf("aligntest5 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest5), __alignof__(struct aligntest5));
+    printf("aligntest6 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest6), __alignof__(struct aligntest6));
+    printf("aligntest7 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest7), __alignof__(struct aligntest7));
+    printf("aligntest8 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest8), __alignof__(struct aligntest8));
+    printf("aligntest9 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest9), __alignof__(struct aligntest9));
+    printf("aligntest10 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest10), __alignof__(struct aligntest10));
+    printf("altest5 sizeof=%d alignof=%d\n",
+           sizeof(altest5), __alignof__(altest5));
+    printf("altest6 sizeof=%d alignof=%d\n",
+           sizeof(altest6), __alignof__(altest6));
+    printf("altest7 sizeof=%d alignof=%d\n",
+           sizeof(altest7), __alignof__(altest7));
            
     /* empty structures (GCC extension) */
     printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
     printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
+
+    printf("Large: sizeof=%d\n", sizeof(ls));
+    memset(&ls, 0, sizeof(ls));
+    ls.compound_head = 42;
+    printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
 }
 
@@ -954,4 +1224,12 @@
 }
 
+static unsigned int calc_vm_flags(unsigned int prot)
+{
+  unsigned int prot_bits;
+  /* This used to segfault in some revisions: */
+  prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
+  return prot_bits;
+}
+
 void bool_test()
 {
@@ -1026,4 +1304,130 @@
             printf("error %d\n", i);
     }
+    printf ("bits = 0x%x\n", calc_vm_flags (0x1));
+}
+
+extern int undefined_function(void);
+extern int defined_function(void);
+
+static inline void refer_to_undefined(void)
+{
+  undefined_function();
+}
+
+void optimize_out(void)
+{
+  int i = 0 ? undefined_function() : defined_function();
+  printf ("oo:%d\n", i);
+  int j = 1 ? defined_function() : undefined_function();
+  printf ("oo:%d\n", j);
+  if (0)
+    printf("oo:%d\n", undefined_function());
+  else
+    printf("oo:%d\n", defined_function());
+  if (1)
+    printf("oo:%d\n", defined_function());
+  else
+    printf("oo:%d\n", undefined_function());
+  while (1) {
+      printf("oow:%d\n", defined_function());
+      break;
+      printf("oow:%d\n", undefined_function());
+  }
+  j = 1;
+  /* Following is a switch without {} block intentionally.  */
+  switch (j)
+    case 1: break;
+  printf ("oos:%d\n", defined_function());
+  /* The following break shouldn't lead to disabled code after
+     the while.  */
+  while (1)
+    break;
+  printf ("ool1:%d\n", defined_function());
+  /* Same for the other types of loops.  */
+  do
+    break;
+  while (1);
+  printf ("ool2:%d\n", defined_function());
+  for (;;)
+    break;
+  printf ("ool3:%d\n", defined_function());
+  /* Normal {} blocks without controlling statements
+     shouldn't reactivate code emission */
+  while (1) {
+	{
+	  break;
+	}
+      printf ("ool4:%d\n", undefined_function());
+  }
+  j = 1;
+  while (j) {
+      if (j == 0)
+	break; /* this break shouldn't disable code outside the if. */
+      printf("ool5:%d\n", defined_function());
+      j--;
+  }
+
+  j = 1;
+  while (j) {
+      if (1)
+	j--;
+      else
+	breakhere: break;
+      printf("ool6:%d\n", defined_function());
+      goto breakhere;
+  }
+
+  /* Test that constants in logical && are optimized: */
+  i = 0 && undefined_function();
+  i = defined_function() && 0 && undefined_function();
+  if (0 && undefined_function())
+    undefined_function();
+  if (defined_function() && 0)
+    undefined_function();
+  if (0 && 0)
+    undefined_function();
+  if (defined_function() && 0 && undefined_function())
+    undefined_function();
+  /* The same for || : */
+  i = 1 || undefined_function();
+  i = defined_function() || 1 || undefined_function();
+  if (1 || undefined_function())
+    ;
+  else
+    undefined_function();
+  if (defined_function() || 1)
+    ;
+  else
+    undefined_function();
+  if (1 || 1)
+    ;
+  else
+    undefined_function();
+  if (defined_function() || 1 || undefined_function())
+    ;
+  else
+    undefined_function();
+
+  if (defined_function() && 0)
+    refer_to_undefined();
+
+  if (0) {
+      (void)sizeof( ({
+		     do { } while (0);
+		     0;
+		     }) );
+      undefined_function();
+  }
+
+  /* Leave the "if(1)return; printf()" in this order and last in the function */
+  if (1)
+    return;
+  printf ("oor:%d\n", undefined_function());
+}
+
+int defined_function(void)
+{
+  static int i = 40;
+  return i++;
 }
 
@@ -1340,4 +1744,17 @@
 };
 
+typedef int arrtype1[];
+arrtype1 sinit19 = {1};
+arrtype1 sinit20 = {2,3};
+typedef int arrtype2[3];
+arrtype2 sinit21 = {4};
+arrtype2 sinit22 = {5,6,7};
+
+/* Address comparisons of non-weak symbols with zero can be const-folded */
+int sinit23[2] = { "astring" ? sizeof("astring") : -1,
+		   &sinit23 ? 42 : -1 };
+
+extern int external_inited = 42;
+
 void init_test(void)
 {
@@ -1354,4 +1771,7 @@
     struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
     int linit17 = sizeof(linit17);
+    int zero = 0;
+    /* Addresses on non-weak symbols are non-zero, but not the access itself */
+    int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
     
     printf("init_test:\n");
@@ -1440,10 +1860,55 @@
     printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
     printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
-}
-
+
+    printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
+    printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
+    printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
+    printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
+    printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
+    printf("arrtype6: %d\n", sizeof(arrtype2));
+
+    printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
+    printf("linit18= %d %d\n", linit18[0], linit18[1]);
+}
+
+void switch_uc(unsigned char uc)
+{
+	switch (uc) {
+	    case 0xfb ... 0xfe:
+		printf("ucsw:1\n");
+		break;
+	    case 0xff:
+		printf("ucsw:2\n");
+		break;
+	    case 0 ... 5:
+		printf("ucsw:3\n");
+		break;
+	    default:
+		printf("ucsw: broken!\n");
+	}
+}
+
+void switch_sc(signed char sc)
+{
+	switch (sc) {
+	    case -5 ... -2:
+		printf("scsw:1\n");
+		break;
+	    case -1:
+		printf("scsw:2\n");
+		break;
+	    case 0 ... 5:
+		printf("scsw:3\n");
+		break;
+	    default:
+		printf("scsw: broken!\n");
+	}
+}
 
 void switch_test()
 {
     int i;
+    unsigned long long ull;
+    long long ll;
 
     for(i=0;i<15;i++) {
@@ -1462,7 +1927,64 @@
             printf("b");
             break;
+        case 0xc33c6b9fU:
+        case 0x7c9eeeb9U:
+            break;
         }
     }
     printf("\n");
+
+    for (i = 1; i <= 5; i++) {
+	ull = (unsigned long long)i << 61;
+	switch (ull) {
+	    case 1ULL << 61:
+		printf("ullsw:1\n");
+		break;
+	    case 2ULL << 61:
+		printf("ullsw:2\n");
+		break;
+	    case 3ULL << 61:
+		printf("ullsw:3\n");
+		break;
+	    case 4ULL << 61:
+		printf("ullsw:4\n");
+		break;
+	    case 5ULL << 61:
+		printf("ullsw:5\n");
+		break;
+	    default:
+		printf("ullsw: broken!\n");
+	}
+    }
+
+    for (i = 1; i <= 5; i++) {
+	ll = (long long)i << 61;
+	switch (ll) {
+	    case 1LL << 61:
+		printf("llsw:1\n");
+		break;
+	    case 2LL << 61:
+		printf("llsw:2\n");
+		break;
+	    case 3LL << 61:
+		printf("llsw:3\n");
+		break;
+	    case 4LL << 61:
+		printf("llsw:4\n");
+		break;
+	    case 5LL << 61:
+		printf("llsw:5\n");
+		break;
+	    default:
+		printf("llsw: broken!\n");
+	}
+    }
+
+    for (i = -5; i <= 5; i++) {
+	switch_uc((unsigned char)i);
+    }
+
+    for (i = -5; i <= 5; i++) {
+	switch_sc ((signed char)i);
+    }
 }
 
@@ -1525,6 +2047,4 @@
         printf("st1.f2 != -1\n");
 
-    /* bit sizes below must be bigger than 32 since GCC doesn't allow
-       long-long bitfields whose size is not bigger than int */
     struct sbf2 {
         long long f1 : 45;
@@ -1539,4 +2059,37 @@
     st2.f2++;
     printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
+
+#if 0
+    Disabled for now until further clarification re GCC compatibility
+    struct sbf3 {
+        int f1 : 7;
+        int f2 : 1;
+        char f3;
+        int f4 : 8;
+        int f5 : 1;
+        int f6 : 16;
+    } st3;
+    printf("sizeof(st3) = %d\n", sizeof(st3));
+#endif
+
+    struct sbf4 {
+	int x : 31;
+	char y : 2;
+    } st4;
+    st4.y = 1;
+    printf("st4.y == %d\n", st4.y);
+    struct sbf5 {
+	int a;
+	char b;
+	int x : 12, y : 4, : 0, : 4, z : 3;
+	char c;
+    } st5 = { 1, 2, 3, 4, -3, 6 };
+    printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
+    struct sbf6 {
+	short x : 12;
+	unsigned char y : 2;
+    } st6;
+    st6.y = 1;
+    printf("st6.y == %d\n", st6.y);
 }
 
@@ -1550,8 +2103,14 @@
 /* declare strto* functions as they are C99 */
 double strtod(const char *nptr, char **endptr);
+
+#if defined(_WIN32)
+float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
+LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
+#else
 float strtof(const char *nptr, char **endptr);
-long double strtold(const char *nptr, char **endptr);
-
-#define FTEST(prefix, type, fmt)\
+LONG_DOUBLE strtold(const char *nptr, char **endptr);
+#endif
+
+#define FTEST(prefix, typename, type, fmt)\
 void prefix ## cmp(type a, type b)\
 {\
@@ -1581,7 +2140,9 @@
     float fa;\
     double da;\
-    long double la;\
+    LONG_DOUBLE la;\
     int ia;\
+    long long llia;\
     unsigned int ua;\
+    unsigned long long llua;\
     type b;\
     fa = a;\
@@ -1590,17 +2151,26 @@
     printf("ftof: %f %f %Lf\n", fa, da, la);\
     ia = (int)a;\
+    llia = (long long)a;\
+    a = (a >= 0) ? a : -a;\
     ua = (unsigned int)a;\
-    printf("ftoi: %d %u\n", ia, ua);\
+    llua = (unsigned long long)a;\
+    printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
     ia = -1234;\
     ua = 0x81234500;\
+    llia = -0x123456789012345LL;\
+    llua = 0xf123456789012345LLU;\
     b = ia;\
     printf("itof: " fmt "\n", b);\
     b = ua;\
     printf("utof: " fmt "\n", b);\
+    b = llia;\
+    printf("lltof: " fmt "\n", b);\
+    b = llua;\
+    printf("ulltof: " fmt "\n", b);\
 }\
 \
 float prefix ## retf(type a) { return a; }\
 double prefix ## retd(type a) { return a; }\
-long double prefix ## retld(type a) { return a; }\
+LONG_DOUBLE prefix ## retld(type a) { return a; }\
 \
 void prefix ## call(void)\
@@ -1612,7 +2182,36 @@
 }\
 \
+void prefix ## signed_zeros(void) \
+{\
+  type x = 0.0, y = -0.0, n, p;\
+  if (x == y)\
+    printf ("Test 1.0 / x != 1.0 / y  returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / y);\
+  else\
+    printf ("x != y; this is wrong!\n");\
+\
+  n = -x;\
+  if (x == n)\
+    printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / n);\
+  else\
+    printf ("x != -x; this is wrong!\n");\
+\
+  p = +y;\
+  if (x == p)\
+    printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / p);\
+  else\
+    printf ("x != +y; this is wrong!\n");\
+  p = -y;\
+  if (x == p)\
+    printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
+            1.0 / x != 1.0 / p);\
+  else\
+    printf ("x != -y; this is wrong!\n");\
+}\
 void prefix ## test(void)\
 {\
-    printf("testing '%s'\n", #type);\
+    printf("testing '%s'\n", #typename);\
     prefix ## cmp(1, 2.5);\
     prefix ## cmp(2, 1.5);\
@@ -1621,9 +2220,10 @@
     prefix ## fcast(-2334.6);\
     prefix ## call();\
-}
-
-FTEST(f, float, "%f")
-FTEST(d, double, "%f")
-FTEST(ld, long double, "%Lf")
+    prefix ## signed_zeros();\
+}
+
+FTEST(f, float, float, "%f")
+FTEST(d, double, double, "%f")
+FTEST(ld, long double, LONG_DOUBLE, "%Lf")
 
 double ftab1[3] = { 1.2, 3.4, -5.6 };
@@ -1632,4 +2232,5 @@
 void float_test(void)
 {
+#if !defined(__arm__) || defined(__ARM_PCS_VFP)
     float fa, fb;
     double da, db;
@@ -1640,5 +2241,5 @@
     printf("sizeof(float) = %d\n", sizeof(float));
     printf("sizeof(double) = %d\n", sizeof(double));
-    printf("sizeof(long double) = %d\n", sizeof(long double));
+    printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
     ftest();
     dtest();
@@ -1657,4 +2258,5 @@
     db = b;
     printf("db = %f\n", db);
+#endif
 }
 
@@ -1675,4 +2277,5 @@
         void (*func)(int);
     } st1;
+    long diff;
 
     printf("funcptr:\n");
@@ -1690,4 +2293,10 @@
     printf("sizeof3 = %d\n", sizeof(&funcptr_test));
     printf("sizeof4 = %d\n", sizeof &funcptr_test);
+    a = 0;
+    func = num + a;
+    diff = func - num;
+    func(42);
+    (func + diff)(42);
+    (num + a)(43);
 }
 
@@ -1699,5 +2308,5 @@
     ub = b;
     /* arith */
-    printf("arith: %Ld %Ld %Ld\n",
+    printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            a + b,
            a - b,
@@ -1705,5 +2314,5 @@
     
     if (b != 0) {
-        printf("arith1: %Ld %Ld\n",
+        printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            a / b,
            a % b);
@@ -1711,5 +2320,5 @@
 
     /* binary */
-    printf("bin: %Ld %Ld %Ld\n",
+    printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            a & b,
            a | b,
@@ -1736,8 +2345,8 @@
     a++;
     b++;
-    printf("arith2: %Ld %Ld\n", a, b);
-    printf("arith2: %Ld %Ld\n", a++, b++);
-    printf("arith2: %Ld %Ld\n", --a, --b);
-    printf("arith2: %Ld %Ld\n", a, b);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
     b = ub = 0;
     printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
@@ -1746,13 +2355,13 @@
 void llshift(long long a, int b)
 {
-    printf("shift: %Ld %Ld %Ld\n",
+    printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            (unsigned long long)a >> b,
            a >> b,
            a << b);
-    printf("shiftc: %Ld %Ld %Ld\n",
+    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            (unsigned long long)a >> 3,
            a >> 3,
            a << 3);
-    printf("shiftc: %Ld %Ld %Ld\n",
+    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
            (unsigned long long)a >> 35,
            a >> 35,
@@ -1764,5 +2373,5 @@
     float fa;
     double da;
-    long double lda;
+    LONG_DOUBLE lda;
     long long la, lb, lc;
     unsigned long long ula, ulb, ulc;
@@ -1771,5 +2380,5 @@
     la = (la << 20) | 0x12345;
     ula = ula << 33;
-    printf("la=%Ld ula=%Lu\n", la, ula);
+    printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
 
     fa = la;
@@ -1781,5 +2390,5 @@
     lb = da;
     lc = lda;
-    printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc);
+    printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
 
     fa = ula;
@@ -1791,5 +2400,5 @@
     ulb = da;
     ulc = lda;
-    printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc);
+    printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
 }
 
@@ -1807,4 +2416,9 @@
 {
     return ((long long int)v->item);
+}
+
+long long llfunc2(long long x, long long y, int z)
+{
+    return x * y * z;
 }
 
@@ -1820,6 +2434,6 @@
     a = ia;
     b = ua;
-    printf("%Ld %Ld\n", a, b);
-    printf("%Ld %Ld %Ld %Lx\n", 
+    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", 
            (long long)1, 
            (long long)-2,
@@ -1827,5 +2441,5 @@
            0x1234567812345679);
     a = llfunc1(-3);
-    printf("%Ld\n", a);
+    printf(LONG_LONG_FORMAT "\n", a);
 
     lloptest(1000, 23);
@@ -1855,23 +2469,30 @@
     lloptest(0x80000000, 0);
 
-    /* another long long spill test */
     {
-        long long *p, v;
+        long long *p, v, **pp;
         v = 1;
         p = &v;
         p[0]++;
-        printf("%lld\n", *p);
+        printf("another long long spill test : %lld\n", *p);
+        pp = &p;
+
+        v = llfunc2(**pp, **pp, ia);
+        printf("a long long function (arm-)reg-args test : %lld\n", v);
     }
-
     a = 68719476720LL;
     b = 4294967295LL;
     printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
 
-    printf("%Ld\n", 0x123456789LLU);
+    printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
+
+    /* long long pointer deref in argument passing test */
+    a = 0x123;
+    long long *p = &a;
+    llshift(*p, 5);
 }
 
 void manyarg_test(void)
 {
-    long double ld = 1234567891234LL;
+    LONG_DOUBLE ld = 1234567891234LL;
     printf("manyarg_test:\n");
     printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
@@ -1879,5 +2500,5 @@
            0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
     printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
-           "%Ld %Ld %f %f\n",
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
            1, 2, 3, 4, 5, 6, 7, 8,
            0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
@@ -1885,15 +2506,13 @@
            42.0, 43.0);
     printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
-           "%Ld %Ld %f %f\n",
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
            ld, 1, 2, 3, 4, 5, 6, 7, 8,
            0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
            1234567891234LL, 987654321986LL,
            42.0, 43.0);
-    /* XXX: known bug of x86-64 */
-#ifndef __x86_64__
     printf("%d %d %d %d %d %d %d %d %Lf\n",
            1, 2, 3, 4, 5, 6, 7, 8, ld);
     printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
-           "%Ld %Ld %f %f %Lf\n",
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
            1, 2, 3, 4, 5, 6, 7, 8,
            0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
@@ -1901,10 +2520,9 @@
            42.0, 43.0, ld);
     printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
-           "%Lf %Ld %Ld %f %f %Lf\n",
+           "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
            1, 2, 3, 4, 5, 6, 7, 8,
            0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
            ld, 1234567891234LL, 987654321986LL,
            42.0, 43.0, ld);
-#endif
 }
 
@@ -1916,5 +2534,5 @@
     double d;
     long long ll;
-    long double ld;
+    LONG_DOUBLE ld;
 
     va_start(aq, fmt);
@@ -1942,8 +2560,8 @@
             case 'l':
                 ll = va_arg(ap, long long);
-                printf("%Ld", ll);
+                printf(LONG_LONG_FORMAT, ll);
                 break;
             case 'F':
-                ld = va_arg(ap, long double);
+                ld = va_arg(ap, LONG_DOUBLE);
                 printf("%Lf", ld);
                 break;
@@ -1978,7 +2596,15 @@
 }
 
+void stdarg_for_libc(const char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+}
+
 void stdarg_test(void)
 {
-    long double ld = 1234567891234LL;
+    LONG_DOUBLE ld = 1234567891234LL;
     struct myspace bob;
 
@@ -1986,10 +2612,7 @@
     vprintf1("%f %d %f\n", 1.0, 2, 3.0);
     vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
-    vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L);
-#ifdef __x86_64__
-    /* a bug of x86's TCC */
+    vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
     vprintf1("%d %f %l %F %d %f %l %F\n",
-             1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L);
-#endif
+             1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
     vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
              1, 2, 3, 4, 5, 6, 7, 8,
@@ -2027,4 +2650,5 @@
     bob.profile = 42;
     stdarg_for_struct(bob, bob, bob, bob.profile);
+    stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
 }
 
@@ -2072,9 +2696,36 @@
 int *rel2 = &reltab[2];
 
+#ifdef _WIN64
+void relocation_test(void) {}
+#else
+void getmyaddress(void)
+{
+    printf("in getmyaddress\n");
+}
+
+#ifdef __LP64__
+long __pa_symbol(void)
+{
+    /* This 64bit constant was handled incorrectly, it was used as addend
+       (which can hold 64bit just fine) in connection with a symbol,
+       and TCC generates wrong code for that (displacements are 32bit only).
+       This effectively is "+ 0x80000000", and if addresses of globals
+       are below 2GB the result should be a number without high 32 bits set.  */
+       return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
+}
+#endif
+
+unsigned long theaddress = (unsigned long)getmyaddress;
 void relocation_test(void)
 {
+    void (*fptr)(void) = (void (*)(void))theaddress;
     printf("*rel1=%d\n", *rel1);
     printf("*rel2=%d\n", *rel2);
-}
+    fptr();
+#ifdef __LP64__
+    printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
+#endif
+}
+#endif
 
 void old_style_f(a,b,c)
@@ -2105,5 +2756,5 @@
 void alloca_test()
 {
-#if defined __i386__ || defined __x86_64__
+#if defined __i386__ || defined __x86_64__ || defined __arm__
     char *p = alloca(16);
     strcpy(p,"123456789012345");
@@ -2138,5 +2789,5 @@
     tab1_ptr = tab1;
     tab2_ptr = tab2;
-    printf("Test C99 VLA 2 (ptrs substract): ");
+    printf("Test C99 VLA 2 (ptrs subtract): ");
     printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
     printf("Test C99 VLA 3 (ptr add): ");
@@ -2174,5 +2825,7 @@
 }
 
+#ifndef __TINYC__
 typedef __SIZE_TYPE__ uintptr_t;
+#endif
 
 void sizeof_test(void)
@@ -2218,4 +2871,21 @@
     printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
     printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
+
+    /* sizes of VLAs need to be evaluated even inside sizeof: */
+    a = 2;
+    printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
+    /* And checking if sizeof compound literal works.  Parenthesized: */
+    printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
+	   sizeof( (struct {int i; int j;}){4,5} ));
+    /* And as direct sizeof argument (as unary expression): */
+    printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
+	   sizeof (struct {short i; short j;}){4,5} );
+
+    /* sizeof(x && y) should be sizeof(int), even if constant
+       evaluating is possible. */
+    printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
+    printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
+    printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
+    printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
 }
 
@@ -2232,8 +2902,20 @@
 }
 
+
+struct hlist_node;
+struct hlist_head {
+    struct hlist_node *first, *last;
+};
+
+void consume_ulong (unsigned long i)
+{
+    i = 0;
+}
+
 void statement_expr_test(void)
 {
     int a, i;
 
+    /* Basic stmt expr test */
     a = 0;
     for(i=0;i<10;i++) {
@@ -2247,4 +2929,46 @@
     printf("a=%d\n", a);
     
+    /* Test that symbols aren't freed prematurely.
+       With SYM_DEBUG valgrind will show a read from a freed
+       symbol, and tcc will show an (invalid) warning on the initialization
+       of 'ptr' below, if symbols are popped after the stmt expr.  */
+    void *v = (void*)39;
+    typeof(({
+	    (struct hlist_node *)v;
+	    })) x;
+    typeof (x)
+	ptr = (struct hlist_node *)v;
+
+    /* This part used to segfault when symbols were popped prematurely.
+       The symbols for the static local would be overwritten with
+       helper symbols from the pre-processor expansions in between.  */
+#define some_attr     __attribute__((aligned(1)))
+#define tps(str) ({                  \
+            static const char *t some_attr = str; \
+            t;                                    \
+          })
+    printf ("stmtexpr: %s %s\n",
+	    tps("somerandomlongstring"),
+	    tps("anotherlongstring"));
+
+    /* Test that the three decls of 't' don't interact.  */
+    int t = 40;
+    int b = ({ int t = 41; t; });
+    int c = ({ int t = 42; t; });
+
+    /* Test that aggregate return values work.  */
+    struct hlist_head h
+	= ({
+	   typedef struct hlist_head T;
+	   long pre = 48;
+	   T t = { (void*)43, (void*)44 };
+	   long post = 49;
+	   t;
+	   });
+    printf ("stmtexpr: %d %d %d\n", t, b, c);
+    printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
+
+    /* Test that we can give out addresses of local labels.  */
+    consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
 }
 
@@ -2280,16 +3004,16 @@
 
 /* inline assembler test */
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
 
 /* from linux kernel */
 static char * strncat1(char * dest,const char * src,size_t count)
 {
-int d0, d1, d2, d3;
+long d0, d1, d2, d3;
 __asm__ __volatile__(
 	"repne\n\t"
 	"scasb\n\t"
-	"decl %1\n\t"
-	"movl %8,%3\n"
-	"1:\tdecl %3\n\t"
+	"dec %1\n\t"
+	"mov %8,%3\n"
+	"1:\tdec %3\n\t"
 	"js 2f\n\t"
 	"lodsb\n\t"
@@ -2297,5 +3021,5 @@
 	"testb %%al,%%al\n\t"
 	"jne 1b\n"
-	"2:\txorl %2,%2\n\t"
+	"2:\txor %2,%2\n\t"
 	"stosb"
 	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
@@ -2307,10 +3031,10 @@
 static char * strncat2(char * dest,const char * src,size_t count)
 {
-int d0, d1, d2, d3;
+long d0, d1, d2, d3;
 __asm__ __volatile__(
 	"repne scasb\n\t" /* one-line repne prefix + string op */
-	"decl %1\n\t"
-	"movl %8,%3\n"
-	"1:\tdecl %3\n\t"
+	"dec %1\n\t"
+	"mov %8,%3\n"
+	"1:\tdec %3\n\t"
 	"js 2f\n\t"
 	"lodsb\n\t"
@@ -2318,5 +3042,5 @@
 	"testb %%al,%%al\n\t"
 	"jne 1b\n"
-	"2:\txorl %2,%2\n\t"
+	"2:\txor %2,%2\n\t"
 	"stosb"
 	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
@@ -2328,5 +3052,5 @@
 static inline void * memcpy1(void * to, const void * from, size_t n)
 {
-int d0, d1, d2;
+long d0, d1, d2;
 __asm__ __volatile__(
 	"rep ; movsl\n\t"
@@ -2346,5 +3070,5 @@
 static inline void * memcpy2(void * to, const void * from, size_t n)
 {
-int d0, d1, d2;
+long d0, d1, d2;
 __asm__ __volatile__(
 	"rep movsl\n\t"  /* one-line rep prefix + string op */
@@ -2369,5 +3093,5 @@
 static __inline__ void sigdelset1(unsigned int *set, int _sig)
 {
-	asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
+	asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
 }
 
@@ -2377,5 +3101,5 @@
 		"rorl $16,%0\n\t"	/* swap words		*/
 		"xchgb %b0,%h0"		/* swap higher bytes	*/
-		:"=q" (x)
+		:"=" "q" (x)
 		: "0" (x));
 	return x;
@@ -2385,5 +3109,13 @@
 {
     unsigned long long res;
+#ifdef __x86_64__
+    /* Using the A constraint is wrong (it means rdx:rax, which is too large)
+       but still test the 32bit->64bit mull.  */
+    unsigned int resh, resl;
+    __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
+    res = ((unsigned long long)resh << 32) | resl;
+#else
     __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
+#endif
     return res;
 }
@@ -2392,16 +3124,311 @@
 {
     unsigned long long res;
+#ifdef __x86_64__
+    /* Using the A constraint is wrong, and increments are tested
+       elsewhere.  */
+    res = a + 1;
+#else
     __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
+#endif
     return res;
 }
 
+struct struct123 {
+    int a;
+    int b;
+};
+struct struct1231 {
+    unsigned long addr;
+};
+
+unsigned long mconstraint_test(struct struct1231 *r)
+{
+    unsigned long ret;
+    unsigned int a[2];
+    a[0] = 0;
+    __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
+	             : "=&r" (ret), "=m" (a)
+	             : "m" (*(struct struct123 *)r->addr));
+    return ret + a[0];
+}
+
+#ifdef __x86_64__
+int fls64(unsigned long long x)
+{
+  int bitpos = -1;
+  asm("bsrq %1,%q0"
+      : "+r" (bitpos)
+      : "rm" (x));
+  return bitpos + 1;
+}
+#endif
+
+void other_constraints_test(void)
+{
+    unsigned long ret;
+    int var;
+#ifndef _WIN64
+    __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
+    printf ("oc1: %d\n", ret == (unsigned long)&var);
+#endif
+}
+
+#ifndef _WIN32
+/* Test global asm blocks playing with aliases.  */
+void base_func(void)
+{
+  printf ("asmc: base\n");
+}
+
+extern void override_func1 (void);
+extern void override_func2 (void);
+
+asm(".weak override_func1\n.set override_func1, base_func");
+asm(".set override_func1, base_func");
+asm(".set override_func2, base_func");
+
+void override_func2 (void)
+{
+  printf ("asmc: override2\n");
+}
+
+/* This checks a construct used by the linux kernel to encode
+   references to strings by PC relative references.  */
+extern int bug_table[] __attribute__((section("__bug_table")));
+char * get_asm_string (void)
+{
+  extern int some_symbol;
+  asm volatile (".globl some_symbol\n"
+		"jmp .+6\n"
+		"1:\n"
+		"some_symbol: .long 0\n"
+		".pushsection __bug_table, \"a\"\n"
+		".globl bug_table\n"
+		"bug_table:\n"
+		/* The first entry (1b-2b) is unused in this test,
+		   but we include it to check if cross-section
+		   PC-relative references work.  */
+		"2:\t.long 1b - 2b, %c0 - 2b\n"
+		".popsection\n" : : "i" ("A string"));
+  char * str = ((char*)bug_table) + bug_table[1];
+  return str;
+}
+
+/* This checks another constructs with local labels.  */
+extern unsigned char alld_stuff[];
+asm(".data\n"
+    ".byte 41\n"
+    "alld_stuff:\n"
+    "661:\n"
+    ".byte 42\n"
+    "662:\n"
+    ".pushsection .data.ignore\n"
+    ".long 661b - .\n" /* This reference to 661 generates an external sym
+                          which shouldn't somehow overwrite the offset that's
+                          already determined for it.  */
+    ".popsection\n"
+    ".byte 662b - 661b\n"  /* So that this value is undeniably 1.  */);
+
+void asm_local_label_diff (void)
+{
+  printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
+}
+
+/* This checks that static local variables are available from assembler.  */
+void asm_local_statics (void)
+{
+  static int localint = 41;
+  asm("incl %0" : "+m" (localint));
+  printf ("asm_local_statics: %d\n", localint);
+}
+#endif
+
+static
 unsigned int set;
 
+void fancy_copy (unsigned *in, unsigned *out)
+{
+  asm volatile ("" : "=r" (*out) : "0" (*in));
+}
+
+void fancy_copy2 (unsigned *in, unsigned *out)
+{
+  asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
+}
+
+#if defined __x86_64__ && !defined _WIN64
+void clobber_r12(void)
+{
+    asm volatile("mov $1, %%r12" ::: "r12");
+}
+#endif
+
+void test_high_clobbers(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+    register long val asm("r12");
+    long val2;
+    /* This tests if asm clobbers correctly save/restore callee saved
+       registers if they are clobbered and if it's the high 8 x86-64
+       registers.  This is fragile for GCC as the constraints do not
+       correctly capture the data flow, but good enough for us.  */
+    asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
+    clobber_r12();
+    asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
+    printf("asmhc: 0x%x\n", val2);
+#endif
+}
+
+static long cpu_number;
+void trace_console(long len, long len2)
+{
+#ifdef __x86_64__
+    /* This generated invalid code when the emission of the switch
+       table isn't disabled.  The asms are necessary to show the bug,
+       normal statements don't work (they need to generate some code
+       even under nocode_wanted, which normal statements don't do,
+       but asms do).  Also at least these number of cases is necessary
+       to generate enough "random" bytes.  They ultimately are enough
+       to create invalid instruction patterns to which the first
+       skip-to-decision-table jump jumps.  If decision table emission
+       is disabled all of this is no problem.
+
+       It also is necessary that the switches are in a statement expression
+       (which has the property of not being enterable from outside. no
+       matter what).  */
+    if (0
+        &&
+            ({
+              long pscr_ret__;
+              switch(len) {
+                case 4:
+                    {
+                       long pfo_ret__;
+                       switch (len2) {
+                         case 8:	printf("bla"); pfo_ret__ = 42; break;
+                       }
+                       pscr_ret__ = pfo_ret__;
+                    }
+                  break;
+                case 8:
+                    {
+                       long pfo_ret__;
+                       switch (len2) {
+                         case 1:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 2:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 4:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 8:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         default: printf("impossible\n");
+                       }
+                       pscr_ret__ = pfo_ret__;
+                    };
+                  break;
+              }
+              pscr_ret__;
+            }))
+      {
+        printf("huh?\n");
+      }
+#endif
+}
+
+void test_asm_dead_code(void)
+{
+  long rdi;
+  /* Try to make sure that xdi contains a zero, and hence will
+     lead to a segfault if the next asm is evaluated without
+     arguments being set up.  */
+  asm volatile ("" : "=D" (rdi) : "0" (0));
+  (void)sizeof (({
+      int var;
+      /* This shouldn't trigger a segfault, either the argument
+         registers need to be set up and the asm emitted despite
+	 this being in an unevaluated context, or both the argument
+	 setup _and_ the asm emission need to be suppressed.  The latter
+	 is better.  Disabling asm code gen when suppression is on
+	 also fixes the above trace_console bug, but that came earlier
+	 than asm suppression.  */
+      asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
+      var;
+  }));
+}
+
+void test_asm_call(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+  static char str[] = "PATH";
+  char *s;
+  /* This tests if a reference to an undefined symbol from an asm
+     block, which isn't otherwise referenced in this file, is correctly
+     regarded as global symbol, so that it's resolved by other object files
+     or libraries.  We chose getenv here, which isn't used anywhere else
+     in this file.  (If we used e.g. printf, which is used we already
+     would have a global symbol entry, not triggering the bug which is
+     tested here).  */
+  /* two pushes so stack remains aligned */
+  asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
+#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
+		"call getenv@plt;"
+#else
+		"call getenv;"
+#endif
+		"pop %%rdi; pop %%rdi"
+		: "=a" (s) : "r" (str));
+  printf("asmd: %s\n", s);
+#endif
+}
+
+#if defined __x86_64__
+# define RX "(%rip)"
+#else
+# define RX
+#endif
+
+void asm_dot_test(void)
+{
+    int x;
+    for (x = 1;; ++x) {
+        int r = x;
+        switch (x) {
+        case 1:
+            asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
+        case 2:
+            asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
+	case 3:
+            asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4");
+            asm(".text; mov X"RX",%eax; jmp p0");
+        case 4:
+            asm(".data; X=.; .int 789; Y=.; .int 999");
+            asm(".text; mov X"RX",%eax; X=Y; jmp p0");
+        case 0:
+	    asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
+	}
+        if (r == x)
+            break;
+        printf("asm_dot_test %d: %d\n", x, r);
+    }
+}
+
 void asm_test(void)
 {
     char buf[128];
-    unsigned int val;
+    unsigned int val, val2;
+    struct struct123 s1;
+    struct struct1231 s2 = { (unsigned long)&s1 };
+    /* Hide the outer base_func, but check later that the inline
+       asm block gets the outer one.  */
+    int base_func = 42;
+    void override_func3 (void);
+    unsigned long asmret;
+#ifdef BOOL_ISOC99
+    _Bool somebool;
+#endif
+    register int regvar asm("%esi");
 
     printf("inline asm:\n");
+
+    // parse 0x1E-1 as 3 tokens in asm mode
+    asm volatile ("mov $0x1E-1,%eax");
+
     /* test the no operand case */
     asm volatile ("xorl %eax, %eax");
@@ -2419,4 +3446,9 @@
     printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
 
+    s1.a = 42;
+    s1.b = 43;
+    printf("mconstraint: %d", mconstraint_test(&s2));
+    printf(" %d %d\n", s1.a, s1.b);
+    other_constraints_test();
     set = 0xff;
     sigdelset1(&set, 2);
@@ -2427,10 +3459,43 @@
  label2:
     __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
-#ifdef __GNUC__ // works strange with GCC 4.3
-    set=0x1080fd;
-#endif
     printf("set=0x%x\n", set);
     val = 0x01020304;
     printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
+#ifndef _WIN32
+    override_func1();
+    override_func2();
+    /* The base_func ref from the following inline asm should find
+       the global one, not the local decl from this function.  */
+    asm volatile(".weak override_func3\n.set override_func3, base_func");
+    override_func3();
+    printf("asmstr: %s\n", get_asm_string());
+    asm_local_label_diff();
+    asm_local_statics();
+#endif
+    /* Check that we can also load structs of appropriate layout
+       into registers.  */
+    asm volatile("" : "=r" (asmret) : "0"(s2));
+    if (asmret != s2.addr)
+      printf("asmstr: failed\n");
+#ifdef BOOL_ISOC99
+    /* Check that the typesize correctly sets the register size to
+       8 bit.  */
+    asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
+    if (!somebool)
+      printf("asmbool: failed\n");
+#endif
+    val = 43;
+    fancy_copy (&val, &val2);
+    printf ("fancycpy(%d)=%d\n", val, val2);
+    val = 44;
+    fancy_copy2 (&val, &val2);
+    printf ("fancycpy2(%d)=%d\n", val, val2);
+    asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
+    printf ("regvar=%x\n", regvar);
+    test_high_clobbers();
+    trace_console(8, 8);
+    test_asm_dead_code();
+    test_asm_call();
+    asm_dot_test();
     return;
  label1:
@@ -2456,4 +3521,7 @@
 void builtin_test(void)
 {
+    short s;
+    int i;
+    long long ll;
 #if GCC_MAJOR >= 3
     COMPAT_TYPE(int, int);
@@ -2466,4 +3534,6 @@
     COMPAT_TYPE(int *, const int *);
     COMPAT_TYPE(char *, unsigned char *);
+    COMPAT_TYPE(char *, signed char *);
+    COMPAT_TYPE(char *, char *);
 /* space is needed because tcc preprocessor introduces a space between each token */
     COMPAT_TYPE(char * *, void *); 
@@ -2473,4 +3543,17 @@
     printf("res = %d\n", __builtin_constant_p(&constant_p_var));
     printf("res = %d\n", __builtin_constant_p(constant_p_var));
+    printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
+    s = 1;
+    ll = 2;
+    i = __builtin_choose_expr (1 != 0, ll, s);
+    printf("bce: %d\n", i);
+    i = __builtin_choose_expr (1 != 1, ll, s);
+    printf("bce: %d\n", i);
+    i = sizeof (__builtin_choose_expr (1, ll, s));
+    printf("bce: %d\n", i);
+    i = sizeof (__builtin_choose_expr (0, ll, s));
+    printf("bce: %d\n", i);
+
+    //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
 }
 
@@ -2525,4 +3608,5 @@
 	printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
 	printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
+	printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
 }
 
@@ -2678,5 +3762,5 @@
 void callsave_test(void)
 {
-#if defined __i386__ || defined __x86_64__
+#if defined __i386__ || defined __x86_64__ || defined __arm__
   int i, s; double *d; double t;
   s = sizeof (double);
@@ -2707,11 +3791,11 @@
 {
     printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
-#if defined(__arm__) && !defined(__GNUC__)
     bfa2(str_offset);
-#endif
 }
 
 void builtin_frame_address_test(void)
 {
+/* builtin_frame_address fails on ARM with gcc which make test3 fail */
+#ifndef __arm__
     char str[] = "__builtin_frame_address";
     char *fp0 = __builtin_frame_address(0);
@@ -2719,3 +3803,77 @@
     printf("str: %s\n", str);
     bfa1(str-fp0);
-}
+#endif
+}
+
+char via_volatile (char i)
+{
+  char volatile vi;
+  vi = i;
+  return vi;
+}
+
+struct __attribute__((__packed__)) Spacked {
+    char a;
+    short b;
+    int c;
+};
+struct Spacked spacked;
+typedef struct __attribute__((__packed__)) {
+    char a;
+    short b;
+    int c;
+} Spacked2;
+Spacked2 spacked2;
+typedef struct Spacked3_s {
+    char a;
+    short b;
+    int c;
+} __attribute__((__packed__)) Spacked3;
+Spacked3 spacked3;
+struct gate_struct64 {
+    unsigned short offset_low;
+    unsigned short segment;
+    unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+    unsigned short offset_middle;
+    unsigned offset_high;
+    unsigned zero1;
+} __attribute__((packed));
+typedef struct gate_struct64 gate_desc;
+gate_desc a_gate_desc;
+void attrib_test(void)
+{
+#ifndef _WIN32
+  printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
+	 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
+  printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
+  printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
+#endif
+}
+extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
+strange_attrib_placement (void);
+
+void * __attribute__((__unused__)) get_void_ptr (void *a)
+{
+  return a;
+}
+
+/* This part checks for a bug in TOK_GET (used for inline expansion),
+   where the large long long constant left the the high bits set for
+   the integer constant token.  */
+static inline
+int __get_order(unsigned long long size)
+{
+  int order;
+  size -= 0xffff880000000000ULL; // this const left high bits set in the token
+    {
+      struct S { int i : 1; } s; // constructed for this '1'
+    }
+  order = size;
+  return order;
+}
+
+/* This just forces the above inline function to be actually emitted.  */
+int force_get_order(unsigned long s)
+{
+    return __get_order(s);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h	(revision 331)
@@ -0,0 +1,9 @@
+static inline const char *get_basefile_from_header(void)
+{
+  return __BASE_FILE__;
+}
+
+static inline const char *get_file_from_header(void)
+{
+  return __FILE__;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c	(revision 331)
@@ -0,0 +1,510 @@
+/*
+ *  Test 128-bit floating-point arithmetic on arm64:
+ *  build with two different compilers and compare the output.
+ *
+ *  Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__))
+
+void check_fail(const char *assertion, const char *file, unsigned int line)
+{
+    printf("%s:%d: Check (%s) failed.", file, line, assertion);
+    exit(1);
+}
+
+typedef struct {
+    unsigned long long x0, x1;
+} u128_t;
+
+float copy_fi(uint32_t x)
+{
+    float f;
+    memcpy(&f, &x, 4);
+    return f;
+}
+
+double copy_di(uint64_t x)
+{
+    double f;
+    memcpy(&f, &x, 8);
+    return f;
+}
+
+long double copy_ldi(u128_t x)
+{
+    long double f;
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+uint32_t copy_if(float f)
+{
+    uint32_t x;
+    memcpy(&x, &f, 4);
+    return x;
+}
+
+uint64_t copy_id(double f)
+{
+    uint64_t x;
+    memcpy(&x, &f, 8);
+    return x;
+}
+
+u128_t copy_ild(long double f)
+{
+    u128_t x;
+    memcpy(&x, &f, 16);
+    return x;
+}
+
+long double make(int sgn, int exp, uint64_t high, uint64_t low)
+{
+    u128_t x = { low,
+                 (0x0000ffffffffffff & high) |
+                 (0x7fff000000000000 & (uint64_t)exp << 48) |
+                 (0x8000000000000000 & (uint64_t)sgn << 63) };
+    return copy_ldi(x);
+}
+
+void cmp(long double a, long double b)
+{
+    u128_t ax = copy_ild(a);
+    u128_t bx = copy_ild(b);
+    int eq = (a == b);
+    int ne = (a != b);
+    int lt = (a < b);
+    int le = (a <= b);
+    int gt = (a > b);
+    int ge = (a >= b);
+
+    check(eq == 0 || eq == 1);
+    check(lt == 0 || lt == 1);
+    check(gt == 0 || gt == 1);
+    check(ne == !eq && le == (lt | eq) && ge == (gt | eq));
+    check(eq + lt + gt < 2);
+
+    printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n",
+           ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt);
+}
+
+void cmps(void)
+{
+    int i, j;
+
+    for (i = 0; i < 2; i++)
+        for (j = 0; j < 2; j++)
+            cmp(make(i, 0, 0, 0), make(j, 0, 0, 0));
+
+    for (i = 0; i < 2; i++) {
+        for (j = 0; j < 64; j++) {
+            long double f1 = make(i, 32767, (uint64_t)1 << j, 0);
+            long double f2 = make(i, 32767, 0, (uint64_t)1 << j);
+            cmp(f1, 0);
+            cmp(f2, 0);
+            cmp(0, f1);
+            cmp(0, f2);
+        }
+    }
+
+    for (i = 0; i < 6; i++)
+        for (j = 0; j < 6; j++)
+            cmp(make(i & 1, i >> 1, 0, 0),
+                make(j & 1, j >> 1, 0, 0));
+
+    for (i = 0; i < 2; i++) {
+        for (j = 0; j < 2; j++) {
+            int a, b;
+            for (a = 0; a < 2; a++) {
+                for (b = 0; b < 2; b++) {
+                    cmp(make(i, j, a, b), make(i, j, 0, 0));
+                    cmp(make(i, j, 0, 0), make(i, j, a, b));
+                }
+            }
+        }
+    }
+}
+
+void xop(const char *name, long double a, long double b, long double c)
+{
+    u128_t ax = copy_ild(a);
+    u128_t bx = copy_ild(b);
+    u128_t cx = copy_ild(c);
+    printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n",
+           name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0);
+}
+
+void fadd(long double a, long double b)
+{
+    xop("add", a, b, a + b);
+}
+
+void fsub(long double a, long double b)
+{
+    xop("sub", a, b, a - b);
+}
+
+void fmul(long double a, long double b)
+{
+    xop("mul", a, b, a * b);
+}
+
+void fdiv(long double a, long double b)
+{
+    xop("div", a, b, a / b);
+}
+
+void nanz(void)
+{
+    // Check NaNs:
+    {
+        long double x[7];
+        int i, j, n = 0;
+        x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53);
+        x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac);
+        x[n++] = make(0, 32767, 0, 1);
+        x[n++] = make(0, 32767, (uint64_t)1 << 46, 0);
+        x[n++] = make(1, 32767, (uint64_t)1 << 47, 0);
+        x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9);
+        x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666);
+        check(n == sizeof(x) / sizeof(*x));
+        for (i = 0; i < n; i++) {
+            for (j = 0; j < n; j++) {
+                fadd(x[i], x[j]);
+                fsub(x[i], x[j]);
+                fmul(x[i], x[j]);
+                fdiv(x[i], x[j]);
+            }
+        }
+    }
+
+    // Check infinities and zeroes:
+    {
+        long double x[6];
+        int i, j, n = 0;
+        x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044);
+        x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19);
+        x[n++] = make(0, 32767, 0, 0);
+        x[n++] = make(1, 32767, 0, 0);
+        x[n++] = make(0, 0, 0, 0);
+        x[n++] = make(1, 0, 0, 0);
+        check(n == sizeof(x) / sizeof(*x));
+        for (i = 0; i < n; i++) {
+            for (j = 0; j < n; j++) {
+                fadd(x[i], x[j]);
+                fsub(x[i], x[j]);
+                fmul(x[i], x[j]);
+                fdiv(x[i], x[j]);
+            }
+        }
+    }
+}
+
+void adds(void)
+{
+    // Check shifting and add/sub:
+    {
+        int i;
+        for (i = -130; i <= 130; i++) {
+            int s1 = (uint32_t)i % 3 < 1;
+            int s2 = (uint32_t)i % 5 < 2;
+            fadd(make(s1, 16384    , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031),
+                 make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448));
+        }
+    }
+
+    // Check normalisation:
+    {
+        uint64_t a0 = 0xc6bab0a6afbef5ed;
+        uint64_t a1 = 0x4f84136c4a2e9b52;
+        int ee[] = { 0, 1, 10000 };
+        int e, i;
+        for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) {
+            int exp = ee[e];
+            fsub(make(0, exp, a1, a0), make(0, 0, 0, 0));
+            for (i = 63; i >= 0; i--)
+                fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0),
+                     make(0, exp, a1 >> i << i, 0));
+            for (i = 63; i >=0; i--)
+                fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1),
+                     make(0, exp, a1, a0 >> i << i));
+        }
+    }
+
+    // Carry/overflow from rounding:
+    {
+        fadd(make(0, 114, -1, -1), make(0, 1, 0, 0));
+        fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0));
+        fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0));
+    }
+}
+
+void muls(void)
+{
+    int i, j;
+
+    {
+        long double max = make(0, 32766, -1, -1);
+        long double min = make(0, 0, 0, 1);
+        fmul(max, max);
+        fmul(max, min);
+        fmul(min, min);
+    }
+
+    for (i = 117; i > 0; i--)
+        fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a),
+             make(i & 1, i, 0, 0));
+
+    fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1));
+    // Round to next exponent:
+    fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1));
+    // Round from subnormal to normal:
+    fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0));
+
+    for (i = 0; i < 2; i++)
+        for (j = 0; j < 112; j++)
+            fmul(make(0, 16383, (uint64_t)1 << i, 0),
+                 make(0, 16383,
+                      j < 64 ? 0 : (uint64_t)1 << (j - 64),
+                      j < 64 ? (uint64_t)1 << j : 0));
+}
+
+void divs(void)
+{
+    int i;
+
+    {
+        long double max = make(0, 32766, -1, -1);
+        long double min = make(0, 0, 0, 1);
+        fdiv(max, max);
+        fdiv(max, min);
+        fdiv(min, max);
+        fdiv(min, min);
+    }
+
+    for (i = 0; i < 64; i++)
+        fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i));
+    for (i = 0; i < 48; i++)
+        fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0));
+}
+
+void cvtlsw(int32_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0);
+}
+
+void cvtlsx(int64_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlsx %016llx %016llx%016llx\n",
+           (long long)(uint64_t)a, x.x1, x.x0);
+}
+
+void cvtluw(uint32_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0);
+}
+
+void cvtlux(uint64_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0);
+}
+
+void cvtil(long double a)
+{
+    u128_t x = copy_ild(a);
+    int32_t b1 = a;
+    int64_t b2 = a;
+    uint32_t b3 = a;
+    uint64_t b4 = a;
+    printf("cvtswl %016llx%016llx %08lx\n",
+           x.x1, x.x0, (long)(uint32_t)b1);
+    printf("cvtsxl %016llx%016llx %016llx\n",
+           x.x1, x.x0, (long long)(uint64_t)b2);
+    printf("cvtuwl %016llx%016llx %08lx\n",
+           x.x1, x.x0, (long)b3);
+    printf("cvtuxl %016llx%016llx %016llx\n",
+           x.x1, x.x0, (long long)b4);
+}
+
+void cvtlf(float a)
+{
+    uint32_t ax = copy_if(a);
+    long double b = a;
+    u128_t bx = copy_ild(b);
+    printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0);
+}
+
+void cvtld(double a)
+{
+    uint64_t ax = copy_id(a);
+    long double b = a;
+    u128_t bx = copy_ild(b);
+    printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0);
+}
+
+void cvtfl(long double a)
+{
+    u128_t ax = copy_ild(a);
+    float b = a;
+    uint32_t bx = copy_if(b);
+    printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx);
+}
+
+void cvtdl(long double a)
+{
+    u128_t ax = copy_ild(a);
+    double b = a;
+    uint64_t bx = copy_id(b);
+    printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx);
+}
+
+void cvts(void)
+{
+    int i, j;
+
+    {
+        uint32_t x = 0xad040c5b;
+        cvtlsw(0);
+        for (i = 0; i < 31; i++)
+            cvtlsw(x >> (31 - i));
+        for (i = 0; i < 31; i++)
+            cvtlsw(-(x >> (31 - i)));
+        cvtlsw(0x80000000);
+    }
+    {
+        uint64_t x = 0xb630a248cad9afd2;
+        cvtlsx(0);
+        for (i = 0; i < 63; i++)
+            cvtlsx(x >> (63 - i));
+        for (i = 0; i < 63; i++)
+            cvtlsx(-(x >> (63 - i)));
+        cvtlsx(0x8000000000000000);
+    }
+    {
+        uint32_t x = 0xad040c5b;
+        cvtluw(0);
+        for (i = 0; i < 32; i++)
+            cvtluw(x >> (31 - i));
+    }
+    {
+        uint64_t x = 0xb630a248cad9afd2;
+        cvtlux(0);
+        for (i = 0; i < 64; i++)
+            cvtlux(x >> (63 - i));
+    }
+
+    for (i = 0; i < 2; i++) {
+        cvtil(make(i, 32767, 0, 1));
+        cvtil(make(i, 32767, (uint64_t)1 << 47, 0));
+        cvtil(make(i, 32767, 123, 456));
+        cvtil(make(i, 32767, 0, 0));
+        cvtil(make(i, 16382, -1, -1));
+        cvtil(make(i, 16383, -1, -1));
+        cvtil(make(i, 16384, 0x7fffffffffff, -1));
+        cvtil(make(i, 16384, 0x800000000000, 0));
+        for (j = 0; j < 68; j++)
+            cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d));
+    }
+
+    cvtlf(copy_fi(0x00000000));
+    cvtlf(copy_fi(0x456789ab));
+    cvtlf(copy_fi(0x7f800000));
+    cvtlf(copy_fi(0x7f923456));
+    cvtlf(copy_fi(0x7fdbcdef));
+    cvtlf(copy_fi(0x80000000));
+    cvtlf(copy_fi(0xabcdef12));
+    cvtlf(copy_fi(0xff800000));
+    cvtlf(copy_fi(0xff923456));
+    cvtlf(copy_fi(0xffdbcdef));
+
+    cvtld(copy_di(0x0000000000000000));
+    cvtld(copy_di(0x456789abcdef0123));
+    cvtld(copy_di(0x7ff0000000000000));
+    cvtld(copy_di(0x7ff123456789abcd));
+    cvtld(copy_di(0x7ffabcdef1234567));
+    cvtld(copy_di(0x8000000000000000));
+    cvtld(copy_di(0xcdef123456789abc));
+    cvtld(copy_di(0xfff0000000000000));
+    cvtld(copy_di(0xfff123456789abcd));
+    cvtld(copy_di(0xfffabcdef1234567));
+
+    for (i = 0; i < 2; i++) {                   \
+        cvtfl(make(i, 0, 0, 0));
+        cvtfl(make(i, 16232, -1, -1));
+        cvtfl(make(i, 16233, 0, 0));
+        cvtfl(make(i, 16233, 0, 1));
+        cvtfl(make(i, 16383, 0xab0ffd000000, 0));
+        cvtfl(make(i, 16383, 0xab0ffd000001, 0));
+        cvtfl(make(i, 16383, 0xab0ffeffffff, 0));
+        cvtfl(make(i, 16383, 0xab0fff000000, 0));
+        cvtfl(make(i, 16383, 0xab0fff000001, 0));
+        cvtfl(make(i, 16510, 0xfffffeffffff, -1));
+        cvtfl(make(i, 16510, 0xffffff000000, 0));
+        cvtfl(make(i, 16511, 0, 0));
+        cvtfl(make(i, 32767, 0, 0));
+        cvtfl(make(i, 32767, 0, 1));
+        cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+        cvtfl(make(i, 32767, 0x800000000000, 1));
+        cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+    }
+
+    for (i = 0; i < 2; i++) {
+        cvtdl(make(i, 0, 0, 0));
+        cvtdl(make(i, 15307, -1, -1));
+        cvtdl(make(i, 15308, 0, 0));
+        cvtdl(make(i, 15308, 0, 1));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001));
+        cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff));
+        cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000));
+        cvtdl(make(i, 17407, 0, 0));
+        cvtdl(make(i, 32767, 0, 0));
+        cvtdl(make(i, 32767, 0, 1));
+        cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+        cvtdl(make(i, 32767, 0x800000000000, 1));
+        cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+    }
+}
+
+void tests(void)
+{
+    cmps();
+    nanz();
+    adds();
+    muls();
+    divs();
+    cvts();
+}
+
+int main()
+{
+#ifdef __aarch64__
+    tests();
+#else
+    printf("This test program is intended for a little-endian architecture\n"
+           "with an IEEE-standard 128-bit long double.\n");
+#endif
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main() 
+{
+   int a;
+   a = 42;
+   printf("%d\n", a);
+
+   int b = 64;
+   printf("%d\n", b);
+
+   int c = 12, d = 34;
+   printf("%d, %d\n", c, d);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect	(revision 331)
@@ -0,0 +1,3 @@
+42
+64
+12, 34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main() 
+{
+   printf("Hello\n");
+   printf("Hello\n"); /* this is a comment */ printf("Hello\n");
+   printf("Hello\n");
+   // this is also a comment sayhello();
+   printf("Hello\n");
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect	(revision 331)
@@ -0,0 +1,5 @@
+Hello
+Hello
+Hello
+Hello
+Hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main() 
+{
+   printf("Hello world\n");
+
+   int Count;
+   for (Count = -5; Count <= 5; Count++)
+      printf("Count = %d\n", Count);
+
+   printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there");
+   printf("Character 'A' is '%c'\n", 65);
+   printf("Character 'a' is '%c'\n", 'a');
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect	(revision 331)
@@ -0,0 +1,15 @@
+Hello world
+Count = -5
+Count = -4
+Count = -3
+Count = -2
+Count = -1
+Count = 0
+Count = 1
+Count = 2
+Count = 3
+Count = 4
+Count = 5
+String 'hello', 'there' is 'hello', 'there'
+Character 'A' is 'A'
+Character 'a' is 'a'
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c	(revision 331)
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+struct fred
+{
+   int boris;
+   int natasha;
+};
+
+int main()
+{
+   struct fred bloggs;
+
+   bloggs.boris = 12;
+   bloggs.natasha = 34;
+
+   printf("%d\n", bloggs.boris);
+   printf("%d\n", bloggs.natasha);
+
+   struct fred jones[2];
+   jones[0].boris = 12;
+   jones[0].natasha = 34;
+   jones[1].boris = 56;
+   jones[1].natasha = 78;
+
+   printf("%d\n", jones[0].boris);
+   printf("%d\n", jones[0].natasha);
+   printf("%d\n", jones[1].boris);
+   printf("%d\n", jones[1].natasha);
+
+   return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect	(revision 331)
@@ -0,0 +1,6 @@
+12
+34
+12
+34
+56
+78
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main() 
+{
+   int Count;
+
+   for (Count = 1; Count <= 10; Count++)
+   {
+      printf("%d\n", Count);
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main() 
+{
+   int Count;
+   int Array[10];
+
+   for (Count = 1; Count <= 10; Count++)
+   {
+      Array[Count-1] = Count * Count;
+   }
+
+   for (Count = 0; Count < 10; Count++)
+   {
+      printf("%d\n", Array[Count]);
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c	(revision 331)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   for (Count = 0; Count < 4; Count++)
+   {
+      printf("%d\n", Count);
+      switch (Count)
+      {
+         case 1:
+            printf("%d\n", 1);
+            break;
+
+         case 2:
+            printf("%d\n", 2);
+            break;
+
+         default:
+            printf("%d\n", 0);
+            break;
+      }
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect	(revision 331)
@@ -0,0 +1,8 @@
+0
+0
+1
+1
+2
+2
+3
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int myfunc(int x)
+{
+   return x * x;
+}
+
+void vfunc(int a)
+{
+   printf("a=%d\n", a);
+}
+
+void qfunc()
+{
+   printf("qfunc()\n");
+}
+
+int main()
+{
+   printf("%d\n", myfunc(3));
+   printf("%d\n", myfunc(4));
+
+   vfunc(1234);
+
+   qfunc();
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect	(revision 331)
@@ -0,0 +1,4 @@
+9
+16
+a=1234
+qfunc()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int p;
+   int t;
+
+   a = 1;
+   p = 0;
+   t = 0;
+
+   while (a < 100)
+   {
+      printf("%d\n", a);
+      t = a;
+      a = t + p;
+      p = t;
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect	(revision 331)
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int p;
+   int t;
+
+   a = 1;
+   p = 0;
+   t = 0;
+
+   do
+   {
+      printf("%d\n", a);
+      t = a;
+      a = t + p;
+      p = t;
+   } while (a < 100);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect	(revision 331)
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c	(revision 331)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+struct ziggy
+{
+   int a;
+   int b;
+   int c;
+} bolshevic;
+
+int main()
+{
+   int a;
+   int *b;
+   int c;
+
+   a = 42;
+   b = &a;
+   printf("a = %d\n", *b);
+
+   bolshevic.a = 12;
+   bolshevic.b = 34;
+   bolshevic.c = 56;
+
+   printf("bolshevic.a = %d\n", bolshevic.a);
+   printf("bolshevic.b = %d\n", bolshevic.b);
+   printf("bolshevic.c = %d\n", bolshevic.c);
+
+   struct ziggy *tsar = &bolshevic;
+
+   printf("tsar->a = %d\n", tsar->a);
+   printf("tsar->b = %d\n", tsar->b);
+   printf("tsar->c = %d\n", tsar->c);
+
+   b = &(bolshevic.b);
+   printf("bolshevic.b = %d\n", *b);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect	(revision 331)
@@ -0,0 +1,8 @@
+a = 42
+bolshevic.a = 12
+bolshevic.b = 34
+bolshevic.c = 56
+tsar->a = 12
+tsar->b = 34
+tsar->c = 56
+bolshevic.b = 34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c	(revision 331)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int b;
+   int c;
+   int d;
+   int e;
+   int f;
+   int x;
+   int y;
+
+   a = 12;
+   b = 34;
+   c = 56;
+   d = 78;
+   e = 0;
+   f = 1;
+
+   printf("%d\n", c + d);
+   printf("%d\n", (y = c + d));
+   printf("%d\n", e || e && f);
+   printf("%d\n", e || f && f);
+   printf("%d\n", e && e || f);
+   printf("%d\n", e && f || f);
+   printf("%d\n", a && f | f);
+   printf("%d\n", a | b ^ c & d);
+   printf("%d, %d\n", a == a, a == b);
+   printf("%d, %d\n", a != a, a != b);
+   printf("%d\n", a != b && c != d);
+   printf("%d\n", a + b * c / f);
+   printf("%d\n", a + b * c / f);
+   printf("%d\n", (4 << 4));
+   printf("%d\n", (64 >> 4));
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect	(revision 331)
@@ -0,0 +1,15 @@
+134
+134
+0
+1
+1
+1
+1
+46
+1, 0
+0, 1
+1
+1916
+1916
+64
+4
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define FRED 12
+#define BLOGGS(x) (12*(x))
+
+int main()
+{
+   printf("%d\n", FRED);
+   printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3));
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect	(revision 331)
@@ -0,0 +1,2 @@
+12
+12, 24, 36
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c	(revision 331)
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int main()
+{
+   int a = 24680;
+   int b = 01234567;
+   int c = 0x2468ac;
+   int d = 0x2468AC;
+   int e = 0b010101010101;
+
+   printf("%d\n", a);
+   printf("%d\n", b);
+   printf("%d\n", c);
+   printf("%d\n", d);
+   printf("%d\n", e);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect	(revision 331)
@@ -0,0 +1,5 @@
+24680
+342391
+2386092
+2386092
+1365
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int a = 1;
+
+   if (a)
+      printf("a is true\n");
+   else
+      printf("a is false\n");
+
+   int b = 0;
+   if (b)
+      printf("b is true\n");
+   else
+      printf("b is false\n");
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect	(revision 331)
@@ -0,0 +1,2 @@
+a is true
+b is false
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int factorial(int i) 
+{
+   if (i < 2)
+      return i;
+   else
+      return i * factorial(i - 1);
+}
+
+int main()
+{
+   int Count;
+
+   for (Count = 1; Count <= 10; Count++)
+      printf("%d\n", factorial(Count));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+6
+24
+120
+720
+5040
+40320
+362880
+3628800
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int x, y, z;
+
+   for (x = 0; x < 2; x++)
+   {
+      for (y = 0; y < 3; y++)
+      {
+         for (z = 0; z < 3; z++)
+         {
+            printf("%d %d %d\n", x, y, z);
+         }
+      }
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect	(revision 331)
@@ -0,0 +1,18 @@
+0 0 0
+0 0 1
+0 0 2
+0 1 0
+0 1 1
+0 1 2
+0 2 0
+0 2 1
+0 2 2
+1 0 0
+1 0 1
+1 0 2
+1 1 0
+1 1 1
+1 1 2
+1 2 0
+1 2 1
+1 2 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c	(revision 331)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+enum fred
+{
+   a,
+   b,
+   c,
+   d,
+   e = 54,
+   f = 73,
+   g,
+   h
+};
+
+/* All following uses of enum efoo should compile
+   without warning.  While forward enums aren't ISO C,
+   it's accepted by GCC also in strict mode, and only warned
+   about with -pedantic.  This happens in the real world.  */
+/* Strict ISO C doesn't allow this kind of forward declaration of
+   enums, but GCC accepts it (and gives only pedantic warning), and
+   it occurs in the wild.  */
+enum efoo;
+struct Sforward_use {
+    int (*fmember) (enum efoo x);
+};
+
+extern enum efoo it_real_fn(void);
+enum efoo {
+  ONE,
+  TWO,
+};
+struct S2 {
+  enum efoo (*f2) (void);
+};
+void should_compile(struct S2 *s)
+{
+  s->f2 = it_real_fn;
+}
+
+enum efoo it_real_fn(void)
+{
+  return TWO;
+}
+
+static unsigned int deref_uintptr(unsigned int *p)
+{
+  return *p;
+}
+
+enum Epositive {
+    epos_one, epos_two
+};
+
+int main()
+{
+   enum fred frod;
+   enum Epositive epos = epos_two;
+
+   printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
+   /* printf("%d\n", frod); */
+   frod = 12;
+   printf("%d\n", frod);
+   frod = e;
+   printf("%d\n", frod);
+
+   /* Following should compile without warning.  */
+   printf ("enum to int: %u\n", deref_uintptr(&epos));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect	(revision 331)
@@ -0,0 +1,4 @@
+0 1 2 3 54 73 74 75
+12
+54
+enum to int: 1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c	(revision 331)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("including\n");
+#include "18_include.h"
+   printf("done\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect	(revision 331)
@@ -0,0 +1,3 @@
+including
+included
+done
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h	(revision 331)
@@ -0,0 +1,1 @@
+printf("included\n");
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c	(revision 331)
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int *b;
+   int *c;
+
+   a = 42;
+   b = &a;
+   c = NULL;
+
+   printf("%d\n", *b);
+
+   if (b == NULL)
+      printf("b is NULL\n");
+   else
+      printf("b is not NULL\n");
+
+   if (c == NULL)
+      printf("c is NULL\n");
+   else
+      printf("c is not NULL\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect	(revision 331)
@@ -0,0 +1,3 @@
+42
+b is not NULL
+c is NULL
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int b;
+   int *d;
+   int *e;
+   d = &a;
+   e = &b;
+   a = 12;
+   b = 34;
+   printf("%d\n", *d);
+   printf("%d\n", *e);
+   printf("%d\n", d == e);
+   printf("%d\n", d != e);
+   d = e;
+   printf("%d\n", d == e);
+   printf("%d\n", d != e);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect	(revision 331)
@@ -0,0 +1,6 @@
+12
+34
+0
+1
+1
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c	(revision 331)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main()
+{
+   int x = 'a';
+   char y = x;
+
+   char *a = "hello";
+
+   printf("%s\n", a);
+
+   int c;
+   c = *a;
+
+   char *b;
+   for (b = a; *b != 0; b++)
+      printf("%c: %d\n", *b, *b);
+
+   char destarray[10];
+   char *dest = &destarray[0];
+   char *src = a;
+
+   while (*src != 0)
+      *dest++ = *src++;
+
+   *dest = 0;
+
+   printf("copied string is %s\n", destarray);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect	(revision 331)
@@ -0,0 +1,7 @@
+hello
+h: 104
+e: 101
+l: 108
+l: 108
+o: 111
+copied string is hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c	(revision 331)
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+   // variables
+   float a = 12.34 + 56.78;
+   printf("%f\n", a);
+
+   // infix operators
+   printf("%f\n", 12.34 + 56.78);
+   printf("%f\n", 12.34 - 56.78);
+   printf("%f\n", 12.34 * 56.78);
+   printf("%f\n", 12.34 / 56.78);
+
+   // comparison operators
+   printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78);
+   printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34);
+   printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34);
+
+   // assignment operators
+   a = 12.34;
+   a += 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a -= 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a *= 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a /= 56.78;
+   printf("%f\n", a);
+
+   // prefix operators
+   printf("%f\n", +12.34);
+   printf("%f\n", -12.34);
+
+   // type coercion
+   a = 2;
+   printf("%f\n", a);
+   printf("%f\n", sin(2));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect	(revision 331)
@@ -0,0 +1,16 @@
+69.120003
+69.120000
+-44.440000
+700.665200
+0.217330
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+69.120003
+-44.439999
+700.665222
+0.217330
+12.340000
+-12.340000
+2.000000
+0.909297
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c	(revision 331)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+void charfunc(char a)
+{
+   printf("char: %c\n", a);
+}
+
+void intfunc(int a)
+{
+   printf("int: %d\n", a);
+}
+
+void floatfunc(float a)
+{
+   printf("float: %f\n", a);
+}
+
+int main()
+{
+   charfunc('a');
+   charfunc(98);
+   charfunc(99.0);
+
+   intfunc('a');
+   intfunc(98);
+   intfunc(99.0);
+
+   floatfunc('a');
+   floatfunc(98);
+   floatfunc(99.0);
+
+   /* printf("%c %d %f\n", 'a', 'b', 'c'); */
+   /* printf("%c %d %f\n", 97, 98, 99); */
+   /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */
+
+   char b = 97;
+   char c = 97.0;
+
+   printf("%d %d\n", b, c);
+
+   int d = 'a';
+   int e = 97.0;
+
+   printf("%d %d\n", d, e);
+
+   float f = 'a';
+   float g = 97;
+
+   printf("%f %f\n", f, g);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect	(revision 331)
@@ -0,0 +1,12 @@
+char: a
+char: b
+char: c
+int: 97
+int: 98
+int: 99
+float: 97.000000
+float: 98.000000
+float: 99.000000
+97 97
+97 97
+97.000000 97.000000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c	(revision 331)
@@ -0,0 +1,30 @@
+#define _ISOC99_SOURCE 1
+
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+   printf("%f\n", sin(0.12));
+   printf("%f\n", cos(0.12));
+   printf("%f\n", tan(0.12));
+   printf("%f\n", asin(0.12));
+   printf("%f\n", acos(0.12));
+   printf("%f\n", atan(0.12));
+   printf("%f\n", sinh(0.12));
+   printf("%f\n", cosh(0.12));
+   printf("%f\n", tanh(0.12));
+   printf("%f\n", exp(0.12));
+   printf("%f\n", fabs(-0.12));
+   printf("%f\n", log(0.12));
+   printf("%f\n", log10(0.12));
+   printf("%f\n", pow(0.12, 0.12));
+   printf("%f\n", sqrt(0.12));
+   printf("%f\n", round(12.34));
+   printf("%f\n", ceil(12.34));
+   printf("%f\n", floor(12.34));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect	(revision 331)
@@ -0,0 +1,18 @@
+0.119712
+0.992809
+0.120579
+0.120290
+1.450506
+0.119429
+0.120288
+1.007209
+0.119427
+1.127497
+0.120000
+-2.120264
+-0.920819
+0.775357
+0.346410
+12.000000
+13.000000
+12.000000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c	(revision 331)
@@ -0,0 +1,83 @@
+#include <stdio.h>
+
+int array[16];
+
+//Swap integer values by array indexes
+void swap(int a, int b)
+{
+   int tmp  = array[a];
+   array[a] = array[b];
+   array[b] = tmp;
+}
+
+//Partition the array into two halves and return the
+//index about which the array is partitioned
+int partition(int left, int right)
+{
+   int pivotIndex = left;
+   int pivotValue = array[pivotIndex];
+   int index = left;
+   int i;
+
+   swap(pivotIndex, right);
+   for(i = left; i < right; i++)
+   {
+      if(array[i] < pivotValue)
+      {
+         swap(i, index);
+         index += 1;
+      }
+   }
+   swap(right, index);
+
+   return index;
+}
+
+//Quicksort the array
+void quicksort(int left, int right)
+{
+   if(left >= right)
+      return;
+
+   int index = partition(left, right);
+   quicksort(left, index - 1);
+   quicksort(index + 1, right);
+}
+
+int main()
+{
+   int i;
+
+   array[0] = 62;
+   array[1] = 83;
+   array[2] = 4;
+   array[3] = 89;
+   array[4] = 36;
+   array[5] = 21;
+   array[6] = 74;
+   array[7] = 37;
+   array[8] = 65;
+   array[9] = 33;
+   array[10] = 96;
+   array[11] = 38;
+   array[12] = 53;
+   array[13] = 16;
+   array[14] = 74;
+   array[15] = 55;
+
+   for (i = 0; i < 16; i++)
+      printf("%d ", array[i]);
+
+   printf("\n");
+
+   quicksort(0, 15);
+
+   for (i = 0; i < 16; i++)
+      printf("%d ", array[i]);
+
+   printf("\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect	(revision 331)
@@ -0,0 +1,2 @@
+62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55 
+4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("%d\n", '\1');
+   printf("%d\n", '\10');
+   printf("%d\n", '\100');
+   printf("%d\n", '\x01');
+   printf("%d\n", '\x0e');
+   printf("%d\n", '\x10');
+   printf("%d\n", '\x40');
+   printf("test \x40\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect	(revision 331)
@@ -0,0 +1,8 @@
+1
+8
+64
+1
+14
+16
+64
+test @
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+   char a;
+   int b;
+   double c;
+
+   printf("%d\n", sizeof(a));
+   printf("%d\n", sizeof(b));
+   printf("%d\n", sizeof(c));
+
+   printf("%d\n", sizeof(!a));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect	(revision 331)
@@ -0,0 +1,4 @@
+1
+4
+8
+4
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c	(revision 331)
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+   char a[10];
+
+   strcpy(a, "hello");
+   printf("%s\n", a);
+
+   strncpy(a, "gosh", 2);
+   printf("%s\n", a);
+
+   printf("%d\n", strcmp(a, "apple") > 0);
+   printf("%d\n", strcmp(a, "goere") > 0);
+   printf("%d\n", strcmp(a, "zebra") < 0);
+
+   printf("%d\n", strlen(a));
+
+   strcat(a, "!");
+   printf("%s\n", a);
+
+   printf("%d\n", strncmp(a, "apple", 2) > 0);
+   printf("%d\n", strncmp(a, "goere", 2) == 0);
+   printf("%d\n", strncmp(a, "goerg", 2) == 0);
+   printf("%d\n", strncmp(a, "zebra", 2) < 0);
+
+   printf("%s\n", strchr(a, 'o'));
+   printf("%s\n", strrchr(a, 'l'));
+   printf("%d\n", strrchr(a, 'x') == NULL);
+
+   memset(&a[1], 'r', 4);
+   printf("%s\n", a);
+
+   memcpy(&a[2], a, 2);
+   printf("%s\n", a);
+
+   printf("%d\n", memcmp(a, "apple", 4) > 0);
+   printf("%d\n", memcmp(a, "grgr", 4) == 0);
+   printf("%d\n", memcmp(a, "zebra", 4) < 0);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect	(revision 331)
@@ -0,0 +1,19 @@
+hello
+gollo
+1
+1
+1
+5
+gollo!
+1
+1
+1
+1
+ollo!
+lo!
+1
+grrrr!
+grgrr!
+1
+1
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c	(revision 331)
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+   char a[10];
+   strcpy(a, "abcdef");
+   printf("%s\n", &a[1]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect	(revision 331)
@@ -0,0 +1,1 @@
+bcdef
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c	(revision 331)
@@ -0,0 +1,122 @@
+/* example from http://barnyard.syr.edu/quickies/hanoi.c */
+
+/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */
+/* By Terry R. McConnell (12/2/97) */
+/* Compile: cc -o hanoi hanoi.c */
+
+/* This program does no error checking. But then, if it's right, 
+   it's right ... right ? */
+
+
+/* The original towers of hanoi problem seems to have been originally posed
+   by one M. Claus in 1883. There is a popular legend that goes along with
+   it that has been often repeated and paraphrased. It goes something like this:
+   In the great temple at Benares there are 3 golden spikes. On one of them,
+   God placed 64 disks increasing in size from bottom to top, at the beginning
+   of time. Since then, and to this day, the priest on duty constantly transfers
+   disks, one at a time, in such a way that no larger disk is ever put on top
+   of a smaller one. When the disks have been transferred entirely to another
+   spike the Universe will come to an end in a large thunderclap.
+
+   This paraphrases the original legend due to DeParville, La Nature, Paris 1884,
+   Part I, 285-286. For this and further information see: Mathematical 
+   Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967,
+   303-305.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TRUE 1
+#define FALSE 0
+
+/* This is the number of "disks" on tower A initially. Taken to be 64 in the
+ * legend. The number of moves required, in general, is 2^N - 1. For N = 64,
+ * this is 18,446,744,073,709,551,615 */
+#define N 4
+
+/* These are the three towers. For example if the state of A is 0,1,3,4, that
+ * means that there are three discs on A of sizes 1, 3, and 4. (Think of right
+ * as being the "down" direction.) */
+int A[N], B[N], C[N]; 
+
+void Hanoi(int,int*,int*,int*);
+
+/* Print the current configuration of A, B, and C to the screen */
+void PrintAll()
+{
+   int i;
+
+   printf("A: ");
+   for(i=0;i<N;i++)printf(" %d ",A[i]);
+   printf("\n");
+
+   printf("B: ");
+   for(i=0;i<N;i++)printf(" %d ",B[i]);
+   printf("\n");
+
+   printf("C: ");
+   for(i=0;i<N;i++)printf(" %d ",C[i]);
+   printf("\n");
+   printf("------------------------------------------\n");
+   return;
+}
+
+/* Move the leftmost nonzero element of source to dest, leave behind 0. */
+/* Returns the value moved (not used.) */
+int Move(int *source, int *dest)
+{
+   int i = 0, j = 0;
+
+   while (i<N && (source[i])==0) i++;
+   while (j<N && (dest[j])==0) j++;
+
+   dest[j-1] = source[i];
+   source[i] = 0;
+   PrintAll();       /* Print configuration after each move. */
+   return dest[j-1];
+}
+
+
+/* Moves first n nonzero numbers from source to dest using the rules of Hanoi.
+   Calls itself recursively.
+   */
+void Hanoi(int n,int *source, int *dest, int *spare)
+{
+   int i;
+   if(n==1){
+      Move(source,dest);
+      return;
+   }
+
+   Hanoi(n-1,source,spare,dest);
+   Move(source,dest);
+   Hanoi(n-1,spare,dest,source);	
+   return;
+}
+
+int main()
+{
+   int i;
+
+   /* initialize the towers */
+   for(i=0;i<N;i++)A[i]=i+1;
+   for(i=0;i<N;i++)B[i]=0;
+   for(i=0;i<N;i++)C[i]=0;
+
+   printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N);
+
+   /* Print the starting state */
+   printf("Starting state:\n");
+   PrintAll();
+   printf("\n\nSubsequent states:\n\n");
+
+   /* Do it! Use A = Source, B = Destination, C = Spare */
+   Hanoi(N,A,B,C);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect	(revision 331)
@@ -0,0 +1,71 @@
+Solution of Tower of Hanoi Problem with 4 Disks
+
+Starting state:
+A:  1  2  3  4 
+B:  0  0  0  0 
+C:  0  0  0  0 
+------------------------------------------
+
+
+Subsequent states:
+
+A:  0  2  3  4 
+B:  0  0  0  0 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  3  4 
+B:  0  0  0  2 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  3  4 
+B:  0  0  1  2 
+C:  0  0  0  0 
+------------------------------------------
+A:  0  0  0  4 
+B:  0  0  1  2 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  4 
+B:  0  0  0  2 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  4 
+B:  0  0  0  0 
+C:  0  0  2  3 
+------------------------------------------
+A:  0  0  0  4 
+B:  0  0  0  0 
+C:  0  1  2  3 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  0  0  4 
+C:  0  1  2  3 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  0  1  4 
+C:  0  0  2  3 
+------------------------------------------
+A:  0  0  0  2 
+B:  0  0  1  4 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  2 
+B:  0  0  0  4 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  2 
+B:  0  0  3  4 
+C:  0  0  0  0 
+------------------------------------------
+A:  0  0  0  2 
+B:  0  0  3  4 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  2  3  4 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  0  0 
+B:  1  2  3  4 
+C:  0  0  0  0 
+------------------------------------------
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+   int Count;
+
+   printf("hello world %d\n", argc);
+   for (Count = 1; Count < argc; Count++)
+      printf("arg %d: %s\n", Count, argv[Count]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect	(revision 331)
@@ -0,0 +1,6 @@
+hello world 6
+arg 1: arg1
+arg 2: arg2
+arg 3: arg3
+arg 4: arg4
+arg 5: arg5
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c	(revision 331)
@@ -0,0 +1,266 @@
+/* example from http://barnyard.syr.edu/quickies/led.c */
+
+/* led.c: print out number as if on 7 line led display. I.e., write integer
+   given on command line like this:  
+      _   _       _  
+   |  _|  _| |_| |_  
+   | |_   _|   |  _| etc.
+
+   We assume the terminal behaves like a classical teletype. So the top
+   lines of all digits have to be printed first, then the middle lines of
+   all digits, etc.
+
+   By Terry R. McConnell
+
+compile: cc -o led led.c
+
+If you just want to link in the subroutine print_led that does all the
+work, compile with -DNO_MAIN, and declare the following in any source file
+that uses the call:
+
+extern void print_led(unsigned long x, char *buf);
+
+Bug: you cannot call repeatedly to print more than one number to a line.
+That would require curses or some other terminal API that allows moving the
+cursor to a previous line.
+
+*/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MAX_DIGITS 32
+#define NO_MAIN
+
+
+/* Print the top line of the digit d into buffer. 
+   Does not null terminate buffer. */
+
+void topline(int d, char *p){
+
+   *p++ = ' ';
+   switch(d){
+
+      /* all these have _ on top line */
+
+      case 0:
+      case 2:
+      case 3:
+      case 5:
+      case 7:
+      case 8:
+      case 9:
+         *p++ = '_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   *p++=' ';
+}
+
+/* Print the middle line of the digit d into the buffer. 
+   Does not null terminate. */
+
+void midline(int d, char *p){
+
+   switch(d){
+
+      /* those that have leading | on middle line */
+
+      case 0:
+      case 4:
+      case 5:
+      case 6:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';	
+   }
+   switch(d){
+
+      /* those that have _ on middle line */
+
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 8:
+      case 9:
+         *p++='_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   switch(d){
+
+      /* those that have closing | on middle line */
+
+      case 0:
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 7:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';
+
+   }
+}
+
+/* Print the bottom line of the digit d. Does not null terminate. */
+
+void botline(int d, char *p){
+
+
+   switch(d){
+
+      /* those that have leading | on bottom line */
+
+      case 0:
+      case 2:
+      case 6:
+      case 8:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';	
+   }
+   switch(d){
+
+      /* those that have _ on bottom line */
+
+      case 0:
+      case 2:
+      case 3:
+      case 5:
+      case 6:
+      case 8:
+         *p++='_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   switch(d){
+
+      /* those that have closing | on bottom line */
+
+      case 0:
+      case 1:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';
+
+   }
+}
+
+/* Write the led representation of integer to string buffer. */
+
+void print_led(unsigned long x, char *buf)
+{
+
+   int i=0,n;
+   static int d[MAX_DIGITS];
+
+
+   /* extract digits from x */
+
+   n = ( x == 0L ? 1 : 0 );  /* 0 is a digit, hence a special case */
+
+   while(x){
+      d[n++] = (int)(x%10L);
+      if(n >= MAX_DIGITS)break;
+      x = x/10L;
+   }
+
+   /* print top lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      topline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n'; /* move teletype to next line */
+
+   /* print middle lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      midline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n';
+
+   /* print bottom lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      botline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n';
+   *buf='\0';
+}
+
+int main()
+{
+   char buf[5*MAX_DIGITS];
+   print_led(1234567, buf);
+   printf("%s\n",buf);
+
+   return 0;
+}
+
+#ifndef NO_MAIN
+int main(int argc, char **argv)
+{
+
+   int i=0,n;
+   long x;
+   static int d[MAX_DIGITS];
+   char buf[5*MAX_DIGITS];
+
+   if(argc != 2){
+      fprintf(stderr,"led: usage: led integer\n");
+      return 1;
+   }
+
+   /* fetch argument from command line */
+
+   x = atol(argv[1]);
+
+   /* sanity check */
+
+   if(x<0){
+      fprintf(stderr,"led: %d must be non-negative\n",x);
+      return 1;
+   }
+
+   print_led(x,buf);
+   printf("%s\n",buf);
+
+   return 0;
+
+}
+#endif
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect	(revision 331)
@@ -0,0 +1,4 @@
+     _   _       _       _  
+  |  _|  _| |_| |_  |_    | 
+  | |_   _|   |  _| |_|   | 
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   for (Count = 0; Count < 10; Count++)
+   {
+      printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3));
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect	(revision 331)
@@ -0,0 +1,10 @@
+0
+1
+4
+9
+16
+15
+18
+21
+24
+27
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c	(revision 331)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int main()
+{
+   int a[4];
+
+   a[0] = 12;
+   a[1] = 23;
+   a[2] = 34;
+   a[3] = 45;
+
+   printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
+
+   int b[4];
+
+   b = a;
+
+   printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect	(revision 331)
@@ -0,0 +1,2 @@
+12 23 34 45
+12 23 34 45
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main()
+{
+   char a;
+   short b;
+
+   printf("%d %d\n", sizeof(char), sizeof(a));
+   printf("%d %d\n", sizeof(short), sizeof(b));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect	(revision 331)
@@ -0,0 +1,2 @@
+1 1
+2 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 };
+
+   for (Count = 0; Count < 10; Count++)
+      printf("%d: %d\n", Count, Array[Count]);
+
+   int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, };
+
+   for (Count = 0; Count < 10; Count++)
+      printf("%d: %d\n", Count, Array2[Count]);
+
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect	(revision 331)
@@ -0,0 +1,20 @@
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   char Buf[100];
+   int Count;
+
+   for (Count = 1; Count <= 20; Count++)
+   {
+      sprintf(Buf, "->%02d<-\n", Count);
+      printf("%s", Buf);
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect	(revision 331)
@@ -0,0 +1,20 @@
+->01<-
+->02<-
+->03<-
+->04<-
+->05<-
+->06<-
+->07<-
+->08<-
+->09<-
+->10<-
+->11<-
+->12<-
+->13<-
+->14<-
+->15<-
+->16<-
+->17<-
+->18<-
+->19<-
+->20<-
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c	(revision 331)
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main()
+{
+   int a[4][4];
+   int b = 0;
+   int x;
+   int y;
+
+   for (x = 0; x < 4; x++)
+   {
+      for (y = 0; y < 4; y++)
+      {
+         b++;
+         a[x][y] = b;
+      }
+   }
+
+   for (x = 0; x < 4; x++)
+   {
+      printf("x=%d: ", x);
+      for (y = 0; y < 4; y++)
+      {
+         printf("%d ", a[x][y]);
+      }
+      printf("\n");
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect	(revision 331)
@@ -0,0 +1,4 @@
+x=0: 1 2 3 4
+x=1: 5 6 7 8
+x=2: 9 10 11 12
+x=3: 13 14 15 16 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c	(revision 331)
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+typedef int MyInt;
+
+struct FunStruct
+{
+   int i;
+   int j;
+};
+
+typedef struct FunStruct MyFunStruct;
+
+typedef MyFunStruct *MoreFunThanEver;
+
+int main()
+{
+   MyInt a = 1;
+   printf("%d\n", a);
+
+   MyFunStruct b;
+   b.i = 12;
+   b.j = 34;
+   printf("%d,%d\n", b.i, b.j);
+
+   MoreFunThanEver c = &b;
+   printf("%d,%d\n", c->i, c->j);
+
+   return 0;
+}
+
+/* "If the specification of an array type includes any type qualifiers,
+   the element type is so-qualified, not the array type." */
+
+typedef int A[3];
+extern A const ca;
+extern const A ca;
+extern const int ca[3];
+
+typedef A B[1][2];
+extern B const cb;
+extern const B cb;
+extern const int cb[1][2][3];
+
+extern B b;
+extern int b[1][2][3];
+
+/* Funny but valid function declaration.  */
+typedef int functype (int);
+extern functype func;
+int func(int i)
+{
+   return i + 1;
+}
+
+/* Even funnier function decl and definition using typeof.  */
+int set_anon_super(void);
+int set_anon_super(void)
+{
+   return 42;
+}
+typedef int sas_type (void);
+extern typeof(set_anon_super) set_anon_super;
+extern sas_type set_anon_super;
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect	(revision 331)
@@ -0,0 +1,3 @@
+1
+12,34
+12,34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c	(revision 331)
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+int main()
+{
+   FILE *f = fopen("fred.txt", "w");
+   fwrite("hello\nhello\n", 1, 12, f);
+   fclose(f);
+
+   char freddy[7];
+   f = fopen("fred.txt", "r");
+   if (fread(freddy, 1, 6, f) != 6)
+      printf("couldn't read fred.txt\n");
+
+   freddy[6] = '\0';
+   fclose(f);
+
+   printf("%s", freddy);
+
+   int InChar;
+   char ShowChar;
+   f = fopen("fred.txt", "r");
+   while ( (InChar = fgetc(f)) != EOF)
+   {
+      ShowChar = InChar;
+      if (ShowChar < ' ')
+         ShowChar = '.';
+
+      printf("ch: %d '%c'\n", InChar, ShowChar);
+   }
+   fclose(f);
+
+   f = fopen("fred.txt", "r");
+   while ( (InChar = getc(f)) != EOF)
+   {
+      ShowChar = InChar;
+      if (ShowChar < ' ')
+         ShowChar = '.';
+
+      printf("ch: %d '%c'\n", InChar, ShowChar);
+   }
+   fclose(f);
+
+   f = fopen("fred.txt", "r");
+   while (fgets(freddy, sizeof(freddy), f) != NULL)
+      printf("x: %s", freddy);
+
+   fclose(f);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect	(revision 331)
@@ -0,0 +1,27 @@
+hello
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+x: hello
+x: hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c	(revision 331)
@@ -0,0 +1,85 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("#include test\n");
+
+#if 1
+#if 0
+   printf("a\n");
+#else
+   printf("b\n");
+#endif
+#else
+#if 0
+   printf("c\n");
+#else
+   printf("d\n");
+#endif
+#endif
+
+#if 0
+#if 1
+   printf("e\n");
+#else
+   printf("f\n");
+#endif
+#else
+#if 1
+   printf("g\n");
+#else
+   printf("h\n");
+#endif
+#endif
+
+#define DEF
+
+#ifdef DEF
+#ifdef DEF
+   printf("i\n");
+#else
+   printf("j\n");
+#endif
+#else
+#ifdef DEF
+   printf("k\n");
+#else
+   printf("l\n");
+#endif
+#endif
+
+#ifndef DEF
+#ifndef DEF
+   printf("m\n");
+#else
+   printf("n\n");
+#endif
+#else
+#ifndef DEF
+   printf("o\n");
+#else
+   printf("p\n");
+#endif
+#endif
+
+#define ONE 1
+#define ZERO 0
+
+#if ONE
+#if ZERO
+   printf("q\n");
+#else
+   printf("r\n");
+#endif
+#else
+#if ZERO
+   printf("s\n");
+#else
+   printf("t\n");
+#endif
+#endif
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect	(revision 331)
@@ -0,0 +1,6 @@
+#include test
+b
+g
+i
+p
+r
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c	(revision 331)
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int fred(int p)
+{
+   printf("yo %d\n", p);
+   return 42;
+}
+
+int (*f)(int) = &fred;
+
+/* To test what this is supposed to test the destination function
+   (fprint here) must not be called directly anywhere in the test.  */
+int (*fprintfptr)(FILE *, const char *, ...) = &fprintf;
+
+int main()
+{
+   fprintfptr(stdout, "%d\n", (*f)(24));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect	(revision 331)
@@ -0,0 +1,2 @@
+yo 24
+42
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+void fred(void)
+{
+   printf("yo\n");
+}
+
+int main()
+{
+   fred();
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect	(revision 331)
@@ -0,0 +1,1 @@
+yo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+
+   for (a = 0; a < 2; a++)
+   {
+      int b = a;
+   }
+
+   printf("it's all good\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect	(revision 331)
@@ -0,0 +1,1 @@
+it's all good
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count = 0;
+
+   for (;;)
+   {
+      Count++;
+      printf("%d\n", Count);
+      if (Count >= 10)
+         break;
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c	(revision 331)
@@ -0,0 +1,568 @@
+/*
+ * The  information  in  this  document  is  subject  to  change
+ * without  notice  and  should not be construed as a commitment
+ * by Digital Equipment Corporation or by DECUS.
+ *
+ * Neither Digital Equipment Corporation, DECUS, nor the authors
+ * assume any responsibility for the use or reliability of  this
+ * document or the described software.
+ *
+ *      Copyright (C) 1980, DECUS
+ *
+ * General permission to copy or modify, but not for profit,  is
+ * hereby  granted,  provided that the above copyright notice is
+ * included and reference made to  the  fact  that  reproduction
+ * privileges were granted by DECUS.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>	// tolower()
+
+/*
+ * grep
+ *
+ * Runs on the Decus compiler or on vms, On vms, define as:
+ *      grep :== "$disk:[account]grep"      (native)
+ *      grep :== "$disk:[account]grep grep" (Decus)
+ * See below for more information.
+ */
+
+char    *documentation[] = {
+   "grep searches a file for a given pattern.  Execute by",
+   "   grep [flags] regular_expression file_list\n",
+   "Flags are single characters preceded by '-':",
+   "   -c      Only a count of matching lines is printed",
+   "   -f      Print file name for matching lines switch, see below",
+   "   -n      Each line is preceded by its line number",
+   "   -v      Only print non-matching lines\n",
+   "The file_list is a list of files (wildcards are acceptable on RSX modes).",
+   "\nThe file name is normally printed if there is a file given.",
+   "The -f flag reverses this action (print name no file, not if more).\n",
+   0 };
+
+char    *patdoc[] = {
+   "The regular_expression defines the pattern to search for.  Upper- and",
+   "lower-case are always ignored.  Blank lines never match.  The expression",
+   "should be quoted to prevent file-name translation.",
+   "x      An ordinary character (not mentioned below) matches that character.",
+   "'\\'    The backslash quotes any character.  \"\\$\" matches a dollar-sign.",
+   "'^'    A circumflex at the beginning of an expression matches the",
+   "       beginning of a line.",
+   "'$'    A dollar-sign at the end of an expression matches the end of a line.",
+   "'.'    A period matches any character except \"new-line\".",
+   "':a'   A colon matches a class of characters described by the following",
+   "':d'     character.  \":a\" matches any alphabetic, \":d\" matches digits,",
+   "':n'     \":n\" matches alphanumerics, \": \" matches spaces, tabs, and",
+   "': '     other control characters, such as new-line.",
+   "'*'    An expression followed by an asterisk matches zero or more",
+   "       occurrences of that expression: \"fo*\" matches \"f\", \"fo\"",
+   "       \"foo\", etc.",
+   "'+'    An expression followed by a plus sign matches one or more",
+   "       occurrences of that expression: \"fo+\" matches \"fo\", etc.",
+   "'-'    An expression followed by a minus sign optionally matches",
+   "       the expression.",
+   "'[]'   A string enclosed in square brackets matches any character in",
+   "       that string, but no others.  If the first character in the",
+   "       string is a circumflex, the expression matches any character",
+   "       except \"new-line\" and the characters in the string.  For",
+   "       example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"",
+   "       matches \"abc\" but not \"axb\".  A range of characters may be",
+   "       specified by two characters separated by \"-\".  Note that,",
+   "       [a-z] matches alphabetics, while [z-a] never matches.",
+   "The concatenation of regular expressions is a regular expression.",
+   0};
+
+#define LMAX    512
+#define PMAX    256
+
+#define CHAR    1
+#define BOL     2
+#define EOL     3
+#define ANY     4
+#define CLASS   5
+#define NCLASS  6
+#define STAR    7
+#define PLUS    8
+#define MINUS   9
+#define ALPHA   10
+#define DIGIT   11
+#define NALPHA  12
+#define PUNCT   13
+#define RANGE   14
+#define ENDPAT  15
+
+int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0;
+
+char *pp, lbuf[LMAX], pbuf[PMAX];
+
+char *cclass();
+char *pmatch();
+void store(int);
+void error(char *);
+void badpat(char *, char *, char *);
+int match(void);
+
+
+/*** Display a file name *******************************/
+void file(char *s)
+{
+   printf("File %s:\n", s);
+}
+
+/*** Report unopenable file ****************************/
+void cant(char *s)
+{
+   fprintf(stderr, "%s: cannot open\n", s);
+}
+
+/*** Give good help ************************************/
+void help(char **hp)
+{
+   char   **dp;
+
+   for (dp = hp; *dp; ++dp)
+      printf("%s\n", *dp);
+}
+
+/*** Display usage summary *****************************/
+void usage(char *s)
+{
+   fprintf(stderr, "?GREP-E-%s\n", s);
+   fprintf(stderr,
+         "Usage: grep [-cfnv] pattern [file ...].  grep ? for help\n");
+   exit(1);
+}
+
+/*** Compile the pattern into global pbuf[] ************/
+void compile(char *source)
+{
+   char  *s;         /* Source string pointer     */
+   char  *lp;        /* Last pattern pointer      */
+   int   c;          /* Current character         */
+   int            o;          /* Temp                      */
+   char           *spp;       /* Save beginning of pattern */
+
+   s = source;
+   if (debug)
+      printf("Pattern = \"%s\"\n", s);
+   pp = pbuf;
+   while (c = *s++) {
+      /*
+       * STAR, PLUS and MINUS are special.
+       */
+      if (c == '*' || c == '+' || c == '-') {
+         if (pp == pbuf ||
+               (o=pp[-1]) == BOL ||
+               o == EOL ||
+               o == STAR ||
+               o == PLUS ||
+               o == MINUS)
+            badpat("Illegal occurrence op.", source, s);
+         store(ENDPAT);
+         store(ENDPAT);
+         spp = pp;               /* Save pattern end     */
+         while (--pp > lp)       /* Move pattern down    */
+            *pp = pp[-1];        /* one byte             */
+         *pp =   (c == '*') ? STAR :
+            (c == '-') ? MINUS : PLUS;
+         pp = spp;               /* Restore pattern end  */
+         continue;
+      }
+      /*
+       * All the rest.
+       */
+      lp = pp;         /* Remember start       */
+      switch(c) {
+
+         case '^':
+            store(BOL);
+            break;
+
+         case '$':
+            store(EOL);
+            break;
+
+         case '.':
+            store(ANY);
+            break;
+
+         case '[':
+            s = cclass(source, s);
+            break;
+
+         case ':':
+            if (*s) {
+               switch(tolower(c = *s++)) {
+
+                  case 'a':
+                  case 'A':
+                     store(ALPHA);
+                     break;
+
+                  case 'd':
+                  case 'D':
+                     store(DIGIT);
+                     break;
+
+                  case 'n':
+                  case 'N':
+                     store(NALPHA);
+                     break;
+
+                  case ' ':
+                     store(PUNCT);
+                     break;
+
+                  default:
+                     badpat("Unknown : type", source, s);
+
+               }
+               break;
+            }
+            else    badpat("No : type", source, s);
+
+         case '\\':
+            if (*s)
+               c = *s++;
+
+         default:
+            store(CHAR);
+            store(tolower(c));
+      }
+   }
+   store(ENDPAT);
+   store(0);                /* Terminate string     */
+   if (debug) {
+      for (lp = pbuf; lp < pp;) {
+         if ((c = (*lp++ & 0377)) < ' ')
+            printf("\\%o ", c);
+         else    printf("%c ", c);
+      }
+      printf("\n");
+   }
+}
+
+/*** Compile a class (within []) ***********************/
+char *cclass(char *source, char *src)
+   /* char       *source;   // Pattern start -- for error msg. */
+   /* char       *src;      // Class start */
+{
+   char   *s;        /* Source pointer    */
+   char   *cp;       /* Pattern start     */
+   int    c;         /* Current character */
+   int             o;         /* Temp              */
+
+   s = src;
+   o = CLASS;
+   if (*s == '^') {
+      ++s;
+      o = NCLASS;
+   }
+   store(o);
+   cp = pp;
+   store(0);                          /* Byte count      */
+   while ((c = *s++) && c!=']') {
+      if (c == '\\') {                /* Store quoted char    */
+         if ((c = *s++) == '\0')      /* Gotta get something  */
+            badpat("Class terminates badly", source, s);
+         else    store(tolower(c));
+      }
+      else if (c == '-' &&
+            (pp - cp) > 1 && *s != ']' && *s != '\0') {
+         c = pp[-1];             /* Range start     */
+         pp[-1] = RANGE;         /* Range signal    */
+         store(c);               /* Re-store start  */
+         c = *s++;               /* Get end char and*/
+         store(tolower(c));      /* Store it        */
+      }
+      else {
+         store(tolower(c));      /* Store normal char */
+      }
+   }
+   if (c != ']')
+      badpat("Unterminated class", source, s);
+   if ((c = (pp - cp)) >= 256)
+      badpat("Class too large", source, s);
+   if (c == 0)
+      badpat("Empty class", source, s);
+   *cp = c;
+   return(s);
+}
+
+/*** Store an entry in the pattern buffer **************/
+void store(int op)
+{
+   if (pp >= &pbuf[PMAX])
+      error("Pattern too complex\n");
+   *pp++ = op;
+}
+
+/*** Report a bad pattern specification ****************/
+void badpat(char *message, char *source, char *stop)
+   /* char  *message;       // Error message */
+   /* char  *source;        // Pattern start */
+   /* char  *stop;          // Pattern end   */
+{
+   fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source);
+   fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n",
+         stop-source, stop[-1]);
+   error("?GREP-E-Bad pattern\n");
+}
+
+/*** Scan the file for the pattern in pbuf[] ***********/
+void grep(FILE *fp, char *fn)
+   /* FILE       *fp;       // File to process            */
+   /* char       *fn;       // File name (for -f option)  */
+{
+   int lno, count, m;
+
+   lno = 0;
+   count = 0;
+   while (fgets(lbuf, LMAX, fp)) {
+      ++lno;
+      m = match();
+      if ((m && !vflag) || (!m && vflag)) {
+         ++count;
+         if (!cflag) {
+            if (fflag && fn) {
+               file(fn);
+               fn = 0;
+            }
+            if (nflag)
+               printf("%d\t", lno);
+            printf("%s\n", lbuf);
+         }
+      }
+   }
+   if (cflag) {
+      if (fflag && fn)
+         file(fn);
+      printf("%d\n", count);
+   }
+}
+
+/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/
+int match()
+{
+   char   *l;        /* Line pointer       */
+
+   for (l = lbuf; *l; ++l) {
+      if (pmatch(l, pbuf))
+         return(1);
+   }
+   return(0);
+}
+
+/*** Match partial line with pattern *******************/
+char *pmatch(char *line, char *pattern)
+   /* char               *line;     // (partial) line to match      */
+   /* char               *pattern;  // (partial) pattern to match   */
+{
+   char   *l;        /* Current line pointer         */
+   char   *p;        /* Current pattern pointer      */
+   char   c;         /* Current character            */
+   char            *e;        /* End for STAR and PLUS match  */
+   int             op;        /* Pattern operation            */
+   int             n;         /* Class counter                */
+   char            *are;      /* Start of STAR match          */
+
+   l = line;
+   if (debug > 1)
+      printf("pmatch(\"%s\")\n", line);
+   p = pattern;
+   while ((op = *p++) != ENDPAT) {
+      if (debug > 1)
+         printf("byte[%ld] = 0%o, '%c', op = 0%o\n",
+               l-line, *l, *l, op);
+      switch(op) {
+
+         case CHAR:
+            if (tolower(*l++) != *p++)
+               return(0);
+            break;
+
+         case BOL:
+            if (l != lbuf)
+               return(0);
+            break;
+
+         case EOL:
+            if (*l != '\0')
+               return(0);
+            break;
+
+         case ANY:
+            if (*l++ == '\0')
+               return(0);
+            break;
+
+         case DIGIT:
+            if ((c = *l++) < '0' || (c > '9'))
+               return(0);
+            break;
+
+         case ALPHA:
+            c = tolower(*l++);
+            if (c < 'a' || c > 'z')
+               return(0);
+            break;
+
+         case NALPHA:
+            c = tolower(*l++);
+            if (c >= 'a' && c <= 'z')
+               break;
+            else if (c < '0' || c > '9')
+               return(0);
+            break;
+
+         case PUNCT:
+            c = *l++;
+            if (c == 0 || c > ' ')
+               return(0);
+            break;
+
+         case CLASS:
+         case NCLASS:
+            c = tolower(*l++);
+            n = *p++ & 0377;
+            do {
+               if (*p == RANGE) {
+                  p += 3;
+                  n -= 2;
+                  if (c >= p[-2] && c <= p[-1])
+                     break;
+               }
+               else if (c == *p++)
+                  break;
+            } while (--n > 1);
+            if ((op == CLASS) == (n <= 1))
+               return(0);
+            if (op == CLASS)
+               p += n - 2;
+            break;
+
+         case MINUS:
+            e = pmatch(l, p);       /* Look for a match    */
+            while (*p++ != ENDPAT); /* Skip over pattern   */
+            if (e)                  /* Got a match?        */
+               l = e;               /* Yes, update string  */
+            break;                  /* Always succeeds     */
+
+         case PLUS:                 /* One or more ...     */
+            if ((l = pmatch(l, p)) == 0)
+               return(0);           /* Gotta have a match  */
+         case STAR:                 /* Zero or more ...    */
+            are = l;                /* Remember line start */
+            while (*l && (e = pmatch(l, p)))
+               l = e;               /* Get longest match   */
+            while (*p++ != ENDPAT); /* Skip over pattern   */
+            while (l >= are) {      /* Try to match rest   */
+               if (e = pmatch(l, p))
+                  return(e);
+               --l;                 /* Nope, try earlier   */
+            }
+            return(0);              /* Nothing else worked */
+
+         default:
+            printf("Bad op code %d\n", op);
+            error("Cannot happen -- match\n");
+      }
+   }
+   return(l);
+}
+
+/*** Report an error ***********************************/
+void error(char *s)
+{
+   fprintf(stderr, "%s", s);
+   exit(1);
+}
+
+/*** Main program - parse arguments & grep *************/
+int main(int argc, char **argv)
+{
+   char   *p;
+   int    c, i;
+   int             gotpattern;
+
+   FILE            *f;
+
+   if (argc <= 1)
+      usage("No arguments");
+   if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) {
+      help(documentation);
+      help(patdoc);
+      return 0;
+   }
+   nfile = argc-1;
+   gotpattern = 0;
+   for (i=1; i < argc; ++i) {
+      p = argv[i];
+      if (*p == '-') {
+         ++p;
+         while (c = *p++) {
+            switch(tolower(c)) {
+
+               case '?':
+                  help(documentation);
+                  break;
+
+               case 'C':
+               case 'c':
+                  ++cflag;
+                  break;
+
+               case 'D':
+               case 'd':
+                  ++debug;
+                  break;
+
+               case 'F':
+               case 'f':
+                  ++fflag;
+                  break;
+
+               case 'n':
+               case 'N':
+                  ++nflag;
+                  break;
+
+               case 'v':
+               case 'V':
+                  ++vflag;
+                  break;
+
+               default:
+                  usage("Unknown flag");
+            }
+         }
+         argv[i] = 0;
+         --nfile;
+      } else if (!gotpattern) {
+         compile(p);
+         argv[i] = 0;
+         ++gotpattern;
+         --nfile;
+      }
+   }
+   if (!gotpattern)
+      usage("No pattern");
+   if (nfile == 0)
+      grep(stdin, 0);
+   else {
+      fflag = fflag ^ (nfile > 0);
+      for (i=1; i < argc; ++i) {
+         if (p = argv[i]) {
+            if ((f=fopen(p, "r")) == NULL)
+               cant(p);
+            else {
+               grep(f, p);
+               fclose(f);
+            }
+         }
+      }
+   }
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect	(revision 331)
@@ -0,0 +1,3 @@
+File 46_grep.c:
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+void fred(int x)
+{
+   switch (x)
+   {
+      case 1: printf("1\n"); return;
+      case 2: printf("2\n"); break;
+      case 3: printf("3\n"); return;
+   }
+
+   printf("out\n");
+}
+
+int main()
+{
+   fred(1);
+   fred(2);
+   fred(3);
+
+   return 0;
+}    
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect	(revision 331)
@@ -0,0 +1,4 @@
+1
+2
+out
+3
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c	(revision 331)
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   char b;
+
+   a = 0;
+   while (a < 2)
+   {
+      printf("%d", a++);
+      break;
+
+      b = 'A';
+      while (b < 'C')
+      {
+         printf("%c", b++);
+      }
+      printf("e");
+   }
+   printf("\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect	(revision 331)
@@ -0,0 +1,1 @@
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c	(revision 331)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+struct point
+{
+   double x;
+   double y;
+};
+
+struct point point_array[100];
+
+int main()
+{
+   int my_point = 10;
+
+   point_array[my_point].x = 12.34;
+   point_array[my_point].y = 56.78;
+
+   printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect	(revision 331)
@@ -0,0 +1,1 @@
+12.340000, 56.780000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c	(revision 331)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int fred()
+{
+   printf("fred\n");
+   return 0;
+}
+
+int joe()
+{
+   printf("joe\n");
+   return 1;
+}
+
+int main()
+{
+   printf("%d\n", fred() && joe());
+   printf("%d\n", fred() || joe());
+   printf("%d\n", joe() && fred());
+   printf("%d\n", joe() || fred());
+   printf("%d\n", fred() && (1 + joe()));
+   printf("%d\n", fred() || (0 + joe()));
+   printf("%d\n", joe() && (0 + fred()));
+   printf("%d\n", joe() || (1 + fred()));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect	(revision 331)
@@ -0,0 +1,20 @@
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+static int fred = 1234;
+static int joe;
+
+void henry()
+{
+   static int fred = 4567;
+
+   printf("%d\n", fred);
+   fred++;
+}
+
+int main()
+{
+   printf("%d\n", fred);
+   henry();
+   henry();
+   henry();
+   henry();
+   printf("%d\n", fred);
+   fred = 8901;
+   joe = 2345;
+   printf("%d\n", fred);
+   printf("%d\n", joe);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect	(revision 331)
@@ -0,0 +1,8 @@
+1234
+4567
+4568
+4569
+4570
+1234
+8901
+2345
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c	(revision 331)
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+enum fred { a, b, c };
+
+int main()
+{
+   printf("a=%d\n", a);
+   printf("b=%d\n", b);
+   printf("c=%d\n", c);
+
+   enum fred d;
+
+   typedef enum { e, f, g } h;
+   typedef enum { i, j, k } m;
+
+   printf("e=%d\n", e);
+   printf("f=%d\n", f);
+   printf("g=%d\n", g);
+
+   printf("i=%d\n", i);
+   printf("j=%d\n", j);
+   printf("k=%d\n", k);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect	(revision 331)
@@ -0,0 +1,9 @@
+a=0
+b=1
+c=2
+e=0
+f=1
+g=2
+i=0
+j=1
+k=2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c	(revision 331)
@@ -0,0 +1,56 @@
+#include <stdio.h>
+
+void fred()
+{
+   printf("In fred()\n");
+   goto done;
+   printf("In middle\n");
+done:
+   printf("At end\n");
+}
+
+void joe()
+{
+   int b = 5678;
+
+   printf("In joe()\n");
+
+   {
+      int c = 1234;
+      printf("c = %d\n", c);
+      goto outer;
+      printf("uh-oh\n");
+   }
+
+outer:    
+
+   printf("done\n");
+}
+
+void henry()
+{
+   int a;
+
+   printf("In henry()\n");
+   goto inner;
+
+   {
+      int b;
+inner:    
+      b = 1234;
+      printf("b = %d\n", b);
+   }
+
+   printf("done\n");
+}
+
+int main()
+{
+   fred();
+   joe();
+   henry();
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect	(revision 331)
@@ -0,0 +1,8 @@
+In fred()
+At end
+In joe()
+c = 1234
+done
+In henry()
+b = 1234
+done
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c	(revision 331)
@@ -0,0 +1,52 @@
+/* $Id$
+
+Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>.
+
+ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
+each of the operands. The type of the result is that of the promoted
+left operand."
+*/
+
+#include <stdio.h>
+
+#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0)
+#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1))
+#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0)
+#define TEST2(X)                 \
+  do                             \
+    {                            \
+      TEST1((X),short);          \
+      TEST1((X),int);            \
+      TEST1((X),long);           \
+      TEST1((X),long long);      \
+    }                            \
+  while (0)
+#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0)
+#define TEST4(X)                 \
+  do                             \
+    {                            \
+      TEST3((X),short);          \
+      TEST3((X),int);            \
+      TEST3((X),long);           \
+      TEST3((X),long long);      \
+    }                            \
+ while (0)
+
+static int debug, nfailed = 0;
+
+static void check (const char *s, int arg1, int shift)
+{
+  int failed = arg1 != shift;
+  if (debug || failed)
+    printf ("%s %d %d\n", s, arg1, shift);
+  nfailed += failed;
+}
+
+int main (int argc, char **argv)
+{
+  debug = argc > 1;
+  TEST4(1);
+  TEST4(-1);
+  printf ("%d test(s) failed\n", nfailed);
+  return nfailed != 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect	(revision 331)
@@ -0,0 +1,1 @@
+0 test(s) failed
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c	(revision 331)
@@ -0,0 +1,51 @@
+#if defined test_56_btype_excess_1
+struct A {} int i;
+
+#elif defined test_57_btype_excess_2
+char int i;
+
+#elif defined test_58_function_redefinition
+int f(void) { return 0; }
+int f(void) { return 1; }
+
+#elif defined test_global_redefinition
+int xxx = 1;
+int xxx;
+int xxx = 2;
+
+#elif defined test_59_function_array
+int (*fct)[42](int x);
+
+#elif defined test_60_enum_redefinition
+enum color { RED, GREEN, BLUE };
+enum color { R, G, B };
+enum color c;
+
+#elif defined test_62_enumerator_redefinition
+enum color { RED, GREEN, BLUE };
+enum rgb { RED, G, B};
+enum color c = RED;
+
+#elif defined test_63_local_enumerator_redefinition
+enum {
+    FOO,
+    BAR
+};
+
+int main(void)
+{
+    enum {
+        FOO = 2,
+        BAR
+    };
+
+    return BAR - FOO;
+}
+
+#elif defined test_61_undefined_enum
+enum rgb3 c = 42;
+
+#elif defined test_74_non_const_init
+int i = i++;
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect	(revision 331)
@@ -0,0 +1,28 @@
+[test_56_btype_excess_1]
+60_errors_and_warnings.c:2: error: too many basic types
+
+[test_57_btype_excess_2]
+60_errors_and_warnings.c:5: error: too many basic types
+
+[test_58_function_redefinition]
+60_errors_and_warnings.c:9: error: redefinition of 'f'
+
+[test_global_redefinition]
+60_errors_and_warnings.c:14: error: redefinition of 'xxx'
+
+[test_59_function_array]
+60_errors_and_warnings.c:17: error: declaration of an array of functions
+
+[test_60_enum_redefinition]
+60_errors_and_warnings.c:21: error: struct/union/enum already defined
+
+[test_62_enumerator_redefinition]
+60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
+
+[test_63_local_enumerator_redefinition]
+
+[test_61_undefined_enum]
+60_errors_and_warnings.c:46: error: unknown type size
+
+[test_74_non_const_init]
+60_errors_and_warnings.c:49: error: initializer element is not constant
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c	(revision 331)
@@ -0,0 +1,12 @@
+#include <stdio.h>	// printf()
+
+#define CAT2(a,b) a##b
+#define CAT(a,b) CAT2(a,b)
+#define AB(x) CAT(x,y)
+
+int main(void)
+{
+  int xy = 42;
+  printf("%d\n", CAT(A,B)(x));
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect	(revision 331)
@@ -0,0 +1,1 @@
+42
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define P(A,B) A ## B ; bob
+#define Q(A,B) A ## B+
+
+int main(void)
+{
+    int bob, jim = 21;
+    bob = P(jim,) *= 2;
+    printf("jim: %d, bob: %d\n", jim, bob);
+    jim = 60 Q(+,)3;
+    printf("jim: %d\n", jim);
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect	(revision 331)
@@ -0,0 +1,2 @@
+jim: 21, bob: 42
+jim: 63
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c	(revision 331)
@@ -0,0 +1,77 @@
+#include <stdio.h>
+
+int main()
+{
+    /* decimal floating constant */
+    float fa0 = .123f;
+    float fa1 = .123E12F;
+    float fa2 = .123e-12f;
+    float fa3 = .123e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3);
+
+    float fb0 = 123.123f;
+    float fb1 = 123.123E12F;
+    float fb2 = 123.123e-12f;
+    float fb3 = 123.123e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3);
+
+    float fc0 = 123.f;
+    float fc1 = 123.E12F;
+    float fc2 = 123.e-12f;
+    float fc3 = 123.e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3);
+
+    float fd0 = 123E12F;
+    float fd1 = 123e-12f;
+    float fd2 = 123e+12f;
+    printf("%f\n%f\n%f\n\n", fd0, fd1, fd2);
+    printf("\n");
+
+    /* hexadecimal floating constant */
+    double da0 = 0X.1ACP12;
+    double da1 = 0x.1acp-12;
+    double da2 = 0x.1acp+12;
+    printf("%f\n%f\n%f\n\n", da0, da1, da2);
+
+    double db0 = 0X1AC.BDP12;
+    double db1 = 0x1ac.bdp-12;
+    double db2 = 0x1ac.dbp+12;
+    printf("%f\n%f\n%f\n\n", db0, db1, db2);
+
+    double dc0 = 0X1AC.P12;
+    double dc1 = 0x1ac.p-12;
+    double dc2 = 0x1ac.p+12;
+    printf("%f\n%f\n%f\n\n", dc0, dc1, dc2);
+
+    double dd0 = 0X1ACP12;
+    double dd1 = 0x1acp-12;
+    double dd2 = 0x1acp+12;
+    printf("%f\n%f\n%f\n\n", dd0, dd1, dd2);
+    printf("\n");
+
+#ifdef __TINYC__
+    /* TCC extension
+       binary floating constant */
+    long double la0 = 0B.110101100P12L;
+    long double la1 = 0b.110101100p-12l;
+    long double la2 = 0b.110101100p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2);
+
+    long double lb0 = 0B110101100.10111101P12L;
+    long double lb1 = 0b110101100.10111101p-12l;
+    long double lb2 = 0b110101100.10111101p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2);
+
+    long double lc0 = 0B110101100.P12L;
+    long double lc1 = 0b110101100.p-12l;
+    long double lc2 = 0b110101100.p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2);
+
+    long double ld0 = 0B110101100P12L;
+    long double ld1 = 0b110101100p-12l;
+    long double ld2 = 0b110101100p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2);
+#endif
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect	(revision 331)
@@ -0,0 +1,53 @@
+0.123000
+122999996416.000000
+0.000000
+122999996416.000000
+
+123.123001
+123122997002240.000000
+0.000000
+123122997002240.000000
+
+123.000000
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+
+428.000000
+0.000026
+428.000000
+
+1756112.000000
+0.104672
+1756592.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+
+3424.000000
+0.000204
+3424.000000
+
+1756112.000000
+0.104672
+1756112.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c	(revision 331)
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#define T(a,b,c) a b c
+
+int main(void)
+{
+    printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,));
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect	(revision 331)
@@ -0,0 +1,1 @@
+17
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c	(revision 331)
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+int main()
+{
+    long long int res = 0;
+
+    if (res < -2147483648LL) {
+        printf("Error: 0 < -2147483648\n");
+        return 1;
+    }
+    else
+    if (2147483647LL < res) {
+        printf("Error: 2147483647 < 0\n");
+        return 2;
+    }
+    else
+        printf("long long constant test ok.\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect	(revision 331)
@@ -0,0 +1,1 @@
+long long constant test ok.
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c	(revision 331)
@@ -0,0 +1,527 @@
+// This program is designed to test some arm64-specific things, such as the
+// calling convention, but should give the same results on any architecture.
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+struct s1 { char x[1]; } s1 = { "0" };
+struct s2 { char x[2]; } s2 = { "12" };
+struct s3 { char x[3]; } s3 = { "345" };
+struct s4 { char x[4]; } s4 = { "6789" };
+struct s5 { char x[5]; } s5 = { "abcde" };
+struct s6 { char x[6]; } s6 = { "fghijk" };
+struct s7 { char x[7]; } s7 = { "lmnopqr" };
+struct s8 { char x[8]; } s8 = { "stuvwxyz" };
+struct s9 { char x[9]; } s9 = { "ABCDEFGHI" };
+struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" };
+struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" };
+struct s12 { char x[12]; } s12 = { "456789abcdef" };
+struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" };
+struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" };
+struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" };
+struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" };
+struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" };
+
+struct hfa11 { float a; } hfa11 = { 11.1 };
+struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 };
+struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 };
+struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 };
+
+struct hfa21 { double a; } hfa21 = { 21.1 };
+struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 };
+struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 };
+struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 };
+
+struct hfa31 { long double a; } hfa31 = { 31.1 };
+struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 };
+struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };
+struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };
+
+void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }
+void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }
+void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }
+void fa_s4(struct s4 a) { printf("%.4s\n", a.x); }
+void fa_s5(struct s5 a) { printf("%.5s\n", a.x); }
+void fa_s6(struct s6 a) { printf("%.6s\n", a.x); }
+void fa_s7(struct s7 a) { printf("%.7s\n", a.x); }
+void fa_s8(struct s8 a) { printf("%.8s\n", a.x); }
+void fa_s9(struct s9 a) { printf("%.9s\n", a.x); }
+void fa_s10(struct s10 a) { printf("%.10s\n", a.x); }
+void fa_s11(struct s11 a) { printf("%.11s\n", a.x); }
+void fa_s12(struct s12 a) { printf("%.12s\n", a.x); }
+void fa_s13(struct s13 a) { printf("%.13s\n", a.x); }
+void fa_s14(struct s14 a) { printf("%.14s\n", a.x); }
+void fa_s15(struct s15 a) { printf("%.15s\n", a.x); }
+void fa_s16(struct s16 a) { printf("%.16s\n", a.x); }
+void fa_s17(struct s17 a) { printf("%.17s\n", a.x); }
+
+void fa_hfa11(struct hfa11 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa12(struct hfa12 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa13(struct hfa13 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa14(struct hfa14 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa21(struct hfa21 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa22(struct hfa22 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa23(struct hfa23 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa24(struct hfa24 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa31(struct hfa31 a)
+{ printf("%.1Lf\n", a.a); }
+void fa_hfa32(struct hfa32 a)
+{ printf("%.1Lf %.1Lf\n", a.a, a.a); }
+void fa_hfa33(struct hfa33 a)
+{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }
+void fa_hfa34(struct hfa34 a)
+{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }
+
+void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,
+         struct s12 e, struct s13 f)
+{
+    printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d,
+         struct s13 e, struct s14 f)
+{
+    printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c)
+{
+    printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n",
+           a.a, a.d, b.a, b.c, c.a, c.b);
+}
+
+void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d,
+         struct s3 e, struct hfa34 f)
+{
+    printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n",
+           a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d);
+}
+
+void arg(void)
+{
+    printf("Arguments:\n");
+    fa_s1(s1);
+    fa_s2(s2);
+    fa_s3(s3);
+    fa_s4(s4);
+    fa_s5(s5);
+    fa_s6(s6);
+    fa_s7(s7);
+    fa_s8(s8);
+    fa_s9(s9);
+    fa_s10(s10);
+    fa_s11(s11);
+    fa_s12(s12);
+    fa_s13(s13);
+    fa_s14(s14);
+    fa_s15(s15);
+    fa_s16(s16);
+    fa_s17(s17);
+    fa_hfa11(hfa11);
+    fa_hfa12(hfa12);
+    fa_hfa13(hfa13);
+    fa_hfa14(hfa14);
+    fa_hfa21(hfa21);
+    fa_hfa22(hfa22);
+    fa_hfa23(hfa23);
+    fa_hfa24(hfa24);
+    fa_hfa31(hfa31);
+    fa_hfa32(hfa32);
+    fa_hfa33(hfa33);
+    fa_hfa34(hfa34);
+    fa1(s8, s9, s10, s11, s12, s13);
+    fa2(s9, s10, s11, s12, s13, s14);
+    fa3(hfa14, hfa23, hfa32);
+    fa4(s1, hfa14, s2, hfa24, s3, hfa34);
+}
+
+struct s1 fr_s1(void) { return s1; }
+struct s2 fr_s2(void) { return s2; }
+struct s3 fr_s3(void) { return s3; }
+struct s4 fr_s4(void) { return s4; }
+struct s5 fr_s5(void) { return s5; }
+struct s6 fr_s6(void) { return s6; }
+struct s7 fr_s7(void) { return s7; }
+struct s8 fr_s8(void) { return s8; }
+struct s9 fr_s9(void) { return s9; }
+struct s10 fr_s10(void) { return s10; }
+struct s11 fr_s11(void) { return s11; }
+struct s12 fr_s12(void) { return s12; }
+struct s13 fr_s13(void) { return s13; }
+struct s14 fr_s14(void) { return s14; }
+struct s15 fr_s15(void) { return s15; }
+struct s16 fr_s16(void) { return s16; }
+struct s17 fr_s17(void) { return s17; }
+
+struct hfa11 fr_hfa11(void) { return hfa11; }
+struct hfa12 fr_hfa12(void) { return hfa12; }
+struct hfa13 fr_hfa13(void) { return hfa13; }
+struct hfa14 fr_hfa14(void) { return hfa14; }
+
+struct hfa21 fr_hfa21(void) { return hfa21; }
+struct hfa22 fr_hfa22(void) { return hfa22; }
+struct hfa23 fr_hfa23(void) { return hfa23; }
+struct hfa24 fr_hfa24(void) { return hfa24; }
+
+struct hfa31 fr_hfa31(void) { return hfa31; }
+struct hfa32 fr_hfa32(void) { return hfa32; }
+struct hfa33 fr_hfa33(void) { return hfa33; }
+struct hfa34 fr_hfa34(void) { return hfa34; }
+
+void ret(void)
+{
+    struct s1 t1 = fr_s1();
+    struct s2 t2 = fr_s2();
+    struct s3 t3 = fr_s3();
+    struct s4 t4 = fr_s4();
+    struct s5 t5 = fr_s5();
+    struct s6 t6 = fr_s6();
+    struct s7 t7 = fr_s7();
+    struct s8 t8 = fr_s8();
+    struct s9 t9 = fr_s9();
+    struct s10 t10 = fr_s10();
+    struct s11 t11 = fr_s11();
+    struct s12 t12 = fr_s12();
+    struct s13 t13 = fr_s13();
+    struct s14 t14 = fr_s14();
+    struct s15 t15 = fr_s15();
+    struct s16 t16 = fr_s16();
+    struct s17 t17 = fr_s17();
+    printf("Return values:\n");
+    printf("%.1s\n", t1.x);
+    printf("%.2s\n", t2.x);
+    printf("%.3s\n", t3.x);
+    printf("%.4s\n", t4.x);
+    printf("%.5s\n", t5.x);
+    printf("%.6s\n", t6.x);
+    printf("%.7s\n", t7.x);
+    printf("%.8s\n", t8.x);
+    printf("%.9s\n", t9.x);
+    printf("%.10s\n", t10.x);
+    printf("%.11s\n", t11.x);
+    printf("%.12s\n", t12.x);
+    printf("%.13s\n", t13.x);
+    printf("%.14s\n", t14.x);
+    printf("%.15s\n", t15.x);
+    printf("%.16s\n", t16.x);
+    printf("%.17s\n", t17.x);
+    printf("%.1f\n", fr_hfa11().a);
+    printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b);
+    printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c);
+    printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d);
+    printf("%.1f\n", fr_hfa21().a);
+    printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b);
+    printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c);
+    printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d);
+    printf("%.1Lf\n", fr_hfa31().a);
+    printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);
+    printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);
+    printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);
+}
+
+int match(const char **s, const char *f)
+{
+    const char *p = *s;
+    for (p = *s; *f && *f == *p; f++, p++)
+        ;
+    if (!*f) {
+        *s = p - 1;
+        return 1;
+    }
+    return 0;
+}
+
+void myprintf(const char *format, ...)
+{
+    const char *s;
+    va_list ap;
+    va_start(ap, format);
+    for (s = format; *s; s++) {
+        if (match(&s, "%7s")) {
+            struct s7 t7 = va_arg(ap, struct s7);
+            printf("%.7s", t7.x);
+        }
+        else if (match(&s, "%9s")) {
+            struct s9 t9 = va_arg(ap, struct s9);
+            printf("%.9s", t9.x);
+        }
+        else if (match(&s, "%hfa11")) {
+            struct hfa11 x = va_arg(ap, struct hfa11);
+            printf("%.1f,%.1f", x.a, x.a);
+        }
+        else if (match(&s, "%hfa12")) {
+            struct hfa12 x = va_arg(ap, struct hfa12);
+            printf("%.1f,%.1f", x.a, x.b);
+        }
+        else if (match(&s, "%hfa13")) {
+            struct hfa13 x = va_arg(ap, struct hfa13);
+            printf("%.1f,%.1f", x.a, x.c);
+        }
+        else if (match(&s, "%hfa14")) {
+            struct hfa14 x = va_arg(ap, struct hfa14);
+            printf("%.1f,%.1f", x.a, x.d);
+        }
+        else if (match(&s, "%hfa21")) {
+            struct hfa21 x = va_arg(ap, struct hfa21);
+            printf("%.1f,%.1f", x.a, x.a);
+        }
+        else if (match(&s, "%hfa22")) {
+            struct hfa22 x = va_arg(ap, struct hfa22);
+            printf("%.1f,%.1f", x.a, x.b);
+        }
+        else if (match(&s, "%hfa23")) {
+            struct hfa23 x = va_arg(ap, struct hfa23);
+            printf("%.1f,%.1f", x.a, x.c);
+        }
+        else if (match(&s, "%hfa24")) {
+            struct hfa24 x = va_arg(ap, struct hfa24);
+            printf("%.1f,%.1f", x.a, x.d);
+        }
+        else if (match(&s, "%hfa31")) {
+            struct hfa31 x = va_arg(ap, struct hfa31);
+            printf("%.1Lf,%.1Lf", x.a, x.a);
+        }
+        else if (match(&s, "%hfa32")) {
+            struct hfa32 x = va_arg(ap, struct hfa32);
+            printf("%.1Lf,%.1Lf", x.a, x.b);
+        }
+        else if (match(&s, "%hfa33")) {
+            struct hfa33 x = va_arg(ap, struct hfa33);
+            printf("%.1Lf,%.1Lf", x.a, x.c);
+        }
+        else if (match(&s, "%hfa34")) {
+            struct hfa34 x = va_arg(ap, struct hfa34);
+            printf("%.1Lf,%.1Lf", x.a, x.d);
+        }
+        else
+            putchar(*s);
+    }
+    putchar('\n');
+}
+
+void stdarg(void)
+{
+    printf("stdarg:\n");
+    myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9);
+    myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9);
+
+    myprintf("HFA long double:");
+    myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34);
+    myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34);
+    myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34);
+    myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34);
+
+    myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33",
+             hfa32, hfa33, hfa33, hfa33, hfa33);
+    myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33",
+             hfa31, hfa33, hfa33, hfa33, hfa33);
+    myprintf("%hfa33 %hfa33 %hfa33 %hfa33",
+             hfa33, hfa33, hfa33, hfa33);
+
+    myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32",
+             hfa34, hfa32, hfa32, hfa32, hfa32);
+    myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32",
+             hfa33, hfa32, hfa32, hfa32, hfa32);
+
+    myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31",
+             hfa34, hfa32, hfa31, hfa31, hfa31, hfa31);
+
+    myprintf("HFA double:");
+    myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24);
+    myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24);
+    myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24);
+    myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24);
+
+    myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23",
+             hfa22, hfa23, hfa23, hfa23, hfa23);
+    myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23",
+             hfa21, hfa23, hfa23, hfa23, hfa23);
+    myprintf("%hfa23 %hfa23 %hfa23 %hfa23",
+             hfa23, hfa23, hfa23, hfa23);
+
+    myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22",
+             hfa24, hfa22, hfa22, hfa22, hfa22);
+    myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22",
+             hfa23, hfa22, hfa22, hfa22, hfa22);
+
+    myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21",
+             hfa24, hfa22, hfa21, hfa21, hfa21, hfa21);
+
+    myprintf("HFA float:");
+    myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14);
+    myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14);
+    myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14);
+    myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14);
+
+    myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13",
+             hfa12, hfa13, hfa13, hfa13, hfa13);
+    myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13",
+             hfa11, hfa13, hfa13, hfa13, hfa13);
+    myprintf("%hfa13 %hfa13 %hfa13 %hfa13",
+             hfa13, hfa13, hfa13, hfa13);
+
+    myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12",
+             hfa14, hfa12, hfa12, hfa12, hfa12);
+    myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12",
+             hfa13, hfa12, hfa12, hfa12, hfa12);
+
+    myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11",
+             hfa14, hfa12, hfa11, hfa11, hfa11, hfa11);
+}
+
+void pll(unsigned long long x)
+{
+    printf("%llx\n", x);
+}
+
+void movi(void)
+{
+    printf("MOVI:\n");
+    pll(0);
+    pll(0xabcd);
+    pll(0xabcd0000);
+    pll(0xabcd00000000);
+    pll(0xabcd000000000000);
+    pll(0xffffabcd);
+    pll(0xabcdffff);
+    pll(0xffffffffffffabcd);
+    pll(0xffffffffabcdffff);
+    pll(0xffffabcdffffffff);
+    pll(0xabcdffffffffffff);
+    pll(0xaaaaaaaa);
+    pll(0x5555555555555555);
+    pll(0x77777777);
+    pll(0x3333333333333333);
+    pll(0xf8f8f8f8);
+    pll(0x1e1e1e1e1e1e1e1e);
+    pll(0x3f803f80);
+    pll(0x01ff01ff01ff01ff);
+    pll(0x007fffc0);
+    pll(0x03fff80003fff800);
+    pll(0x0007fffffffffe00);
+
+    pll(0xabcd1234);
+    pll(0xabcd00001234);
+    pll(0xabcd000000001234);
+    pll(0xabcd12340000);
+    pll(0xabcd000012340000);
+    pll(0xabcd123400000000);
+    pll(0xffffffffabcd1234);
+    pll(0xffffabcdffff1234);
+    pll(0xabcdffffffff1234);
+    pll(0xffffabcd1234ffff);
+    pll(0xabcdffff1234ffff);
+    pll(0xabcd1234ffffffff);
+
+    pll(0xffffef0123456789);
+    pll(0xabcdef012345ffff);
+
+    pll(0xabcdef0123456789);
+}
+
+static uint32_t addip0(uint32_t x) { return x + 0; }
+static uint64_t sublp0(uint64_t x) { return x - 0; }
+static uint32_t addip123(uint32_t x) { return x + 123; }
+static uint64_t addlm123(uint64_t x) { return x + -123; }
+static uint64_t sublp4095(uint64_t x) { return x - 4095; }
+static uint32_t subim503808(uint32_t x) { return x - -503808; }
+static uint64_t addp12345(uint64_t x) { return x + 12345; }
+static uint32_t subp12345(uint32_t x) { return x - 12345; }
+
+static uint32_t mvni(uint32_t x) { return 0xffffffff - x; }
+static uint64_t negl(uint64_t x) { return 0 - x; }
+static uint32_t rsbi123(uint32_t x) { return 123 - x; }
+static uint64_t rsbl123(uint64_t x) { return 123 - x; }
+
+static uint32_t andi0(uint32_t x) { return x & 0; }
+static uint64_t andlm1(uint64_t x) { return x & -1; }
+static uint64_t orrl0(uint64_t x) { return x | 0; }
+static uint32_t orrim1(uint32_t x) { return x | -1; }
+static uint32_t eori0(uint32_t x) { return x ^ 0; }
+static uint64_t eorlm1(uint64_t x) { return x ^ -1; }
+static uint32_t and0xf0(uint32_t x) { return x & 0xf0; }
+static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; }
+static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; }
+
+static uint32_t lsli0(uint32_t x) { return x << 0; }
+static uint32_t lsri0(uint32_t x) { return x >> 0; }
+static int64_t asrl0(int64_t x) { return x >> 0; }
+static uint32_t lsli1(uint32_t x) { return x << 1; }
+static uint32_t lsli31(uint32_t x) { return x << 31; }
+static uint64_t lsll1(uint64_t x) { return x << 1; }
+static uint64_t lsll63(uint64_t x) { return x << 63; }
+static uint32_t lsri1(uint32_t x) { return x >> 1; }
+static uint32_t lsri31(uint32_t x) { return x >> 31; }
+static uint64_t lsrl1(uint64_t x) { return x >> 1; }
+static uint64_t lsrl63(uint64_t x) { return x >> 63; }
+static int32_t asri1(int32_t x) { return x >> 1; }
+static int32_t asri31(int32_t x) { return x >> 31; }
+static int64_t asrl1(int64_t x) { return x >> 1; }
+static int64_t asrl63(int64_t x) { return x >> 63; }
+
+void opi(void)
+{
+    int x = 1000;
+    pll(addip0(x));
+    pll(sublp0(x));
+    pll(addip123(x));
+    pll(addlm123(x));
+    pll(sublp4095(x));
+    pll(subim503808(x));
+    pll(addp12345(x));
+    pll(subp12345(x));
+    pll(mvni(x));
+    pll(negl(x));
+    pll(rsbi123(x));
+    pll(rsbl123(x));
+    pll(andi0(x));
+    pll(andlm1(x));
+    pll(orrl0(x));
+    pll(orrim1(x));
+    pll(eori0(x));
+    pll(eorlm1(x));
+    pll(and0xf0(x));
+    pll(orr0xf0(x));
+    pll(eor0xf0(x));
+    pll(lsli0(x));
+    pll(lsri0(x));
+    pll(asrl0(x));
+    pll(lsli1(x));
+    pll(lsli31(x));
+    pll(lsll1(x));
+    pll(lsll63(x));
+    pll(lsri1(x));
+    pll(lsri31(x));
+    pll(lsrl1(x));
+    pll(lsrl63(x));
+    pll(asri1(x));
+    pll(asri31(x));
+    pll(asrl1(x));
+    pll(asrl63(x));
+}
+
+void pcs(void)
+{
+    arg();
+    ret();
+    stdarg();
+    movi();
+    opi();
+}
+
+int main()
+{
+    pcs();
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect	(revision 331)
@@ -0,0 +1,174 @@
+Arguments:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.1
+13.1 13.2 13.3
+14.1 14.2 14.3 14.4
+21.1
+22.1 22.1
+23.1 23.2 23.3
+24.1 24.2 24.3 24.4
+31.1
+32.1 32.1
+33.1 33.2 33.3
+34.1 34.2 34.3 34.4
+stu ABC JKL TUV 456 ghi
+ABC JKL TUV 456 ghi tuv
+14.1 14.4 23.1 23.3 32.1 32.2
+0 14.1 14.4 12 24.1 24.4 345 34.1 34.4
+Return values:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.2
+13.1 13.3
+14.1 14.4
+21.1
+22.1 22.2
+23.1 23.3
+24.1 24.4
+31.1
+32.1 32.2
+33.1 33.3
+34.1 34.4
+stdarg:
+ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+HFA long double:
+34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4
+33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4
+31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1
+HFA double:
+24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4
+23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4
+21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1
+HFA float:
+14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4
+13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4
+11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1
+MOVI:
+0
+abcd
+abcd0000
+abcd00000000
+abcd000000000000
+ffffabcd
+abcdffff
+ffffffffffffabcd
+ffffffffabcdffff
+ffffabcdffffffff
+abcdffffffffffff
+aaaaaaaa
+5555555555555555
+77777777
+3333333333333333
+f8f8f8f8
+1e1e1e1e1e1e1e1e
+3f803f80
+1ff01ff01ff01ff
+7fffc0
+3fff80003fff800
+7fffffffffe00
+abcd1234
+abcd00001234
+abcd000000001234
+abcd12340000
+abcd000012340000
+abcd123400000000
+ffffffffabcd1234
+ffffabcdffff1234
+abcdffffffff1234
+ffffabcd1234ffff
+abcdffff1234ffff
+abcd1234ffffffff
+ffffef0123456789
+abcdef012345ffff
+abcdef0123456789
+3e8
+3e8
+463
+36d
+fffffffffffff3e9
+7b3e8
+3421
+ffffd3af
+fffffc17
+fffffffffffffc18
+fffffc93
+fffffffffffffc93
+0
+3e8
+3e8
+ffffffff
+3e8
+fffffffffffffc17
+e0
+3f8
+318
+3e8
+3e8
+3e8
+7d0
+0
+7d0
+0
+1f4
+0
+1f4
+0
+1f4
+0
+1f4
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c	(revision 331)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+/* This test is a snippet from the J interpreter */
+
+typedef long I;
+typedef struct{I c[4];I b,e,k;} PT;
+
+PT cases[] = {
+ ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1,
+ ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1,
+ (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1,
+ (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0,
+};
+
+int main() {
+    int i, j;
+
+    for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) {
+	for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++)
+	    printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]);
+
+	printf("cases[%d].b=%ld\n", j, cases[j].b);
+	printf("cases[%d].e=%ld\n", j, cases[j].e);
+	printf("cases[%d].k=%ld\n", j, cases[j].k);
+	printf("\n");
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect	(revision 331)
@@ -0,0 +1,72 @@
+cases[0].c[0]=73400320
+cases[0].c[1]=262144
+cases[0].c[2]=805567999
+cases[0].c[3]=-1
+cases[0].b=1
+cases[0].e=2
+cases[0].k=1
+
+cases[1].c[0]=879754751
+cases[1].c[1]=262144
+cases[1].c[2]=262144
+cases[1].c[3]=805567999
+cases[1].b=2
+cases[1].e=3
+cases[1].k=2
+
+cases[2].c[0]=879754751
+cases[2].c[1]=805567999
+cases[2].c[2]=262144
+cases[2].c[3]=805567999
+cases[2].b=1
+cases[2].e=3
+cases[2].k=2
+
+cases[3].c[0]=879754751
+cases[3].c[1]=805830143
+cases[3].c[2]=524288
+cases[3].c[3]=-1
+cases[3].b=1
+cases[3].e=2
+cases[3].k=1
+
+cases[4].c[0]=879754751
+cases[4].c[1]=805830143
+cases[4].c[2]=1048576
+cases[4].c[3]=805830143
+cases[4].b=1
+cases[4].e=3
+cases[4].k=1
+
+cases[5].c[0]=879754751
+cases[5].c[1]=805830143
+cases[5].c[2]=262144
+cases[5].c[3]=262144
+cases[5].b=1
+cases[5].e=3
+cases[5].k=1
+
+cases[6].c[0]=73400320
+cases[6].c[1]=807403007
+cases[6].c[2]=807403007
+cases[6].c[3]=-1
+cases[6].b=1
+cases[6].e=2
+cases[6].k=1
+
+cases[7].c[0]=839122431
+cases[7].c[1]=2097152
+cases[7].c[2]=807403007
+cases[7].c[3]=-1
+cases[7].b=0
+cases[7].e=2
+cases[7].k=1
+
+cases[8].c[0]=67108864
+cases[8].c[1]=807403007
+cases[8].c[2]=134217728
+cases[8].c[3]=-1
+cases[8].b=0
+cases[8].e=2
+cases[8].k=0
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c	(revision 331)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+#define $(x) x
+#define $fred 10
+#define joe$ 20
+#define hen$y 30
+
+#define $10(x) x*10
+#define _$10(x) x/10
+
+int main()
+{
+   printf("fred=%d\n", $fred);
+   printf("joe=%d\n", joe$);
+   printf("henry=%d\n", hen$y);
+
+   printf("fred2=%d\n", $($fred));
+   printf("joe2=%d\n", $(joe$));
+   printf("henry2=%d\n", $(hen$y));
+
+   printf("fred10=%d\n", $10($fred));
+   printf("joe_10=%d\n", _$10(joe$));
+
+   int $ = 10;
+   int a100$ = 100;
+   int a$$ = 1000;
+   int a$c$b = 2121;
+   int $100 = 10000;
+   const char *$$$ = "money";
+
+   printf("local=%d\n", $);
+   printf("a100$=%d\n", a100$);
+   printf("a$$=%d\n", a$$);
+   printf("a$c$b=%d\n", a$c$b);
+   printf("$100=%d\n", $100);
+   printf("$$$=%s", $$$);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect	(revision 331)
@@ -0,0 +1,14 @@
+fred=10
+joe=20
+henry=30
+fred2=10
+joe2=20
+henry2=30
+fred10=100
+joe_10=2
+local=10
+a100$=100
+a$$=1000
+a$c$b=2121
+$100=10000
+$$$=money
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int main()
+{
+    /* must not affect how #pragma ppop_macro works */
+    #define pop_macro foobar1
+
+    /* must not affect how #pragma push_macro works */
+    #define push_macro foobar2
+
+    #undef abort
+    #define abort "111"
+    printf("abort = %s\n", abort);
+
+    #pragma push_macro("abort")
+    #undef abort
+    #define abort "222"
+    printf("abort = %s\n", abort);
+
+    #pragma push_macro("abort")
+    #undef abort
+    #define abort "333"
+    printf("abort = %s\n", abort);
+
+    #pragma pop_macro("abort")
+    printf("abort = %s\n", abort);
+
+    #pragma pop_macro("abort")
+    printf("abort = %s\n", abort);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect	(revision 331)
@@ -0,0 +1,5 @@
+abort = 111
+abort = 222
+abort = 333
+abort = 222
+abort = 111
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c	(revision 331)
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+/* This test segfaults as of April 27, 2015. */
+void f1(int argc)
+{
+  char test[argc];
+  if(0)
+  label:
+    printf("boom!\n");
+  if(argc-- == 0)
+    return;
+  goto label;
+}
+
+/* This segfaulted on 2015-11-19. */
+void f2(void)
+{
+    goto start;
+    {
+        int a[1 && 1]; /* not a variable-length array */
+        int b[1 || 1]; /* not a variable-length array */
+        int c[1 ? 1 : 1]; /* not a variable-length array */
+    start:
+        a[0] = 0;
+        b[0] = 0;
+        c[0] = 0;
+    }
+}
+
+void f3(void)
+{
+    printf("%d\n", 0 ? printf("x1\n") : 11);
+    printf("%d\n", 1 ? 12 : printf("x2\n"));
+    printf("%d\n", 0 && printf("x3\n"));
+    printf("%d\n", 1 || printf("x4\n"));
+}
+
+int main()
+{
+  f1(2);
+  f2();
+  f3();
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect	(revision 331)
@@ -0,0 +1,6 @@
+boom!
+boom!
+11
+12
+0
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c	(revision 331)
@@ -0,0 +1,116 @@
+#include <stdio.h>
+
+int f(void)
+{
+  return 5;
+}
+
+void test1()
+{
+  int count = 10;
+  void *addr[10];
+  for(;count--;) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test2()
+{
+  int count = 10;
+  void *addr[count];
+  for(;count--;) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test3()
+{
+  int count = 10;
+  void *addr[count];
+  while(count--) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test4()
+{
+  int count = 10;
+  void *addr[count];
+  do {
+    int a[f()];
+
+    addr[--count] = a;
+
+    continue;
+  } while (count);
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test5()
+{
+  int count = 10;
+  int a[f()];
+  int c[f()];
+
+  c[0] = 42;
+
+  for(;count--;) {
+    int b[f()];
+    int i;
+    for (i=0; i<f(); i++) {
+      b[i] = count;
+    }
+  }
+
+  if (c[0] == 42) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+int main(void)
+{
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect	(revision 331)
@@ -0,0 +1,5 @@
+OK
+OK
+OK
+OK
+OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c	(revision 331)
@@ -0,0 +1,25 @@
+#include <stdio.h>
+struct wchar {
+    char *data; char mem[];
+};
+struct wint {
+    char *data; int mem[];
+};
+int f1char (void) {
+    char s[9]="nonono";
+    struct wchar q = {"bugs"};
+    return !s[0];
+}
+int f1int (void) {
+    char s[9]="nonono";
+    struct wint q = {"bugs"};
+    return !s[0];
+}
+int main (void) {
+   char s[9]="nonono";
+   static struct wchar q = {"bugs", {'c'}};
+   //printf ("tcc has %s %s\n", s, q.data);
+   if (f1char() || f1int())
+     printf ("bla\n");
+   return !s[0];
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c	(revision 331)
@@ -0,0 +1,43 @@
+/* The following are all valid decls, even though some subtypes
+   are incomplete.  */
+enum E *e;
+const enum E *e1;
+enum E const *e2;
+struct S *s;
+const struct S *s1;
+struct S const *s2;
+
+/* Various strangely looking declarators, which are all valid
+   and have to map to the same numbered typedefs. */
+typedef int (*fptr1)();
+int f1 (int (), int);
+typedef int (*fptr2)(int x);
+int f2 (int (int x), int);
+typedef int (*fptr3)(int);
+int f3 (int (int), int);
+typedef int (*fptr4[4])(int);
+int f4 (int (*[4])(int), int);
+typedef int (*fptr5)(fptr1);
+int f5 (int (int()), fptr1);
+int f1 (fptr1 fp, int i)
+{
+  return (*fp)(i);
+}
+int f2 (fptr2 fp, int i)
+{
+  return (*fp)(i);
+}
+int f3 (fptr3 fp, int i)
+{
+  return (*fp)(i);
+}
+int f4 (fptr4 fp, int i)
+{
+  return (*fp[i])(i);
+}
+int f5 (fptr5 fp, fptr1 i)
+{
+  return fp(i);
+}
+int f8 (int ([4]), int);
+int main () { return 0; }
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c	(revision 331)
@@ -0,0 +1,19 @@
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef union Unaligned16a {
+  uint16_t u;
+  uint8_t b[2];
+} __attribute__((packed)) Unaligned16a;
+
+typedef union __attribute__((packed)) Unaligned16b {
+  uint16_t u;
+  uint8_t b[2];
+} Unaligned16b;
+
+extern void foo (void) __attribute__((stdcall));
+void __attribute__((stdcall)) foo (void)
+{
+}
+
+int main () { return 0; }
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c	(revision 331)
@@ -0,0 +1,9 @@
+#include <stdio.h>
+double Ð¿ÑÐ¸Ð²ÐµÑ=0.1;
+int LefÃ¨vre=2;
+int main(){
+    printf("Ð¿ÑÐ¸Ð²ÐµÑ=%g\n",Ð¿ÑÐ¸Ð²ÐµÑ);
+    printf("LefÃ¨vre=%d\n",LefÃ¨vre);
+    return 0;
+}
+// pcc & tcc only
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect	(revision 331)
@@ -0,0 +1,2 @@
+Ð¿ÑÐ¸Ð²ÐµÑ=0.1
+LefÃ¨vre=2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c	(revision 331)
@@ -0,0 +1,12 @@
+extern int printf(const char *format, ...);
+
+#define ACPI_TYPE_INVALID       0x1E
+#define NUM_NS_TYPES            ACPI_TYPE_INVALID+1
+int array[NUM_NS_TYPES];
+
+#define n 0xe
+int main()
+{
+    printf("n+1 = %d\n", n+1);
+//    printf("n+1 = %d\n", 0xe+1);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect	(revision 331)
@@ -0,0 +1,1 @@
+n+1 = 15
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c	(revision 331)
@@ -0,0 +1,9 @@
+extern int printf (const char *, ...);
+extern void vide(void);
+__asm__("vide: ret");
+
+int main() {
+    vide();
+    printf ("okay\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect	(revision 331)
@@ -0,0 +1,1 @@
+okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c	(revision 331)
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int
+main()
+{
+#if defined(__LLP64__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 4
+	    && sizeof(long long int) == 8
+	    && sizeof(void*) == 8) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __LLP64__\n");
+	}
+#elif defined(__LP64__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 8
+	    && sizeof(long long int) == 8
+	    && sizeof(void*) == 8) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __LP64__\n");
+	}
+#elif defined(__ILP32__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 4
+	    && sizeof(void*) == 4) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __ILP32__\n");
+	}
+#else
+	(void)printf("KO no __*LP*__ defined.\n");
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect	(revision 331)
@@ -0,0 +1,1 @@
+Ok
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c	(revision 331)
@@ -0,0 +1,122 @@
+/* This checks various ways of dead code inside if statements
+   where there are non-obvious ways of how the code is actually
+   not dead due to reachable by labels.  */
+extern int printf (const char *, ...);
+static void kb_wait_1(void)
+{
+  unsigned long timeout = 2;
+  do {
+      /* Here the else arm is a statement expression that's supposed
+         to be suppressed.  The label inside the while would unsuppress
+	 code generation again if not handled correctly.  And that
+	 would wreak havoc to the cond-expression because there's no
+	 jump-around emitted, the whole statement expression really
+	 needs to not generate code (perhaps except useless forward jumps).  */
+      (1 ? 
+       printf("timeout=%ld\n", timeout) :
+       ({
+	int i = 1;
+	while (1)
+	  while (i--)
+	    some_label:
+	      printf("error\n");
+	goto some_label;
+	})
+      );
+      timeout--;
+  } while (timeout);
+}
+int main (void)
+{
+  int i = 1;
+  kb_wait_1();
+
+  /* Simple test of dead code at first sight which isn't actually dead. */
+  if (0) {
+yeah:
+      printf ("yeah\n");
+  } else {
+      printf ("boo\n");
+  }
+  if (i--)
+    goto yeah;
+
+  /* Some more non-obvious uses where the problems are loops, so that even
+     the first loop statements aren't actually dead.  */
+  i = 1;
+  if (0) {
+      while (i--) {
+	  printf ("once\n");
+enterloop:
+	  printf ("twice\n");
+      }
+  }
+  if (i >= 0)
+    goto enterloop;
+
+  /* The same with statement expressions.  One might be tempted to
+     handle them specially by counting if inside statement exprs and
+     not unsuppressing code at loops at all then.
+     See kb_wait_1 for the other side of the medal where that wouldn't work.  */
+  i = ({
+      int j = 1;
+      if (0) {
+	  while (j--) {
+	      printf ("SEonce\n");
+    enterexprloop:
+	      printf ("SEtwice\n");
+	  }
+      }
+      if (j >= 0)
+	goto enterexprloop;
+      j; });
+
+  /* The other two loop forms: */
+  i = 1;
+  if (0) {
+      for (i = 1; i--;) {
+	  printf ("once2\n");
+enterloop2:
+	  printf ("twice2\n");
+      }
+  }
+  if (i > 0)
+    goto enterloop2;
+
+  i = 1;
+  if (0) {
+      do {
+	  printf ("once3\n");
+enterloop3:
+	  printf ("twice3\n");
+      } while (i--);
+  }
+  if (i > 0)
+    goto enterloop3;
+
+  /* And check that case and default labels have the same effect
+     of disabling code suppression.  */
+  i = 41;
+  switch (i) {
+      if (0) {
+	  printf ("error\n");
+      case 42:
+	  printf ("error2\n");
+      case 41:
+	  printf ("caseok\n");
+      }
+  }
+
+  i = 41;
+  switch (i) {
+      if (0) {
+	  printf ("error3\n");
+      default:
+	  printf ("caseok2\n");
+	  break;
+      case 42:
+	  printf ("error4\n");
+      }
+  }
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect	(revision 331)
@@ -0,0 +1,18 @@
+timeout=2
+timeout=1
+boo
+yeah
+twice
+once
+twice
+SEtwice
+SEonce
+SEtwice
+twice2
+once2
+twice2
+twice3
+once3
+twice3
+caseok
+caseok2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c	(revision 331)
@@ -0,0 +1,68 @@
+/* Check some way in where code suppression caused various
+   miscompilations.  */
+extern int printf (const char *, ...);
+typedef unsigned long size_t;
+
+size_t _brk_start, _brk_end;
+void * extend_brk(size_t size, size_t align)
+{
+    size_t mask = align - 1;
+    void *ret = 0;
+
+     do {
+	 if (__builtin_expect(!!(_brk_start == 0), 0))
+	   do {
+	       printf("wrong1\n");
+	   } while (0);
+     } while (0);
+     _brk_end = (_brk_end + mask) & ~mask;
+     ret = (void *)_brk_end;
+     _brk_end += size;
+
+     return ret;
+}
+
+static void get_args (int a, int b)
+{
+  if (a != 1)
+    printf("wrong2\n");
+  else
+    printf("okay\n");
+}
+
+void bla(void)
+{
+  int __ret = 42;
+  ({
+    if (__builtin_expect(!!(0), 0)) {
+      if (__builtin_expect(!!__ret, 0))
+        printf("wrong3\n");
+      int x = !!(__ret);
+    }
+    __ret;
+  });
+  get_args(!!__ret, sizeof(__ret));
+}
+
+_Bool chk(unsigned long addr, unsigned long limit, unsigned long size)
+{
+  _Bool ret;
+  /* This just needs to compile, no runtime test.  (And it doesn't compile
+     only with certain internal checking added that's not committed).  */
+  if (0)
+    ret = 0 != (!!(addr > limit - size));
+}
+
+int main()
+{
+  void *r;
+  _brk_start = 1024;
+  _brk_end = 1024;
+  r = extend_brk (4096, 16);
+  if (!r)
+    printf("wrong4\n");
+  else
+    printf("okay\n");
+  bla();
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect	(revision 331)
@@ -0,0 +1,2 @@
+okay
+okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c	(revision 331)
@@ -0,0 +1,112 @@
+extern int printf(const char *format, ...);
+static void kb_wait_1(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                while (1)
+                    printf("error\n");
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                for (;;)
+                    printf("error\n");
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2_1(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                do {
+                    printf("error\n");
+		} while (1);
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2_2(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                label:
+                    printf("error\n");
+		goto label;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_3(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                int i = 1;
+                goto label;
+                i = i + 2;
+            label:
+                i = i + 3;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_4(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                switch(timeout) {
+                    case 2:
+                        printf("timeout is 2");
+                        break;
+                    case 1:
+                        printf("timeout is 1");
+                        break;
+                    default:
+                        printf("timeout is 0?");
+                        break;
+                };
+                // return;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+int main()
+{
+    printf("begin\n");
+    kb_wait_1();
+    kb_wait_2();
+    kb_wait_2_1();
+    kb_wait_2_2();
+    kb_wait_3();
+    kb_wait_4();
+    printf("end\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect	(revision 331)
@@ -0,0 +1,14 @@
+begin
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+end
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c	(revision 331)
@@ -0,0 +1,284 @@
+typedef unsigned char u8;
+typedef struct {} empty_s;
+struct contains_empty {
+    u8 a;
+    empty_s empty;
+    u8 b;
+};
+struct contains_empty ce = { { (1) }, (empty_s){}, 022, };
+/* The following decl of 'q' would demonstrate the TCC bug in init_putv when
+   handling copying compound literals.  (Compound literals
+   aren't acceptable constant initializers in isoc99, but
+   we accept them like gcc, except for this case)
+//char *q = (char *){ "trara" }; */
+struct SS {u8 a[3], b; };
+struct SS sinit16[] = { { 1 }, 2 };
+struct S
+{
+  u8 a,b;
+  u8 c[2];
+};
+
+struct T
+{
+  u8 s[16];
+  u8 a;
+};
+
+struct U
+{
+  u8 a;
+  struct S s;
+  u8 b;
+  struct T t;
+};
+
+struct V
+{
+  struct S s;
+  struct T t;
+  u8 a;
+};
+
+struct W
+{
+  struct V t;
+  struct S s[];
+};
+
+struct S gs = ((struct S){1, 2, 3, 4});
+struct S gs2 = {1, 2, {3, 4}};
+struct T gt = {"hello", 42};
+struct U gu = {3, 5,6,7,8, 4, "huhu", 43};
+struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}};
+/* Optional braces around scalar initializers.  Accepted, but with
+   a warning.  */
+struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}};
+/* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+struct U gu4 = { 3, {5,6,7,},  5, { "bla", {44}} };
+/* Superfluous braces and useless parens around values */
+struct S gs3 = { (1), {(2)}, {(((3))), {4}}};
+/* Superfluous braces, and leaving out braces for V.t, plus cast */
+struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46};
+/* Compound literal */
+struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48};
+/* Parens around compound literal */
+struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50};
+/* Initialization of a flex array member (warns in GCC) */
+struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
+
+union UU {
+    u8 a;
+    u8 b;
+};
+struct SU {
+    union UU u;
+    u8 c;
+};
+struct SU gsu = {5,6};
+
+/* Unnamed struct/union members aren't ISO C, but it's a widely accepted
+   extension.  See below for further extensions to that under -fms-extension.*/
+union UV {
+    struct {u8 a,b;};
+    struct S s;
+};
+union UV guv = {{6,5}};
+union UV guv2 = {{.b = 7, .a = 8}};
+union UV guv3 = {.b = 8, .a = 7};
+
+/* Under -fms-extensions also the following is valid:
+union UV2 {
+    struct Anon {u8 a,b;};    // unnamed member, but tagged struct, ...
+    struct S s;
+};
+struct Anon gan = { 10, 11 }; // ... which makes it available here.
+union UV2 guv4 = {{4,3}};     // and the other inits from above as well
+*/
+
+struct in6_addr {
+    union {
+	u8 u6_addr8[16];
+	unsigned short u6_addr16[8];
+    } u;
+};
+struct flowi6 {
+    struct in6_addr saddr, daddr;
+};
+struct pkthdr {
+    struct in6_addr daddr, saddr;
+};
+struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } };
+
+struct Wrap {
+    void *func;
+};
+int global;
+void inc_global (void)
+{
+  global++;
+}
+
+struct Wrap global_wrap[] = {
+    ((struct Wrap) {inc_global}),
+    inc_global,
+};
+
+#include <stdio.h>
+void print_ (const char *name, const u8 *p, long size)
+{
+  printf ("%s:", name);
+  while (size--) {
+      printf (" %x", *p++);
+  }
+  printf ("\n");
+}
+#define print(x) print_(#x, (u8*)&x, sizeof (x))
+#if 1
+void foo (struct W *w, struct pkthdr *phdr_)
+{
+  struct S ls = {1, 2, 3, 4};
+  struct S ls2 = {1, 2, {3, 4}};
+  struct T lt = {"hello", 42};
+  struct U lu = {3, 5,6,7,8, 4, "huhu", 43};
+  struct U lu1 = {3, ls, 4, {"huhu", 43}};
+  struct U lu2 = {3, (ls), 4, {"huhu", 43}};
+  const struct S *pls = &ls;
+  struct S ls21 = *pls;
+  struct U lu22 = {3, *pls, 4, {"huhu", 43}};
+  /* Incomplete bracing.  */
+  struct U lu21 = {3, ls, 4, "huhu", 43};
+  /* Optional braces around scalar initializers.  Accepted, but with
+     a warning.  */
+  struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}};
+  /* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+  struct U lu4 = { 3, {5,6,7,},  5, { "bla", 44} };
+  /* Superfluous braces and useless parens around values */
+  struct S ls3 = { (1), (2), {(((3))), 4}};
+  /* Superfluous braces, and leaving out braces for V.t, plus cast */
+  struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46};
+  /* Compound literal */
+  struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48};
+  /* Parens around compound literal */
+  struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};
+  const struct pkthdr *phdr = phdr_;
+  struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr };
+  int elt = 0x42;
+  /* Range init, overlapping */
+  struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 };
+  print(ls);
+  print(ls2);
+  print(lt);
+  print(lu);
+  print(lu1);
+  print(lu2);
+  print(ls21);
+  print(lu21);
+  print(lu22);
+  print(lu3);
+  print(lu4);
+  print(ls3);
+  print(lv);
+  print(lv2);
+  print(lv3);
+  print(lt2);
+  print(flow);
+}
+#endif
+
+void test_compound_with_relocs (void)
+{
+  struct Wrap local_wrap[] = {
+      ((struct Wrap) {inc_global}),
+      inc_global,
+  };
+  void (*p)(void);
+  p = global_wrap[0].func; p();
+  p = global_wrap[1].func; p();
+  p = local_wrap[0].func; p();
+  p = local_wrap[1].func; p();
+}
+
+void sys_ni(void) { printf("ni\n"); }
+void sys_one(void) { printf("one\n"); }
+void sys_two(void) { printf("two\n"); }
+void sys_three(void) { printf("three\n"); }
+typedef void (*fptr)(void);
+const fptr table[3] = {
+    [0 ... 2] = &sys_ni,
+    [0] = sys_one,
+    [1] = sys_two,
+    [2] = sys_three,
+};
+
+void test_multi_relocs(void)
+{
+  int i;
+  for (i = 0; i < sizeof(table)/sizeof(table[0]); i++)
+    table[i]();
+}
+
+
+/* Following is from GCC gcc.c-torture/execute/20050613-1.c.  */
+
+struct SEA { int i; int j; int k; int l; };
+struct SEB { struct SEA a; int r[1]; };
+struct SEC { struct SEA a; int r[0]; };
+struct SED { struct SEA a; int r[]; };
+
+static void
+test_correct_filling (struct SEA *x)
+{
+  static int i;
+  if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0)
+    printf("sea_fill%d: wrong\n", i);
+  else
+    printf("sea_fill%d: okay\n", i);
+  i++;
+}
+
+int
+test_zero_init (void)
+{
+  /* The peculiarity here is that only a.j is initialized.  That
+     means that all other members must be zero initialized.  TCC
+     once didn't do that for sub-level designators.  */
+  struct SEB b = { .a.j = 5 };
+  struct SEC c = { .a.j = 5 };
+  struct SED d = { .a.j = 5 };
+  test_correct_filling (&b.a);
+  test_correct_filling (&c.a);
+  test_correct_filling (&d.a);
+  return 0;
+}
+
+
+int main()
+{
+  print(ce);
+  print(gs);
+  print(gs2);
+  print(gt);
+  print(gu);
+  print(gu2);
+  print(gu3);
+  print(gu4);
+  print(gs3);
+  print(gv);
+  print(gv2);
+  print(gv3);
+  print(sinit16);
+  print(gw);
+  print(gsu);
+  print(guv);
+  print(guv.b);
+  print(guv2);
+  print(guv3);
+  print(phdr);
+  foo(&gw, &phdr);
+  //printf("q: %s\n", q);
+  test_compound_with_relocs();
+  test_multi_relocs();
+  test_zero_init();
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect	(revision 331)
@@ -0,0 +1,43 @@
+ce: 1 12
+gs: 1 2 3 4
+gs2: 1 2 3 4
+gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+gs3: 1 2 3 4
+gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
+sinit16: 1 0 0 0 2 0 0 0
+gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+gsu: 5 6
+guv: 6 5 0 0
+guv.b: 5
+guv2: 8 7 0 0
+guv3: 7 8 0 0
+phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0
+ls: 1 2 3 4
+ls2: 1 2 3 4
+lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+ls21: 1 2 3 4
+lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+ls3: 1 2 3 4
+lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32
+lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1
+flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0
+one
+two
+three
+sea_fill0: okay
+sea_fill1: okay
+sea_fill2: okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c	(revision 331)
@@ -0,0 +1,15 @@
+int printf(const char *, ...);
+char t[] = "012345678";
+
+int main(void)
+{
+    char *data = t;
+    unsigned long long r = 4;
+    unsigned a = 5;
+    unsigned long long b = 12;
+
+    *(unsigned*)(data + r) += a - b;
+
+    printf("data = \"%s\"\n", data);
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect	(revision 331)
@@ -0,0 +1,1 @@
+data = "0123-5678"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c	(revision 331)
@@ -0,0 +1,57 @@
+/* This checks if enums needing 8 bit but only having positive
+   values are correctly zero extended (instead of sign extended)
+   when stored into/loaded from a 8 bit bit-field of enum type (which
+   itself is implementation defined, so isn't necessarily supported by all
+   other compilers).  */
+enum tree_code {
+  SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */
+  LAST_AND_UNUSED_TREE_CODE
+};
+typedef union tree_node *tree;
+struct tree_common
+{
+  union tree_node *chain;
+  union tree_node *type;
+  enum tree_code code : 8;
+  unsigned side_effects_flag : 1;
+};
+union tree_node
+{
+  struct tree_common common;
+ };
+enum c_tree_code {
+  C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
+  STMT_EXPR,
+  LAST_C_TREE_CODE
+};
+enum cplus_tree_code {
+  CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,
+  AMBIG_CONV,
+  LAST_CPLUS_TREE_CODE
+};
+
+extern int printf(const char *, ...);
+int blah(){return 0;}
+
+int convert_like_real (tree convs)
+{
+  switch (((enum tree_code) (convs)->common.code))
+    {
+    case AMBIG_CONV: /* This has bit 7 set, which must not be the sign
+			bit in tree_common.code, i.e. the bitfield must
+			be somehow marked unsigned.  */
+      return blah();
+    default:
+      break;
+    };
+   printf("unsigned enum bit-fields broken\n");
+}
+
+int main()
+{
+  union tree_node convs;
+
+  convs.common.code = AMBIG_CONV;
+  convert_like_real (&convs);
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c	(revision 331)
@@ -0,0 +1,71 @@
+/* integer promotion */
+
+int printf(const char*, ...);
+#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? "  " : "un", #s);
+
+int main (void)
+{
+    struct {
+        unsigned ub:3;
+        unsigned u:32;
+        unsigned long long ullb:35;
+        unsigned long long ull:64;
+        unsigned char c;
+    } s = { 1, 1, 1 };
+
+    promote(s.ub);
+    promote(s.u);
+    promote(s.ullb);
+    promote(s.ull);
+    promote(s.c);
+    printf("\n");
+
+    promote((1 ? s.ub : 1));
+    promote((1 ? s.u : 1));
+    promote((1 ? s.ullb : 1));
+    promote((1 ? s.ull : 1));
+    promote((1 ? s.c : 1));
+    printf("\n");
+
+    promote(s.ub << 1);
+    promote(s.u << 1);
+    promote(s.ullb << 1);
+    promote(s.ull << 1);
+    promote(s.c << 1);
+    printf("\n");
+
+    promote(+s.ub);
+    promote(+s.u);
+    promote(+s.ullb);
+    promote(+s.ull);
+    promote(+s.c);
+    printf("\n");
+
+    promote(-s.ub);
+    promote(-s.u);
+    promote(-s.ullb);
+    promote(-s.ull);
+    promote(-s.c);
+    printf("\n");
+
+    promote(~s.ub);
+    promote(~s.u);
+    promote(~s.ullb);
+    promote(~s.ull);
+    promote(~s.c);
+    printf("\n");
+
+    promote(!s.ub);
+    promote(!s.u);
+    promote(!s.ullb);
+    promote(!s.ull);
+    promote(!s.c);
+    printf("\n");
+
+    promote(+(unsigned)s.ub);
+    promote(-(unsigned)s.ub);
+    promote(~(unsigned)s.ub);
+    promote(!(unsigned)s.ub);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect	(revision 331)
@@ -0,0 +1,46 @@
+   signed : s.ub
+ unsigned : s.u
+   signed : s.ullb
+ unsigned : s.ull
+   signed : s.c
+
+   signed : (1 ? s.ub : 1)
+ unsigned : (1 ? s.u : 1)
+   signed : (1 ? s.ullb : 1)
+ unsigned : (1 ? s.ull : 1)
+   signed : (1 ? s.c : 1)
+
+   signed : s.ub << 1
+ unsigned : s.u << 1
+   signed : s.ullb << 1
+ unsigned : s.ull << 1
+   signed : s.c << 1
+
+   signed : +s.ub
+ unsigned : +s.u
+   signed : +s.ullb
+ unsigned : +s.ull
+   signed : +s.c
+
+   signed : -s.ub
+ unsigned : -s.u
+   signed : -s.ullb
+ unsigned : -s.ull
+   signed : -s.c
+
+   signed : ~s.ub
+ unsigned : ~s.u
+   signed : ~s.ullb
+ unsigned : ~s.ull
+   signed : ~s.c
+
+   signed : !s.ub
+   signed : !s.u
+   signed : !s.ullb
+   signed : !s.ull
+   signed : !s.c
+
+ unsigned : +(unsigned)s.ub
+ unsigned : -(unsigned)s.ub
+ unsigned : ~(unsigned)s.ub
+   signed : !(unsigned)s.ub
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c	(revision 331)
@@ -0,0 +1,64 @@
+#include <stdio.h>
+
+const int a = 0;
+
+struct a {
+	int a;
+};
+
+struct b {
+	int a;
+};
+
+int a_f()
+{
+	return 20;
+}
+
+int b_f()
+{
+	return 10;
+}
+
+typedef int int_type1;
+
+#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123);
+
+int main()
+{
+	int i = 0;
+	signed long int l = 2;
+	struct b titi;
+	const int * const ptr;
+	const char *ti;
+	int_type1 i2;
+
+	i = _Generic(a, int: a_f, const int: b_f)();
+	printf("%d\n", i);
+	i = _Generic(a, int: a_f() / 2, const int: b_f() / 2);
+	printf("%d\n", i);
+	i = _Generic(ptr, int *:1, int * const:2, default:20);
+	printf("%d\n", i);
+	i = gen_sw(a);
+	printf("%d\n", i);
+	i = _Generic(titi, struct a:1, struct b:2, default:20);
+	printf("%d\n", i);
+	i = _Generic(i2, char: 1, int : 0);
+	printf("%d\n", i);
+	i = _Generic(a, char:1, int[4]:2, default:5);
+	printf("%d\n", i);
+	i = _Generic(17, int :1, int **:2);
+	printf("%d\n", i);
+	i = _Generic(17L, int :1, long :2, long long : 3);
+	printf("%d\n", i);
+	i = _Generic("17, io", char *: 3, const char *: 1);
+	printf("%d\n", i);
+	i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3,
+		     const signed char *:2);
+	printf("%d\n", i);
+	printf("%s\n", _Generic(i + 2L, long: "long", int: "int",
+				long long: "long long"));
+	i = _Generic(l, long: 1, int: 2);
+	printf("%d\n", i);
+	return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect	(revision 331)
@@ -0,0 +1,13 @@
+20
+10
+20
+123
+2
+0
+5
+1
+2
+3
+4
+long
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c	(revision 331)
@@ -0,0 +1,218 @@
+/* ----------------------------------------------------------------------- */
+#if TEST == 1
+{
+    struct M P A __s
+    {
+        unsigned x : 12;
+        unsigned char y : 7;
+        unsigned z : 28;
+        unsigned a: 4;
+        unsigned b: 5;
+    };
+    TEST_STRUCT(0x333,0x44,0x555555,6,7);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 2
+{
+    struct M P __s
+    {
+        int x: 12;
+        char y: 6;
+        long long z:63;
+        A char a:4;
+        long long b:2;
+
+    };
+    TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 3
+{
+    struct M P __s
+    {
+        unsigned x:5, y:5, :0, z:5; char a:5; A short b:5;
+    };
+    TEST_STRUCT(21,23,25,6,14);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 4
+{
+    struct M P __s {
+        int x : 3;
+        int : 2;
+        int y : 1;
+        int : 0;
+        int z : 5;
+        int a : 7;
+        unsigned int b : 7;
+    };
+    TEST_STRUCT(3,1,15,120,120);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 5
+{
+    struct M P __s {
+        long long x : 45;
+        long long : 2;
+        long long y : 30;
+        unsigned long long z : 38;
+        char a; short b;
+    };
+    TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 6
+{
+    struct M P __s {
+	int a;
+	signed char b;
+	int x : 12, y : 4, : 0, : 4, z : 3;
+	char d;
+    };
+    TEST_STRUCT(1,2,3,4,-3);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif defined PACK
+
+#if PACK
+# pragma pack(push,1)
+# define P //_P
+#else
+# define P
+#endif
+
+printf("\n\n" + 2*top);
+#define TEST 1
+#include SELF
+top = 0;
+#define TEST 2
+#include SELF
+#define TEST 3
+#include SELF
+#define TEST 4
+#include SELF
+#define TEST 5
+#include SELF
+#define TEST 6
+#include SELF
+
+#if PACK
+# pragma pack(pop)
+#endif
+
+#undef P
+#undef PACK
+
+/* ----------------------------------------------------------------------- */
+#elif defined ALIGN
+
+#if ALIGN
+# define A _A(16)
+#else
+# define A
+#endif
+
+#define PACK 0
+#include SELF
+#define PACK 1
+#include SELF
+
+#undef A
+#undef ALIGN
+
+/* ----------------------------------------------------------------------- */
+#elif defined MS_BF
+
+#if MS_BF
+# ifdef __TINYC__
+#  pragma comment(option, "-mms-bitfields")
+# elif defined __GNUC__
+#  define M __attribute__((ms_struct))
+# endif
+#else
+# ifdef __TINYC__
+#  pragma comment(option, "-mno-ms-bitfields")
+# elif defined __GNUC__
+#  define M __attribute__((gcc_struct))
+# endif
+#endif
+#ifndef M
+# define M
+#endif
+
+#define ALIGN 0
+#include SELF
+#define ALIGN 1
+#include SELF
+
+#undef M
+#undef MS_BF
+
+/* ----------------------------------------------------------------------- */
+#else
+
+#include <stdio.h>
+#include <string.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+void dump(void *p, int s)
+{
+    int i;
+    for (i = s; --i >= 0;)
+        printf("%02X", ((unsigned char*)p)[i]);
+    printf("\n");
+}
+
+#define pv(m) \
+    printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
+
+#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
+        struct __s _s, *s = & _s; \
+        printf("\n---- TEST %d%s%s%s ----\n" + top, \
+            TEST, MS_BF?" - MS-BITFIELDS":"", \
+            PACK?" - PACKED":"", \
+            ALIGN?" - WITH ALIGN":""); \
+        memset(s, 0, sizeof *s); \
+        s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
+        printf("bits in use : "), dump(s, sizeof *s); \
+        s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
+        printf("bits as set : "), dump(s, sizeof *s); \
+        printf("values      :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
+        printf("align/size  : %d %d\n", alignof(struct __s),sizeof(struct __s)); \
+    }
+
+#ifdef _MSC_VER
+# define _A(n) __declspec(align(n))
+# define _P
+# define alignof(x) __alignof(x)
+#else
+# define _A(n) __attribute__((aligned(n)))
+# define _P __attribute__((packed))
+# define alignof(x) __alignof__(x)
+#endif
+
+#ifndef MS_BITFIELDS
+# define MS_BITFIELDS 0
+#endif
+
+#define SELF "95_bitfields.c"
+
+int top = 1;
+
+int main()
+{
+#define MS_BF MS_BITFIELDS
+#include SELF
+    return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+#endif
+#undef TEST
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect	(revision 331)
@@ -0,0 +1,149 @@
+---- TEST 1 ----
+bits in use : 0000001FFFFFFFFF007F0FFF
+bits as set : 000000076055555500440333
+values      : 333 44 555555 06 07
+align/size  : 4 12
+
+---- TEST 2 ----
+bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 0000000000000025123456789ABCDEF000000000001E0003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 8 24
+
+---- TEST 3 ----
+bits in use : 001F1F1F000003FF
+bits as set : 000E0619000002F5
+values      : 15 17 19 06 0e
+align/size  : 4 8
+
+---- TEST 4 ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 8 24
+
+---- TEST 6 ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 12
+
+
+
+---- TEST 1 - PACKED ----
+bits in use : FFFFFFFFFFFFFF
+bits as set : 3B02AAAAAC4333
+values      : 333 44 555555 06 07
+align/size  : 1 7
+
+---- TEST 2 - PACKED ----
+bits in use : 7FFFFFFFFFFFFFFFFFFFFF
+bits as set : 4A48D159E26AF37BC1E003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 1 11
+
+---- TEST 3 - PACKED ----
+bits in use : 7FFF000003FF
+bits as set : 38D9000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 6
+
+---- TEST 4 - PACKED ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 7
+
+---- TEST 5 - PACKED ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 1 18
+
+---- TEST 6 - PACKED ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 10
+
+
+
+---- TEST 1 - WITH ALIGN ----
+bits in use : 000000000000001FFFFFFFFF007F0FFF
+bits as set : 00000000000000076055555500440333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 16 32
+
+---- TEST 3 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 32
+
+---- TEST 4 - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - WITH ALIGN ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 8 24
+
+---- TEST 6 - WITH ALIGN ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 12
+
+
+
+---- TEST 1 - PACKED - WITH ALIGN ----
+bits in use : 000000000000000000FFFFFFFFFFFFFF
+bits as set : 0000000000000000003B02AAAAAC4333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - PACKED - WITH ALIGN ----
+bits in use : 3F01FFFFFFFFFFFFFFFFFFFF
+bits as set : 250048D159E26AF37BC1E003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 1 12
+
+---- TEST 3 - PACKED - WITH ALIGN ----
+bits in use : 1F03FF000003FF
+bits as set : 0E00D9000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 7
+
+---- TEST 4 - PACKED - WITH ALIGN ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 7
+
+---- TEST 5 - PACKED - WITH ALIGN ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 1 18
+
+---- TEST 6 - PACKED - WITH ALIGN ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c	(revision 331)
@@ -0,0 +1,2 @@
+#define MS_BITFIELDS 1
+#include "95_bitfields.c"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect	(revision 331)
@@ -0,0 +1,149 @@
+---- TEST 1 - MS-BITFIELDS ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values      : 333 44 555555 06 07
+align/size  : 4 16
+
+---- TEST 2 - MS-BITFIELDS ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 8 32
+
+---- TEST 3 - MS-BITFIELDS ----
+bits in use : 001F001F0000001F000003FF
+bits as set : 000E000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 4 12
+
+---- TEST 4 - MS-BITFIELDS ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - MS-BITFIELDS ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 8 32
+
+---- TEST 6 - MS-BITFIELDS ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED ----
+bits in use : 0000001FFFFFFFFF7F00000FFF
+bits as set : 00000007605555554400000333
+values      : 333 44 555555 06 07
+align/size  : 1 13
+
+---- TEST 2 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205123456789ABCDEF01E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 1 22
+
+---- TEST 3 - MS-BITFIELDS - PACKED ----
+bits in use : 001F1F0000001F000003FF
+bits as set : 000E0600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 11
+
+---- TEST 4 - MS-BITFIELDS - PACKED ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 14
+
+
+
+---- TEST 1 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 16 32
+
+---- TEST 3 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 32
+
+---- TEST 4 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 8 32
+
+---- TEST 6 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0000000000001FFFFFFFFF7F00000FFF
+bits as set : 00000000000007605555554400000333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205000000123456789ABCDEF01E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 16 25
+
+---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 001F000000000000001F0000001F000003FF
+bits as set : 000E000000000000000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 18
+
+---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 14
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c	(revision 331)
@@ -0,0 +1,84 @@
+/*****************************************************************************/
+/* test 'nodata_wanted' data output suppression */
+
+#if defined test_static_data_error
+void foo() {
+    if (1) {
+	static short w = (int)&foo; /* initializer not computable */
+    }
+}
+
+#elif defined test_static_nodata_error
+void foo() {
+    if (0) {
+	static short w = (int)&foo; /* initializer not computable */
+    }
+}
+
+#elif defined test_global_data_error
+void foo();
+static short w = (int)&foo; /* initializer not computable */
+
+
+#elif defined test_local_data_noerror
+void foo() {
+    short w = &foo; /* 2 cast warnings */
+}
+
+#elif defined test_data_suppression_off || defined test_data_suppression_on
+
+#if defined test_data_suppression_on
+# define SKIP 1
+#else
+# define SKIP 0
+#endif
+
+#include <stdio.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+int main()
+{
+    __label__ ts0, te0, ts1, te1;
+    int tl, dl;
+
+    static char ds0 = 0;
+    static char de0 = 0;
+    /* get reference size of empty jmp */
+ts0:;
+    if (!SKIP) {}
+te0:;
+    dl = -(&de0 - &ds0);
+    tl = -(&&te0 - &&ts0);
+
+    /* test data and code suppression */
+    static char ds1 = 0;
+ts1:;
+    if (!SKIP) {
+        static void *p = (void*)&main;
+        static char cc[] = "static string";
+        static double d = 8.0;
+
+        static struct __attribute__((packed)) {
+            unsigned x : 12;
+            unsigned char y : 7;
+            unsigned z : 28, a: 4, b: 5;
+        } s = { 0x333,0x44,0x555555,6,7 };
+
+        printf("data:\n");
+        printf("  %d - %.1f - %.1f - %s - %s\n",
+            sizeof 8.0, 8.0, d, __FUNCTION__, cc);
+        printf("  %x %x %x %x %x\n",
+            s.x, s.y, s.z, s.a, s.b);
+    }
+te1:;
+    static char de1 = 0;
+
+    dl += &de1 - &ds1;
+    tl += &&te1 - &&ts1;
+    printf("size of data/text:\n  %s/%s\n",
+        dl ? "non-zero":"zero", tl ? "non-zero":"zero");
+    /*printf("# %d/%d\n", dl, tl);*/
+}
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect	(revision 331)
@@ -0,0 +1,23 @@
+[test_static_data_error]
+96_nodata_wanted.c:7: error: initializer element is not computable at load time
+
+[test_static_nodata_error]
+96_nodata_wanted.c:14: error: initializer element is not computable at load time
+
+[test_global_data_error]
+96_nodata_wanted.c:20: error: initializer element is not computable at load time
+
+[test_local_data_noerror]
+96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
+96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
+
+[test_data_suppression_off]
+data:
+  8 - 8.0 - 8.0 - main - static string
+  333 44 555555 6 7
+size of data/text:
+  non-zero/non-zero
+
+[test_data_suppression_on]
+size of data/text:
+  zero/zero
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c	(revision 331)
@@ -0,0 +1,12 @@
+// this file contains BMP chars encoded in UTF-8
+#include <stdio.h>
+#include <wchar.h>
+
+int main()
+{
+    wchar_t s[] = L"hello$$ä½ å¥½Â¢Â¢ä¸çâ¬â¬world";
+    wchar_t *p;
+    for (p = s; *p; p++) printf("%04X ", (unsigned) *p);
+    printf("\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect	(revision 331)
@@ -0,0 +1,1 @@
+0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c	(revision 331)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+asm (
+    ".text;"
+    ".globl _us;.globl _ss;.globl _uc;.globl _sc;"
+    "_us:;_ss:;_uc:;_sc:;"
+    "movl $0x1234ABCD, %eax;"
+	"ret;"
+);
+
+#if 1
+#define us _us
+#define ss _ss
+#define uc _uc
+#define sc _sc
+#endif
+
+int main()
+{
+    unsigned short us(void);
+    short ss(void);
+    unsigned char uc(void);
+    signed char sc(void);
+
+    unsigned short (*fpus)(void) = us;
+    short (*fpss)(void) = ss;
+    unsigned char (*fpuc)(void) = uc;
+    signed char (*fpsc)(void) = sc;
+
+    printf("%08X %08X\n", us() + 1, fpus() + 1);
+    printf("%08X %08X\n", ss() + 1, fpss() + 1);
+    printf("%08X %08X\n", uc() + 1, fpuc() + 1);
+    printf("%08X %08X\n", sc() + 1, fpsc() + 1);
+    printf("\n");
+    printf("%08X %08X\n", fpus() + 1, us() + 1);
+    printf("%08X %08X\n", fpss() + 1, ss() + 1);
+    printf("%08X %08X\n", fpuc() + 1, uc() + 1);
+    printf("%08X %08X\n", fpsc() + 1, sc() + 1);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect	(revision 331)
@@ -0,0 +1,9 @@
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
+
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c	(revision 331)
@@ -0,0 +1,276 @@
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef _WIN32
+#define __fastcall __attribute((fastcall))
+#endif
+
+#if 1
+#define SYMBOL(x) _##x
+#else
+#define SYMBOL(x) x
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TRAP FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// if you cast 'TRAP' to a function pointer and call it,
+//   it will save all 8 registers,
+//   and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'),
+//   in C-code you can pop DWORDs from stack and modify registers
+//
+
+void *SYMBOL(trap_handler);
+
+extern unsigned char SYMBOL(trap)[];
+asm (
+    ".text;"
+    "_trap:;"
+    "pushl %esp;"
+    "pusha;"
+    "addl $0x4, 0xc(%esp);"
+    "pushl %esp;"
+    "call *_trap_handler;"
+    "addl $0x4, %esp;"
+    "movl 0xc(%esp), %eax;"
+    "movl %eax, 0x20(%esp);"
+    "popa;"
+    "popl %esp;"
+	"ret;"
+);
+
+struct trapframe {
+    unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax;
+};
+
+
+#define M_FLOAT(addr) (*(float *)(addr))
+#define M_DWORD(addr) (*(unsigned *)(addr))
+#define M_WORD(addr) (*(unsigned short *)(addr))
+#define M_BYTE(addr) (*(unsigned char *)(addr))
+#define R_EAX ((tf)->eax)
+#define R_ECX ((tf)->ecx)
+#define R_EDX ((tf)->edx)
+#define R_EBX ((tf)->ebx)
+#define R_ESP ((tf)->esp)
+#define R_EBP ((tf)->ebp)
+#define R_ESI ((tf)->esi)
+#define R_EDI ((tf)->edi)
+
+#define ARG(x) (M_DWORD(R_ESP + (x) * 4))
+
+#define RETN(x) do { \
+    M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \
+    R_ESP += (x); \
+} while (0)
+
+#define DUMP() do { \
+    unsigned i; \
+    printf("EAX: %08X\n", R_EAX); \
+    printf("ECX: %08X\n", R_ECX); \
+    printf("EDX: %08X\n", R_EDX); \
+    printf("EBX: %08X\n", R_EBX); \
+    printf("ESP: %08X\n", R_ESP); \
+    printf("EBP: %08X\n", R_EBP); \
+    printf("ESI: %08X\n", R_ESI); \
+    printf("EDI: %08X\n", R_EDI); \
+    printf("\n"); \
+    printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \
+    for (i = 1; i <= 8; i++) { \
+        printf("[ARG%4d]: %08X\n", i, ARG(i)); \
+    } \
+} while (0)
+
+#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x))
+#define TRAP ((void *) &SYMBOL(trap))
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                SAFECALL FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// this framework will convert any calling convention to cdecl
+// usage: first set call target with 'SET_SAFECALL_TARGET(x)'
+//        then cast 'SAFECALL' to target function pointer type and invoke it
+//        after calling, 'ESPDIFF' is the difference of old and new esp
+
+void *SYMBOL(sc_call_target);
+unsigned SYMBOL(sc_retn_addr);
+unsigned SYMBOL(sc_old_esp);
+unsigned SYMBOL(sc_new_esp);
+
+extern unsigned char SYMBOL(safecall)[];
+asm (
+    ".text;"
+    "_safecall:;"
+    "popl _sc_retn_addr;"
+    "movl %esp, _sc_old_esp;"
+    "call *_sc_call_target;"
+    "movl %esp, _sc_new_esp;"
+    "movl _sc_old_esp, %esp;"
+	"jmp *_sc_retn_addr;"
+);
+
+#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x))
+#define SAFECALL ((void *) &SYMBOL(safecall))
+#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp))
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TEST FASTCALL INVOKE
+/////////////////////////////////////////////////////////////////////////
+
+void check_fastcall_invoke_0(struct trapframe *tf)
+{
+    //DUMP();
+    RETN(0);
+}
+
+void check_fastcall_invoke_1(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    RETN(0);
+}
+void check_fastcall_invoke_2(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    RETN(0);
+}
+void check_fastcall_invoke_3(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    RETN(1*4);
+}
+void check_fastcall_invoke_4(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    assert(ARG(2) == 0x44444444);
+    RETN(2*4);
+}
+
+void check_fastcall_invoke_5(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    assert(ARG(2) == 0x44444444);
+    assert(ARG(3) == 0x55555555);
+    RETN(3*4);
+}
+
+void test_fastcall_invoke()
+{
+    SET_TRAP_HANDLER(check_fastcall_invoke_0);
+    ((void __fastcall (*)(void)) TRAP)();
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_1);
+    ((void __fastcall (*)(unsigned)) TRAP)(0x11111111);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_2);
+    ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_3);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_4);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_5);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TEST FUNCTION CODE GENERATION
+/////////////////////////////////////////////////////////////////////////
+
+int __fastcall check_fastcall_espdiff_0(void)
+{
+    return 0;
+}
+
+int __fastcall check_fastcall_espdiff_1(int a)
+{
+    return a;
+}
+
+int __fastcall check_fastcall_espdiff_2(int a, int b)
+{
+    return a + b;
+}
+
+int __fastcall check_fastcall_espdiff_3(int a, int b, int c)
+{
+    return a + b + c;
+}
+
+int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d)
+{
+    return a + b + c + d;
+}
+
+int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e)
+{
+    return a + b + c + d + e;
+}
+
+void test_fastcall_espdiff()
+{
+    int x;
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_0);
+    x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)();
+    assert(x == 0);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_1);
+    x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1);
+    assert(x == 1);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_2);
+    x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2);
+    assert(x == 1 + 2);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_3);
+    x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3);
+    assert(x == 1 + 2 + 3);
+    assert(ESPDIFF == 1*4);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_4);
+    x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4);
+    assert(x == 1 + 2 + 3 + 4);
+    assert(ESPDIFF == 2*4);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_5);
+    x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5);
+    assert(x == 1 + 2 + 3 + 4 + 5);
+    assert(ESPDIFF == 3*4);
+}
+
+int main()
+{
+#define N 10000
+    int i;
+
+    for (i = 1; i <= N; i++) {
+        test_fastcall_espdiff();
+    }
+
+    for (i = 1; i <= N; i++) {
+        test_fastcall_invoke();
+    }
+
+    puts("TEST OK");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect	(revision 331)
@@ -0,0 +1,1 @@
+TEST OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE	(revision 331)
@@ -0,0 +1,37 @@
+The tests in this directory are either directly copied from the picoc project or
+are subsequently modified and added to for the purpose of TinyCC project. All
+these modifications are licensed under the same terms as TinyCC as specified in
+the file COPYING.
+
+=== picoc license ===
+
+Copyright (c) 2009-2011, Zik Saleeba
+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.
+      
+    * Neither the name of the Zik Saleeba nor the names of its 
+      contributors may be used to endorse or promote products derived 
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE 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.
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile	(revision 331)
@@ -0,0 +1,112 @@
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/tests2
+VPATH = $(SRC)
+
+TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c))))
+
+# some tests do not pass on all platforms, remove them for now
+SKIP = 34_array_assignment.test # array assignment is not in C standard
+ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ SKIP += 22_floating_point.test
+endif
+ifdef CONFIG_OSX
+ SKIP += 40_stdio.test 42_function_pointer.test
+ FLAGS += -w
+endif
+ifeq ($(ARCH),x86_64)
+ SKIP += 73_arm64.test
+endif
+ifeq (,$(filter i386,$(ARCH)))
+ SKIP += 98_al_ax_extend.test 99_fastcall.test
+endif
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ SKIP += 85_asm-outside-function.test
+endif
+ifeq (-$(findstring gcc,$(CC))-,--)
+ SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
+endif
+ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
+ SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows
+endif
+
+# Some tests might need arguments
+ARGS =
+31_args.test : ARGS = arg1 arg2 arg3 arg4 arg5
+46_grep.test : ARGS = '[^* ]*[:a:d: ]+\:\*-/: $$' $(SRC)/46_grep.c
+
+# And some tests don't test the right thing with -run
+NORUN =
+42_function_pointer.test : NORUN = true
+
+# Some tests might need different flags
+FLAGS =
+76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
+
+# These tests run several snippets from the same file one by one
+60_errors_and_warnings.test : FLAGS += -dt
+96_nodata_wanted.test : FLAGS += -dt
+
+# Always generate certain .expects (don't put these in the GIT),
+GEN-ALWAYS =
+# GEN-ALWAYS += 95_bitfields.expect # does not work
+
+# using the ms compiler for the really ms-compatible bitfields
+95_bitfields_ms.test : GEN = $(GEN-MSC)
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+# Filter some always-warning
+ifeq (-$(findstring arm,$(ARCH))-,-arm-)
+FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported'
+endif
+
+all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
+
+%.test: %.c %.expect
+	@echo Test: $*...
+	@$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3))
+
+T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)
+T2 = $(TCC) $(FLAGS) -run $< $(ARGS)
+T3 = $(FILTER) >$*.output 2>&1 || true \
+     && diff -Nbu $(filter %.expect,$^) $*.output \
+     && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
+
+# run single test and update .expect file, e.g. "make tests2.37+"
+tests2.%+:
+	@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
+
+# just run tcc to see the output, e.g. "make tests2.37-"
+tests2.%-:
+	@$(MAKE) $(call F1,$*) NODIFF=true --no-print-directory
+
+# run single test, e.g. "make tests2.37"
+tests2.%:
+	@$(MAKE) $(call F1,$*) --no-print-directory
+
+F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
+F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
+
+# automatically generate .expect files with gcc:
+%.expect :
+	@echo Generating: $@
+	@$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
+	@rm -f *.exe *.obj *.pdb
+
+# using TCC for .expect if -dt in FLAGS
+GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
+GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
+GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
+GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe
+MS-CC = cl
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+# force .expect generation for these files
+$(sort $(GEN-ALWAYS) $(UPDATE)) : force
+force:
+
+clean:
+	rm -f fred.txt *.output a.exe $(GEN-ALWAYS)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c	(revision 331)
@@ -0,0 +1,84 @@
+/*
+ * Test that allocating a variable length array in a loop
+ * does not use up a linear amount of memory
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LOOP_COUNT 1000
+#define ARRAY_SIZE 100
+
+/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */
+void smash(char *p, int n) {
+  memset(p, 0, n);
+}
+
+int test1(int n) {
+  int i;
+  char *array_ptrs[LOOP_COUNT];
+  
+  for (i = 0; i < LOOP_COUNT; ++i) {
+    char test[n];
+    smash(test, n);
+    array_ptrs[i] = test;
+  }
+  
+  return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+/* ensure goto does not circumvent array free */
+int test2(int n) {
+  char *array_ptrs[LOOP_COUNT];
+
+  int i = 0;
+loop:;
+  char test[n];
+  smash(test, n);
+  if (i >= LOOP_COUNT)
+    goto end;
+  array_ptrs[i] = test;
+  ++i;
+  goto loop;
+
+end:
+  smash(test, n);
+  char test2[n];
+  smash(test2, n);
+  return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+int test3(int n) {
+  char test[n];
+  smash(test, n);
+  goto label;
+label:
+  smash(test, n);
+  char test2[n];
+  smash(test2, n);
+  return (test-test2 >= n) ? 0 : 1;
+}
+
+#define RUN_TEST(t) \
+  if (!testname || (strcmp(#t, testname) == 0)) { \
+    fputs(#t "... ", stdout); \
+    fflush(stdout); \
+    if (t(ARRAY_SIZE) == 0) { \
+      fputs("success\n", stdout); \
+    } else { \
+      fputs("failure\n", stdout); \
+      retval = EXIT_FAILURE; \
+    } \
+  }
+
+int main(int argc, char **argv) {
+  const char *testname = NULL;
+  int retval = EXIT_SUCCESS;
+  if (argc > 1)
+    testname = argv[1];
+  RUN_TEST(test1)
+  RUN_TEST(test2)
+  RUN_TEST(test3)
+  return retval;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/x86_64-asm.h	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h	(revision 331)
@@ -6,6 +6,6 @@
      DEF_ASM_OP0(lahf, 0x9f)
      DEF_ASM_OP0(sahf, 0x9e)
-     DEF_ASM_OP0(pushfl, 0x9c)
-     DEF_ASM_OP0(popfl, 0x9d)
+     DEF_ASM_OP0(pushfq, 0x9c)
+     DEF_ASM_OP0(popfq, 0x9d)
      DEF_ASM_OP0(pushf, 0x9c)
      DEF_ASM_OP0(popf, 0x9d)
@@ -35,41 +35,42 @@
      DEF_ASM_OP0(wait, 0x9b)
      DEF_ASM_OP0(nop, 0x90)
+     DEF_ASM_OP0(pause, 0xf390)
      DEF_ASM_OP0(xlat, 0xd7)
 
      /* strings */
-ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLQ))
-
-ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWLQ))
-
-ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLQ))
-
-ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLQ))
-
-ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLQ))
-
-ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLQ))
-ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLQ))
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
 
      /* bits */
 
-ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA, OPT_REGW))
-
-ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
-
-ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
 
      /* prefixes */
@@ -88,45 +89,63 @@
      DEF_ASM_OP0(rdmsr, 0x0f32)
      DEF_ASM_OP0(rdpmc, 0x0f33)
+
+     DEF_ASM_OP0(syscall, 0x0f05)
+     DEF_ASM_OP0(sysret, 0x0f07)
+     DEF_ASM_OP0L(sysretq, 0x480f07, 0, 0)
      DEF_ASM_OP0(ud2, 0x0f0b)
 
      /* NOTE: we took the same order as gas opcode definition order */
-ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLQ, OPT_ADDR, OPT_EAX))
-ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLQ, OPT_EAX, OPT_ADDR))
-ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLQ, OPT_IM, OPT_REG))
-ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLQ, OPT_IM, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLQ, OPT_SEG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLQ, OPT_EA | OPT_REG, OPT_SEG))
-
-ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLQ, OPT_CR, OPT_REG64))
-ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLQ, OPT_DB, OPT_REG64))
-ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLQ, OPT_TR, OPT_REG64))
-ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_CR))
-ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_DB))
-ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLQ, OPT_REG64, OPT_TR))
-
+/* Right now we can't express the fact that 0xa1/0xa3 can't use $eax and a 
+   32 bit moffset as operands.
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) */
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+/* The moves are special: the 0xb8 form supports IM64 (the only insn that
+   does) with REG64.  It doesn't support IM32 with REG64, it would use
+   the full movabs form (64bit immediate).  For IM32->REG64 we prefer
+   the 0xc7 opcode.  So disallow all 64bit forms and code the rest by hand. */
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(mov,  0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movq, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_DB))
+
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
 ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movsbq, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REGW))
 ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(movslq, 0x4863, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
-ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movswq, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movslq, 0x63, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
 ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
-
-ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLQ, OPT_REG64))
-ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLQ, OPT_REG64 | OPT_EA))
-ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLQ, OPT_IM32))
-ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLQ, OPT_SEG))
-    DEF_ASM_OP1(pushb, 0x6a, 0, OPC_B, OPT_IM8S)
-
-ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLQ, OPT_REGW))
-ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLQ, OPT_REGW | OPT_EA))
-ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLQ, OPT_SEG))
-
-ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_REG, OPT_EAX))
-ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLQ, OPT_EAX, OPT_REG))
-ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(movzwq, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP1(pushq, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(push, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x666a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REG64 | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6668, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
 
 ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
@@ -140,5 +159,5 @@
 ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
 
-ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLQ, OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
 
 ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
@@ -149,74 +168,76 @@
 
      /* arith */
-ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
-ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLQ, OPT_IMNO64, OPT_EAX))
-ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_EA | OPT_REG, OPT_REG))
-ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLQ, OPT_REG, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLQ, OPT_IMNO64, OPT_EAX))
-ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLQ, OPT_IMNO64, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLQ, OPT_REGW))
-ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLQ, OPT_REGW))
-ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-
-ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLQ, OPT_REG | OPT_EA, OPT_REG))
-ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLQ, OPT_IM8S, OPT_REGW))
-ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
-ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLQ, OPT_IMW, OPT_REGW))
-
-ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX))
-ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA))
-ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLQ, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
 
      /* shifts */
-ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
-ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLQ | OPC_SHIFT, OPT_EA | OPT_REG))
-
-ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLQ, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
-ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLQ, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
 
 ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
-ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
 ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
-ALT(DEF_ASM_OP1(jmp, 0xff, 0, OPC_JMP | OPC_WL, OPT_REGW))
-ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
-
-ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
-ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
+
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(ljmpw, 0x66ff, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(ljmpl, 0xff, 5, OPC_MODRM, OPT_EA)
 
 ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
 ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
     DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
     DEF_ASM_OP0(leave, 0xc9)
     DEF_ASM_OP0(ret, 0xc3)
+    DEF_ASM_OP0(retq, 0xc3)
+ALT(DEF_ASM_OP1(retq, 0xc2, 0, 0, OPT_IM16))
 ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
     DEF_ASM_OP0(lret, 0xcb)
 ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
 
-ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
-    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
-    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8)
 
      /* float */
@@ -226,4 +247,6 @@
 ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
 ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
 ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
 ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
@@ -328,43 +351,53 @@
     DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
     DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+    /* The *q forms of fxrstor/fxsave use a REX prefix.
+       If the operand would use extended registers we would have to modify
+       it instead of generating a second one.  Currently that's no
+       problem with TCC, we don't use extended registers.  */
+    DEF_ASM_OP1(fxsaveq, 0x0fae, 0, OPC_MODRM | OPC_48, OPT_EA )
+    DEF_ASM_OP1(fxrstorq, 0x0fae, 1, OPC_MODRM | OPC_48, OPT_EA )
 
     /* segments */
     DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
-    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
     DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lidtq, 0x0f01, 3, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
     DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
-ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
-    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
+    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG16)
     DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sgdtq, 0x0f01, 0, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sidtq, 0x0f01, 1, OPC_MODRM, OPT_EA)
     DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
     DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
-    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
+    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG32 | OPT_EA)
+ALT(DEF_ASM_OP1(str, 0x660f00, 1, OPC_MODRM, OPT_REG16))
+ALT(DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM | OPC_48, OPT_REG64))
     DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
     DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP0L(swapgs, 0x0f01, 7, OPC_MODRM)
 
     /* 486 */
+    /* bswap can't be applied to 16bit regs */
     DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
-ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
-ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
+    DEF_ASM_OP1(bswapl, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+    DEF_ASM_OP1(bswapq, 0x0fc8, 0, OPC_REG | OPC_48, OPT_REG64 )
+
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
     DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
-
-    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
-    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
 
     /* pentium */
     DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
 
+    /* AMD 64 */
+    DEF_ASM_OP1(cmpxchg16b, 0x0fc7, 1, OPC_MODRM | OPC_48, OPT_EA )
+
     /* pentium pro */
-ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovno, 0x0f41, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovc, 0x0f42, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovnc, 0x0f43, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovz, 0x0f44, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovnz, 0x0f45, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmovna, 0x0f46, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
-ALT(DEF_ASM_OP2(cmova, 0x0f47, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
 
     DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
@@ -384,61 +417,105 @@
     /* mmx */
     DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
-    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
-ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
+    /* movd shouldn't accept REG64, but AMD64 spec uses it for 32 and 64 bit
+       moves, so let's be compatible. */
+ALT(DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG64, OPT_MMXSSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f6e, 0, OPC_MODRM | OPC_48, OPT_REG64, OPT_MMXSSE ))
 ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
 ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
-    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
-    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
-
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
+
+    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+    /* sse */
+    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+
+    DEF_ASM_OP1(prefetchnta, 0x0f18, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht0, 0x0f18, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht1, 0x0f18, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht2, 0x0f18, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetchw, 0x0f0d, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM)
+    DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
+    DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
+    DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA)
 #undef ALT
 #undef DEF_ASM_OP0
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.26/x86_64-gen.c	(revision 321)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c	(revision 331)
@@ -24,6 +24,7 @@
 
 /* number of available registers */
-#define NB_REGS         5
-#define NB_ASM_REGS     8
+#define NB_REGS         25
+#define NB_ASM_REGS     16
+#define CONFIG_TCC_ASM
 
 /* a register can belong to several classes. The classes must be
@@ -35,13 +36,21 @@
 #define RC_RCX     0x0008
 #define RC_RDX     0x0010
+#define RC_ST0     0x0080 /* only for long double */
 #define RC_R8      0x0100
 #define RC_R9      0x0200
 #define RC_R10     0x0400
 #define RC_R11     0x0800
-#define RC_XMM0    0x0020
-#define RC_ST0     0x0040 /* only for long double */
+#define RC_XMM0    0x1000
+#define RC_XMM1    0x2000
+#define RC_XMM2    0x4000
+#define RC_XMM3    0x8000
+#define RC_XMM4    0x10000
+#define RC_XMM5    0x20000
+#define RC_XMM6    0x40000
+#define RC_XMM7    0x80000
 #define RC_IRET    RC_RAX /* function return: integer register */
 #define RC_LRET    RC_RDX /* function return: second integer register */
 #define RC_FRET    RC_XMM0 /* function return: float register */
+#define RC_QRET    RC_XMM1 /* function return: second float register */
 
 /* pretty names for the registers */
@@ -50,16 +59,25 @@
     TREG_RCX = 1,
     TREG_RDX = 2,
-    TREG_XMM0 = 3,
-    TREG_ST0 = 4,
-
+    TREG_RSP = 4,
     TREG_RSI = 6,
     TREG_RDI = 7,
+
     TREG_R8  = 8,
     TREG_R9  = 9,
-
     TREG_R10 = 10,
     TREG_R11 = 11,
 
-    TREG_MEM = 0x10,
+    TREG_XMM0 = 16,
+    TREG_XMM1 = 17,
+    TREG_XMM2 = 18,
+    TREG_XMM3 = 19,
+    TREG_XMM4 = 20,
+    TREG_XMM5 = 21,
+    TREG_XMM6 = 22,
+    TREG_XMM7 = 23,
+
+    TREG_ST0 = 24,
+
+    TREG_MEM = 0x20
 };
 
@@ -71,4 +89,5 @@
 #define REG_LRET TREG_RDX /* second word return register (for long long) */
 #define REG_FRET TREG_XMM0 /* float return register */
+#define REG_QRET TREG_XMM1 /* second float return register */
 
 /* defined if function parameters must be evaluated in reverse order */
@@ -80,21 +99,7 @@
 /* long double size and alignment, in bytes */
 #define LDOUBLE_SIZE  16
-#define LDOUBLE_ALIGN 8
+#define LDOUBLE_ALIGN 16
 /* maximum alignment (for aligned attribute support) */
-#define MAX_ALIGN     8
-
-/******************************************************/
-/* ELF defines */
-
-#define EM_TCC_TARGET EM_X86_64
-
-/* relocation type for 32 bit data relocation */
-#define R_DATA_32   R_X86_64_32
-#define R_DATA_PTR  R_X86_64_64
-#define R_JMP_SLOT  R_X86_64_JUMP_SLOT
-#define R_COPY      R_X86_64_COPY
-
-#define ELF_START_ADDR 0x08048000
-#define ELF_PAGE_SIZE  0x1000
+#define MAX_ALIGN     16
 
 /******************************************************/
@@ -104,17 +109,33 @@
 #include <assert.h>
 
-ST_DATA const int reg_classes[NB_REGS+7] = {
+ST_DATA const int reg_classes[NB_REGS] = {
     /* eax */ RC_INT | RC_RAX,
     /* ecx */ RC_INT | RC_RCX,
     /* edx */ RC_INT | RC_RDX,
-    /* xmm0 */ RC_FLOAT | RC_XMM0,
-    /* st0 */ RC_ST0,
     0,
     0,
     0,
-    RC_INT | RC_R8,
-    RC_INT | RC_R9,
-    RC_INT | RC_R10,
-    RC_INT | RC_R11
+    0,
+    0,
+    RC_R8,
+    RC_R9,
+    RC_R10,
+    RC_R11,
+    0,
+    0,
+    0,
+    0,
+    /* xmm0 */ RC_FLOAT | RC_XMM0,
+    /* xmm1 */ RC_FLOAT | RC_XMM1,
+    /* xmm2 */ RC_FLOAT | RC_XMM2,
+    /* xmm3 */ RC_FLOAT | RC_XMM3,
+    /* xmm4 */ RC_FLOAT | RC_XMM4,
+    /* xmm5 */ RC_FLOAT | RC_XMM5,
+    /* xmm6 an xmm7 are included so gv() can be used on them,
+       but they are not tagged with RC_FLOAT because they are
+       callee saved on Windows */
+    RC_XMM6,
+    RC_XMM7,
+    /* st0 */ RC_ST0
 };
 
@@ -123,7 +144,9 @@
 
 /* XXX: make it faster ? */
-void g(int c)
+ST_FUNC void g(int c)
 {
     int ind1;
+    if (nocode_wanted)
+        return;
     ind1 = ind + 1;
     if (ind1 > cur_text_section->data_allocated)
@@ -133,5 +156,5 @@
 }
 
-void o(unsigned int c)
+ST_FUNC void o(unsigned int c)
 {
     while (c) {
@@ -141,5 +164,5 @@
 }
 
-void gen_le16(int v)
+ST_FUNC void gen_le16(int v)
 {
     g(v);
@@ -147,5 +170,5 @@
 }
 
-void gen_le32(int c)
+ST_FUNC void gen_le32(int c)
 {
     g(c);
@@ -155,5 +178,5 @@
 }
 
-void gen_le64(int64_t c)
+ST_FUNC void gen_le64(int64_t c)
 {
     g(c);
@@ -167,5 +190,5 @@
 }
 
-void orex(int ll, int r, int r2, int b)
+static void orex(int ll, int r, int r2, int b)
 {
     if ((r & VT_VALMASK) >= VT_CONST)
@@ -179,11 +202,10 @@
 
 /* output a symbol and patch all calls to it */
-void gsym_addr(int t, int a)
-{
-    int n, *ptr;
+ST_FUNC void gsym_addr(int t, int a)
+{
     while (t) {
-        ptr = (int *)(cur_text_section->data + t);
-        n = *ptr; /* next value */
-        *ptr = a - t - 4;
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t n = read32le(ptr); /* next value */
+        write32le(ptr, a - t - 4);
         t = n;
     }
@@ -195,7 +217,4 @@
 }
 
-/* psym is used to put an instruction with a data field which is a
-   reference to a symbol. It is in fact the same as oad ! */
-#define psym oad
 
 static int is64_type(int t)
@@ -206,30 +225,23 @@
 }
 
-static int is_sse_float(int t) {
-    int bt;
-    bt = t & VT_BTYPE;
-    return bt == VT_DOUBLE || bt == VT_FLOAT;
-}
-
-
 /* instruction + 4 bytes data. Return the address of the data */
-ST_FUNC int oad(int c, int s)
-{
-    int ind1;
-
+static int oad(int c, int s)
+{
+    int t;
+    if (nocode_wanted)
+        return s;
     o(c);
-    ind1 = ind + 4;
-    if (ind1 > cur_text_section->data_allocated)
-        section_realloc(cur_text_section, ind1);
-    *(int *)(cur_text_section->data + ind) = s;
-    s = ind;
-    ind = ind1;
-    return s;
-}
+    t = ind;
+    gen_le32(s);
+    return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
 
 ST_FUNC void gen_addr32(int r, Sym *sym, int c)
 {
     if (r & VT_SYM)
-        greloc(cur_text_section, sym, ind, R_X86_64_32);
+        greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0;
     gen_le32(c);
 }
@@ -239,5 +251,5 @@
 {
     if (r & VT_SYM)
-        greloc(cur_text_section, sym, ind, R_X86_64_64);
+        greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0;
     gen_le64(c);
 }
@@ -247,5 +259,5 @@
 {
     if (r & VT_SYM)
-        greloc(cur_text_section, sym, ind, R_X86_64_PC32);
+        greloca(cur_text_section, sym, ind, R_X86_64_PC32, c-4), c=4;
     gen_le32(c-4);
 }
@@ -254,19 +266,13 @@
 static void gen_gotpcrel(int r, Sym *sym, int c)
 {
-#ifndef TCC_TARGET_PE
-    Section *sr;
-    ElfW(Rela) *rel;
-    greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL);
-    sr = cur_text_section->reloc;
-    rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela)));
-    rel->r_addend = -4;
-#else
-    printf("picpic: %s %x %x | %02x %02x %02x\n", get_tok_str(sym->v, NULL), c, r,
+#ifdef TCC_TARGET_PE
+    tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
+        get_tok_str(sym->v, NULL), c, r,
         cur_text_section->data[ind-3],
         cur_text_section->data[ind-2],
         cur_text_section->data[ind-1]
         );
-    greloc(cur_text_section, sym, ind, R_X86_64_PC32);
 #endif
+    greloca(cur_text_section, sym, ind, R_X86_64_GOTPCREL, -4);
     gen_le32(0);
     if (c) {
@@ -283,10 +289,16 @@
     if ((r & VT_VALMASK) == VT_CONST) {
         /* constant memory reference */
-        o(0x05 | op_reg);
-        if (is_got) {
-            gen_gotpcrel(r, sym, c);
-        } else {
-            gen_addrpc32(r, sym, c);
-        }
+	if (!(r & VT_SYM)) {
+	    /* Absolute memory reference */
+	    o(0x04 | op_reg); /* [sib] | destreg */
+	    oad(0x25, c);     /* disp32 */
+	} else {
+	    o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
+	    if (is_got) {
+		gen_gotpcrel(r, sym, c);
+	    } else {
+		gen_addrpc32(r, sym, c);
+	    }
+	}
     } else if ((r & VT_VALMASK) == VT_LOCAL) {
         /* currently, we use only ebp as base */
@@ -310,5 +322,5 @@
 }
 
-/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+/* generate a modrm reference. 'op_reg' contains the additional 3
    opcode bits */
 static void gen_modrm(int op_reg, int r, Sym *sym, int c)
@@ -317,5 +329,5 @@
 }
 
-/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+/* generate a modrm reference. 'op_reg' contains the additional 3
    opcode bits */
 static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c)
@@ -340,6 +352,10 @@
 
     fr = sv->r;
-    ft = sv->type.t;
-    fc = sv->c.ul;
+    ft = sv->type.t & ~VT_DEFSIGN;
+    fc = sv->c.i;
+    if (fc != sv->c.i && (fr & VT_SYM))
+      tcc_error("64 bit addend in load");
+
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
 
 #ifndef TCC_TARGET_PE
@@ -366,18 +382,49 @@
             v1.type.t = VT_PTR;
             v1.r = VT_LOCAL | VT_LVAL;
-            v1.c.ul = fc;
+            v1.c.i = fc;
             fr = r;
-            if (!(reg_classes[fr] & RC_INT))
+            if (!(reg_classes[fr] & (RC_INT|RC_R11)))
                 fr = get_reg(RC_INT);
             load(fr, &v1);
         }
+	if (fc != sv->c.i) {
+	    /* If the addends doesn't fit into a 32bit signed
+	       we must use a 64bit move.  We've checked above
+	       that this doesn't have a sym associated.  */
+	    v1.type.t = VT_LLONG;
+	    v1.r = VT_CONST;
+	    v1.c.i = sv->c.i;
+	    fr = r;
+	    if (!(reg_classes[fr] & (RC_INT|RC_R11)))
+	        fr = get_reg(RC_INT);
+	    load(fr, &v1);
+	    fc = 0;
+	}
         ll = 0;
+	/* Like GCC we can load from small enough properly sized
+	   structs and unions as well.
+	   XXX maybe move to generic operand handling, but should
+	   occur only with asm, so tccasm.c might also be a better place */
+	if ((ft & VT_BTYPE) == VT_STRUCT) {
+	    int align;
+	    switch (type_size(&sv->type, &align)) {
+		case 1: ft = VT_BYTE; break;
+		case 2: ft = VT_SHORT; break;
+		case 4: ft = VT_INT; break;
+		case 8: ft = VT_LLONG; break;
+		default:
+		    tcc_error("invalid aggregate type for register load");
+		    break;
+	    }
+	}
         if ((ft & VT_BTYPE) == VT_FLOAT) {
-            b = 0x6e0f66, r = 0; /* movd */
+            b = 0x6e0f66;
+            r = REG_VALUE(r); /* movd */
         } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
-            b = 0x7e0ff3, r = 0; /* movq */
+            b = 0x7e0ff3; /* movq */
+            r = REG_VALUE(r);
         } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
             b = 0xdb, r = 5; /* fldt */
-        } else if ((ft & VT_TYPE) == VT_BYTE) {
+        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
             b = 0xbe0f;   /* movsbl */
         } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
@@ -388,4 +435,9 @@
             b = 0xb70f;   /* movzwl */
         } else {
+            assert(((ft & VT_BTYPE) == VT_INT)
+                   || ((ft & VT_BTYPE) == VT_LLONG)
+                   || ((ft & VT_BTYPE) == VT_PTR)
+                   || ((ft & VT_BTYPE) == VT_FUNC)
+                );
             ll = is64_type(ft);
             b = 0x8b;
@@ -417,5 +469,5 @@
             } else if (is64_type(ft)) {
                 orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
-                gen_le64(sv->c.ull);
+                gen_le64(sv->c.i);
             } else {
                 orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
@@ -451,16 +503,28 @@
             oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */
         } else if (v != r) {
-            if (r == TREG_XMM0) {
-                assert(v == TREG_ST0);
-                /* gen_cvt_ftof(VT_DOUBLE); */
-                o(0xf0245cdd); /* fstpl -0x10(%rsp) */
-                /* movsd -0x10(%rsp),%xmm0 */
-                o(0x44100ff2);
-                o(0xf024);
+            if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) {
+                if (v == TREG_ST0) {
+                    /* gen_cvt_ftof(VT_DOUBLE); */
+                    o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+                    /* movsd -0x10(%rsp),%xmmN */
+                    o(0x100ff2);
+                    o(0x44 + REG_VALUE(r)*8); /* %xmmN */
+                    o(0xf024);
+                } else {
+                    assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
+                    if ((ft & VT_BTYPE) == VT_FLOAT) {
+                        o(0x100ff3);
+                    } else {
+                        assert((ft & VT_BTYPE) == VT_DOUBLE);
+                        o(0x100ff2);
+                    }
+                    o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8);
+                }
             } else if (r == TREG_ST0) {
-                assert(v == TREG_XMM0);
+                assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
                 /* gen_cvt_ftof(VT_LDOUBLE); */
-                /* movsd %xmm0,-0x10(%rsp) */
-                o(0x44110ff2);
+                /* movsd %xmmN,-0x10(%rsp) */
+                o(0x110ff2);
+                o(0x44 + REG_VALUE(r)*8); /* %xmmN */
                 o(0xf024);
                 o(0xf02444dd); /* fldl -0x10(%rsp) */
@@ -486,7 +550,10 @@
 #endif
 
+    fr = v->r & VT_VALMASK;
     ft = v->type.t;
-    fc = v->c.ul;
-    fr = v->r & VT_VALMASK;
+    fc = v->c.i;
+    if (fc != v->c.i && (fr & VT_SYM))
+      tcc_error("64 bit addend in store");
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
     bt = ft & VT_BTYPE;
 
@@ -496,5 +563,5 @@
         /* mov xx(%rip), %r11 */
         o(0x1d8b4c);
-        gen_gotpcrel(TREG_R11, v->sym, v->c.ul);
+        gen_gotpcrel(TREG_R11, v->sym, v->c.i);
         pic = is64_type(bt) ? 0x49 : 0x41;
     }
@@ -506,10 +573,10 @@
         o(pic);
         o(0x7e0f); /* movd */
-        r = 0;
+        r = REG_VALUE(r);
     } else if (bt == VT_DOUBLE) {
         o(0x66);
         o(pic);
         o(0xd60f); /* movq */
-        r = 0;
+        r = REG_VALUE(r);
     } else if (bt == VT_LDOUBLE) {
         o(0xc0d9); /* fld %st(0) */
@@ -556,16 +623,20 @@
 {
     int r;
-    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+	((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
         /* constant case */
         if (vtop->r & VT_SYM) {
             /* relocation case */
-            greloc(cur_text_section, vtop->sym,
-                   ind + 1, R_X86_64_PC32);
+#ifdef TCC_TARGET_PE
+            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
+#else
+            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
+#endif
         } else {
             /* put an empty PC32 relocation */
-            put_elf_reloc(symtab_section, cur_text_section,
-                          ind + 1, R_X86_64_PC32, 0);
-        }
-        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
+            put_elf_reloca(symtab_section, cur_text_section,
+                          ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
+        }
+        oad(0xe8 + is_jmp, 0); /* call/jmp im */
     } else {
         /* otherwise, indirect call */
@@ -578,12 +649,106 @@
 }
 
+#if defined(CONFIG_TCC_BCHECK)
+#ifndef TCC_TARGET_PE
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+#endif
+
+static void gen_static_call(int v)
+{
+    Sym *sym = external_global_sym(v, &func_old_type, 0);
+    oad(0xe8, 0);
+    greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+}
+
+/* generate a bounded pointer addition */
+ST_FUNC void gen_bounded_ptr_add(void)
+{
+    /* save all temporary registers */
+    save_regs(0);
+
+    /* prepare fast x86_64 function call */
+    gv(RC_RAX);
+    o(0xc68948); // mov  %rax,%rsi ## second arg in %rsi, this must be size
+    vtop--;
+
+    gv(RC_RAX);
+    o(0xc78948); // mov  %rax,%rdi ## first arg in %rdi, this must be ptr
+    vtop--;
+
+    /* do a fast function call */
+    gen_static_call(TOK___bound_ptr_add);
+
+    /* returned pointer is in rax */
+    vtop++;
+    vtop->r = TREG_RAX | VT_BOUNDED;
+
+
+    /* relocation offset of the bounding function call point */
+    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+   also tested */
+ST_FUNC void gen_bounded_ptr_deref(void)
+{
+    addr_t func;
+    int size, align;
+    ElfW(Rela) *rel;
+    Sym *sym;
+
+    size = 0;
+    /* XXX: put that code in generic part of tcc */
+    if (!is_float(vtop->type.t)) {
+        if (vtop->r & VT_LVAL_BYTE)
+            size = 1;
+        else if (vtop->r & VT_LVAL_SHORT)
+            size = 2;
+    }
+    if (!size)
+    size = type_size(&vtop->type, &align);
+    switch(size) {
+    case  1: func = TOK___bound_ptr_indir1; break;
+    case  2: func = TOK___bound_ptr_indir2; break;
+    case  4: func = TOK___bound_ptr_indir4; break;
+    case  8: func = TOK___bound_ptr_indir8; break;
+    case 12: func = TOK___bound_ptr_indir12; break;
+    case 16: func = TOK___bound_ptr_indir16; break;
+    default:
+        tcc_error("unhandled size when dereferencing bounded pointer");
+        func = 0;
+        break;
+    }
+
+    sym = external_global_sym(func, &func_old_type, 0);
+    if (!sym->c)
+        put_extern_sym(sym, NULL, 0, 0);
+
+    /* patch relocation */
+    /* XXX: find a better solution ? */
+
+    rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
+    rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
+}
+#endif
+
 #ifdef TCC_TARGET_PE
 
 #define REGN 4
-static const uint8_t arg_regs[] = {
+static const uint8_t arg_regs[REGN] = {
     TREG_RCX, TREG_RDX, TREG_R8, TREG_R9
 };
 
-static int func_scratch;
+/* Prepare arguments in R10 and R11 rather than RCX and RDX
+   because gv() will not ever use these */
+static int arg_prepare_reg(int idx) {
+  if (idx == 0 || idx == 1)
+      /* idx=0: r10, idx=1: r11 */
+      return idx + 10;
+  else
+      return arg_regs[idx];
+}
+
+static int func_scratch, func_alloca;
 
 /* Generate function call. The function address is pushed first, then
@@ -591,5 +756,5 @@
    parameters and the function address. */
 
-void gen_offs_sp(int b, int r, int d)
+static void gen_offs_sp(int b, int r, int d)
 {
     orex(1,0,r & 0x100 ? 0 : r, b);
@@ -603,11 +768,51 @@
 }
 
+static int using_regs(int size)
+{
+    return !(size > 8 || (size & (size - 1)));
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+    int size, align;
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    *regsize = 8;
+    size = type_size(vt, &align);
+    if (!using_regs(size))
+        return 0;
+    if (size == 8)
+        ret->t = VT_LLONG;
+    else if (size == 4)
+        ret->t = VT_INT;
+    else if (size == 2)
+        ret->t = VT_SHORT;
+    else
+        ret->t = VT_BYTE;
+    ret->ref = NULL;
+    return 1;
+}
+
+static int is_sse_float(int t) {
+    int bt;
+    bt = t & VT_BTYPE;
+    return bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+static int gfunc_arg_size(CType *type) {
+    int align;
+    if (type->t & (VT_ARRAY|VT_BITFIELD))
+        return 8;
+    return type_size(type, &align);
+}
+
 void gfunc_call(int nb_args)
 {
-    int size, align, r, args_size, i, d, j, bt, struct_size;
-    int nb_reg_args, gen_reg;
-
-    nb_reg_args = nb_args;
-    args_size = (nb_reg_args < REGN ? REGN : nb_reg_args) * PTR_SIZE;
+    int size, r, args_size, i, d, bt, struct_size;
+    int arg;
+
+    args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
+    arg = nb_args;
 
     /* for struct arguments, we need to call memcpy and the function
@@ -616,8 +821,15 @@
     struct_size = args_size;
     for(i = 0; i < nb_args; i++) {
-        SValue *sv = &vtop[-i];
+        SValue *sv;
+        
+        --arg;
+        sv = &vtop[-i];
         bt = (sv->type.t & VT_BTYPE);
+        size = gfunc_arg_size(&sv->type);
+
+        if (using_regs(size))
+            continue; /* arguments smaller than 8 bytes passed in registers or on stack */
+
         if (bt == VT_STRUCT) {
-            size = type_size(&sv->type, &align);
             /* align to stack align size */
             size = (size + 15) & ~15;
@@ -632,11 +844,8 @@
             vstore();
             --vtop;
-
         } else if (bt == VT_LDOUBLE) {
-
             gv(RC_ST0);
             gen_offs_sp(0xdb, 0x107, struct_size);
             struct_size += 16;
-
         }
     }
@@ -644,66 +853,58 @@
     if (func_scratch < struct_size)
         func_scratch = struct_size;
-#if 1
-    for (i = 0; i < REGN; ++i)
-        save_reg(arg_regs[i]);
-    save_reg(TREG_RAX);
-#endif
-    gen_reg = nb_reg_args;
+
+    arg = nb_args;
     struct_size = args_size;
 
     for(i = 0; i < nb_args; i++) {
+        --arg;
         bt = (vtop->type.t & VT_BTYPE);
 
-        if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
-            if (bt == VT_LDOUBLE)
-                size = 16;
-            else
-                size = type_size(&vtop->type, &align);
+        size = gfunc_arg_size(&vtop->type);
+        if (!using_regs(size)) {
             /* align to stack align size */
             size = (size + 15) & ~15;
-            j = --gen_reg;
-            if (j >= REGN) {
-                d = TREG_RAX;
+            if (arg >= REGN) {
+                d = get_reg(RC_INT);
                 gen_offs_sp(0x8d, d, struct_size);
-                gen_offs_sp(0x89, d, j*8);
+                gen_offs_sp(0x89, d, arg*8);
             } else {
-                d = arg_regs[j];
+                d = arg_prepare_reg(arg);
                 gen_offs_sp(0x8d, d, struct_size);
             }
             struct_size += size;
-
-        } else if (is_sse_float(vtop->type.t)) {
-            gv(RC_FLOAT); /* only one float register */
-            j = --gen_reg;
-            if (j >= REGN) {
-                /* movq %xmm0, j*8(%rsp) */
-                gen_offs_sp(0xd60f66, 0x100, j*8);
+        } else {
+            if (is_sse_float(vtop->type.t)) {
+		if (tcc_state->nosse)
+		  tcc_error("SSE disabled");
+                gv(RC_XMM0); /* only use one float register */
+                if (arg >= REGN) {
+                    /* movq %xmm0, j*8(%rsp) */
+                    gen_offs_sp(0xd60f66, 0x100, arg*8);
+                } else {
+                    /* movaps %xmm0, %xmmN */
+                    o(0x280f);
+                    o(0xc0 + (arg << 3));
+                    d = arg_prepare_reg(arg);
+                    /* mov %xmm0, %rxx */
+                    o(0x66);
+                    orex(1,d,0, 0x7e0f);
+                    o(0xc0 + REG_VALUE(d));
+                }
             } else {
-                /* movaps %xmm0, %xmmN */
-                o(0x280f);
-                o(0xc0 + (j << 3));
-                d = arg_regs[j];
-                /* mov %xmm0, %rxx */
-                o(0x66);
-                orex(1,d,0, 0x7e0f);
-                o(0xc0 + REG_VALUE(d));
-            }
-        } else {
-            j = --gen_reg;
-            if (j >= REGN) {
+                if (bt == VT_STRUCT) {
+                    vtop->type.ref = NULL;
+                    vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
+                        : size > 1 ? VT_SHORT : VT_BYTE;
+                }
+                
                 r = gv(RC_INT);
-                gen_offs_sp(0x89, r, j*8);
-            } else {
-                d = arg_regs[j];
-                if (d < NB_REGS) {
-                    gv(reg_classes[d] & ~RC_INT);
+                if (arg >= REGN) {
+                    gen_offs_sp(0x89, r, arg*8);
                 } else {
-                    r = gv(RC_INT);
-                    if (d != r) {
-                        orex(1,d,r, 0x89);
-                        o(0xc0 + REG_VALUE(d) + REG_VALUE(r) * 8);
-                    }
+                    d = arg_prepare_reg(arg);
+                    orex(1,d,r,0x89); /* mov */
+                    o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
                 }
-
             }
         }
@@ -711,5 +912,36 @@
     }
     save_regs(0);
+    
+    /* Copy R10 and R11 into RCX and RDX, respectively */
+    if (nb_args > 0) {
+        o(0xd1894c); /* mov %r10, %rcx */
+        if (nb_args > 1) {
+            o(0xda894c); /* mov %r11, %rdx */
+        }
+    }
+    
     gcall_or_jmp(0);
+
+    if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
+        /* need to add the "func_scratch" area after alloca */
+        o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
+    }
+
+    /* other compilers don't clear the upper bits when returning char/short */
+    bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
+    if (bt == (VT_BYTE | VT_UNSIGNED))
+        o(0xc0b60f);  /* movzbl %al, %eax */
+    else if (bt == VT_BYTE)
+        o(0xc0be0f); /* movsbl %al, %eax */
+    else if (bt == VT_SHORT)
+        o(0x98); /* cwtl */
+    else if (bt == (VT_SHORT | VT_UNSIGNED))
+        o(0xc0b70f);  /* movzbl %al, %eax */
+#if 0 /* handled in gen_cast() */
+    else if (bt == VT_INT)
+        o(0x9848); /* cltq */
+    else if (bt == (VT_INT | VT_UNSIGNED))
+        o(0xc089); /* mov %eax,%eax */
+#endif
     vtop--;
 }
@@ -721,5 +953,5 @@
 void gfunc_prolog(CType *func_type)
 {
-    int addr, reg_param_index, bt;
+    int addr, reg_param_index, bt, size;
     Sym *sym;
     CType *type;
@@ -727,4 +959,5 @@
     func_ret_sub = 0;
     func_scratch = 0;
+    func_alloca = 0;
     loc = 0;
 
@@ -739,8 +972,11 @@
        implicit pointer parameter */
     func_vt = sym->type;
-    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+    size = gfunc_arg_size(&func_vt);
+    if (!using_regs(size)) {
         gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+        func_vc = addr;
         reg_param_index++;
-        addr += PTR_SIZE;
+        addr += 8;
     }
 
@@ -749,22 +985,34 @@
         type = &sym->type;
         bt = type->t & VT_BTYPE;
-        if (reg_param_index < REGN) {
-            /* save arguments passed by register */
+        size = gfunc_arg_size(type);
+        if (!using_regs(size)) {
+            if (reg_param_index < REGN) {
+                gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+            }
+            sym_push(sym->v & ~SYM_FIELD, type, VT_LLOCAL | VT_LVAL, addr);
+        } else {
+            if (reg_param_index < REGN) {
+                /* save arguments passed by register */
+                if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
+		    if (tcc_state->nosse)
+		      tcc_error("SSE disabled");
+                    o(0xd60f66); /* movq */
+                    gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
+                } else {
+                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+                }
+            }
+            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
+        }
+        addr += 8;
+        reg_param_index++;
+    }
+
+    while (reg_param_index < REGN) {
+        if (func_type->ref->f.func_type == FUNC_ELLIPSIS) {
             gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
-        }
-        if (bt == VT_STRUCT || bt == VT_LDOUBLE) {
-            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL | VT_REF, addr);
-        } else {
-            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
+            addr += 8;
         }
         reg_param_index++;
-        addr += PTR_SIZE;
-    }
-
-    while (reg_param_index < REGN) {
-        if (func_type->ref->c == FUNC_ELLIPSIS)
-            gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
-        reg_param_index++;
-        addr += PTR_SIZE;
     }
 }
@@ -787,4 +1035,5 @@
     ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
     /* align local size to word & save local variables */
+    func_scratch = (func_scratch + 15) & -16;
     v = (func_scratch + -loc + 15) & -16;
 
@@ -792,6 +1041,6 @@
         Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
         oad(0xb8, v); /* mov stacksize, %eax */
-        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
-        greloc(cur_text_section, sym, ind-4, R_X86_64_PC32);
+        oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */
+        greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
         o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
     } else {
@@ -801,4 +1050,11 @@
     }
 
+    /* add the "func_scratch" area after each alloca seen */
+    while (func_alloca) {
+        unsigned char *ptr = cur_text_section->data + func_alloca;
+        func_alloca = read32le(ptr);
+        write32le(ptr, func_scratch);
+    }
+
     cur_text_section->data_offset = saved_ind;
     pe_add_unwind_data(ind, saved_ind, v);
@@ -818,4 +1074,148 @@
 }
 
+typedef enum X86_64_Mode {
+  x86_64_mode_none,
+  x86_64_mode_memory,
+  x86_64_mode_integer,
+  x86_64_mode_sse,
+  x86_64_mode_x87
+} X86_64_Mode;
+
+static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
+{
+    if (a == b)
+        return a;
+    else if (a == x86_64_mode_none)
+        return b;
+    else if (b == x86_64_mode_none)
+        return a;
+    else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory))
+        return x86_64_mode_memory;
+    else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer))
+        return x86_64_mode_integer;
+    else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87))
+        return x86_64_mode_memory;
+    else
+        return x86_64_mode_sse;
+}
+
+static X86_64_Mode classify_x86_64_inner(CType *ty)
+{
+    X86_64_Mode mode;
+    Sym *f;
+    
+    switch (ty->t & VT_BTYPE) {
+    case VT_VOID: return x86_64_mode_none;
+    
+    case VT_INT:
+    case VT_BYTE:
+    case VT_SHORT:
+    case VT_LLONG:
+    case VT_BOOL:
+    case VT_PTR:
+    case VT_FUNC:
+        return x86_64_mode_integer;
+    
+    case VT_FLOAT:
+    case VT_DOUBLE: return x86_64_mode_sse;
+    
+    case VT_LDOUBLE: return x86_64_mode_x87;
+      
+    case VT_STRUCT:
+        f = ty->ref;
+
+        mode = x86_64_mode_none;
+        for (f = f->next; f; f = f->next)
+            mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));
+        
+        return mode;
+    }
+    assert(0);
+    return 0;
+}
+
+static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
+{
+    X86_64_Mode mode;
+    int size, align, ret_t = 0;
+    
+    if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
+        *psize = 8;
+        *palign = 8;
+        *reg_count = 1;
+        ret_t = ty->t;
+        mode = x86_64_mode_integer;
+    } else {
+        size = type_size(ty, &align);
+        *psize = (size + 7) & ~7;
+        *palign = (align + 7) & ~7;
+    
+        if (size > 16) {
+            mode = x86_64_mode_memory;
+        } else {
+            mode = classify_x86_64_inner(ty);
+            switch (mode) {
+            case x86_64_mode_integer:
+                if (size > 8) {
+                    *reg_count = 2;
+                    ret_t = VT_QLONG;
+                } else {
+                    *reg_count = 1;
+                    ret_t = (size > 4) ? VT_LLONG : VT_INT;
+                }
+                break;
+                
+            case x86_64_mode_x87:
+                *reg_count = 1;
+                ret_t = VT_LDOUBLE;
+                break;
+
+            case x86_64_mode_sse:
+                if (size > 8) {
+                    *reg_count = 2;
+                    ret_t = VT_QFLOAT;
+                } else {
+                    *reg_count = 1;
+                    ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
+                }
+                break;
+            default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/
+            }
+        }
+    }
+    
+    if (ret) {
+        ret->ref = NULL;
+        ret->t = ret_t;
+    }
+    
+    return mode;
+}
+
+ST_FUNC int classify_x86_64_va_arg(CType *ty)
+{
+    /* This definition must be synced with stdarg.h */
+    enum __va_arg_type {
+        __va_gen_reg, __va_float_reg, __va_stack
+    };
+    int size, align, reg_count;
+    X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
+    switch (mode) {
+    default: return __va_stack;
+    case x86_64_mode_integer: return __va_gen_reg;
+    case x86_64_mode_sse: return __va_float_reg;
+    }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+    int size, align, reg_count;
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    *regsize = 8;
+    return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);
+}
+
 #define REGN 6
 static const uint8_t arg_regs[REGN] = {
@@ -823,4 +1223,12 @@
 };
 
+static int arg_prepare_reg(int idx) {
+  if (idx == 2 || idx == 3)
+      /* idx=2: r10, idx=3: r11 */
+      return idx + 8;
+  else
+      return arg_regs[idx];
+}
+
 /* Generate function call. The function address is pushed first, then
    all the parameters in call order. This functions pops all the
@@ -828,25 +1236,43 @@
 void gfunc_call(int nb_args)
 {
-    int size, align, r, args_size, i;
+    X86_64_Mode mode;
+    CType type;
+    int size, align, r, args_size, stack_adjust, i, reg_count;
     int nb_reg_args = 0;
     int nb_sse_args = 0;
     int sse_reg, gen_reg;
-
-    /* calculate the number of integer/float arguments */
-    args_size = 0;
-    for(i = 0; i < nb_args; i++) {
-        if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) {
-            args_size += type_size(&vtop[-i].type, &align);
-            args_size = (args_size + 7) & ~7;
-        } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) {
-            args_size += 16;
-        } else if (is_sse_float(vtop[-i].type.t)) {
-            nb_sse_args++;
-            if (nb_sse_args > 8) args_size += 8;
-        } else {
-            nb_reg_args++;
-            if (nb_reg_args > REGN) args_size += 8;
-        }
-    }
+    char _onstack[nb_args], *onstack = _onstack;
+
+    /* calculate the number of integer/float register arguments, remember
+       arguments to be passed via stack (in onstack[]), and also remember
+       if we have to align the stack pointer to 16 (onstack[i] == 2).  Needs
+       to be done in a left-to-right pass over arguments.  */
+    stack_adjust = 0;
+    for(i = nb_args - 1; i >= 0; i--) {
+        mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+        if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
+            nb_sse_args += reg_count;
+	    onstack[i] = 0;
+	} else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
+            nb_reg_args += reg_count;
+	    onstack[i] = 0;
+	} else if (mode == x86_64_mode_none) {
+	    onstack[i] = 0;
+	} else {
+	    if (align == 16 && (stack_adjust &= 15)) {
+		onstack[i] = 2;
+		stack_adjust = 0;
+	    } else
+	      onstack[i] = 1;
+	    stack_adjust += size;
+	}
+    }
+
+    if (nb_sse_args && tcc_state->nosse)
+      tcc_error("SSE disabled but floating point arguments passed");
+
+    /* fetch cpu flag before generating any code */
+    if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
+      gv(RC_INT);
 
     /* for struct arguments, we need to call memcpy and the function
@@ -855,73 +1281,72 @@
     gen_reg = nb_reg_args;
     sse_reg = nb_sse_args;
-
-    /* adjust stack to align SSE boundary */
-    if (args_size &= 15) {
-        /* fetch cpu flag before the following sub will change the value */
-        if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
-            gv(RC_INT);
-
-        args_size = 16 - args_size;
-        o(0x48);
-        oad(0xec81, args_size); /* sub $xxx, %rsp */
-    }
-
-    for(i = 0; i < nb_args; i++) {
-	/* Swap argument to top, it will possibly be changed here,
-	   and might use more temps.  All arguments must remain on the
-	   stack, so that get_reg can correctly evict some of them onto
-	   stack.  We could use also use a vrott(nb_args) at the end
-	   of this loop, but this seems faster.  */
-        SValue tmp = vtop[0];
-	vtop[0] = vtop[-i];
-	vtop[-i] = tmp;
-        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
-            size = type_size(&vtop->type, &align);
-            /* align to stack align size */
-            size = (size + 7) & ~7;
-            /* allocate the necessary size on stack */
-            o(0x48);
-            oad(0xec81, size); /* sub $xxx, %rsp */
-            /* generate structure store */
-            r = get_reg(RC_INT);
-            orex(1, r, 0, 0x89); /* mov %rsp, r */
-            o(0xe0 + REG_VALUE(r));
-	    vset(&vtop->type, r | VT_LVAL, 0);
-	    vswap();
-	    vstore();
-            args_size += size;
-        } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
-            gv(RC_ST0);
-            size = LDOUBLE_SIZE;
-            oad(0xec8148, size); /* sub $xxx, %rsp */
-            o(0x7cdb); /* fstpt 0(%rsp) */
-            g(0x24);
-            g(0x00);
-            args_size += size;
-        } else if (is_sse_float(vtop->type.t)) {
-            int j = --sse_reg;
-            if (j >= 8) {
-                gv(RC_FLOAT);
-                o(0x50); /* push $rax */
-                /* movq %xmm0, (%rsp) */
-                o(0x04d60f66);
-                o(0x24);
-                args_size += 8;
-            }
-        } else {
-            int j = --gen_reg;
-            /* simple type */
-            /* XXX: implicit cast ? */
-            if (j >= REGN) {
-                r = gv(RC_INT);
-                orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
-                args_size += 8;
-            }
-        }
-
-	/* And swap the argument back to it's original position.  */
-        tmp = vtop[0];
-	vtop[0] = vtop[-i];
-	vtop[-i] = tmp;
+    args_size = 0;
+    stack_adjust &= 15;
+    for (i = 0; i < nb_args;) {
+	mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+	if (!onstack[i]) {
+	    ++i;
+	    continue;
+	}
+        /* Possibly adjust stack to align SSE boundary.  We're processing
+	   args from right to left while allocating happens left to right
+	   (stack grows down), so the adjustment needs to happen _after_
+	   an argument that requires it.  */
+        if (stack_adjust) {
+	    o(0x50); /* push %rax; aka sub $8,%rsp */
+            args_size += 8;
+	    stack_adjust = 0;
+        }
+	if (onstack[i] == 2)
+	  stack_adjust = 1;
+
+	vrotb(i+1);
+
+	switch (vtop->type.t & VT_BTYPE) {
+	    case VT_STRUCT:
+		/* allocate the necessary size on stack */
+		o(0x48);
+		oad(0xec81, size); /* sub $xxx, %rsp */
+		/* generate structure store */
+		r = get_reg(RC_INT);
+		orex(1, r, 0, 0x89); /* mov %rsp, r */
+		o(0xe0 + REG_VALUE(r));
+		vset(&vtop->type, r | VT_LVAL, 0);
+		vswap();
+		vstore();
+		break;
+
+	    case VT_LDOUBLE:
+                gv(RC_ST0);
+                oad(0xec8148, size); /* sub $xxx, %rsp */
+                o(0x7cdb); /* fstpt 0(%rsp) */
+                g(0x24);
+                g(0x00);
+		break;
+
+	    case VT_FLOAT:
+	    case VT_DOUBLE:
+		assert(mode == x86_64_mode_sse);
+		r = gv(RC_FLOAT);
+		o(0x50); /* push $rax */
+		/* movq %xmmN, (%rsp) */
+		o(0xd60f66);
+		o(0x04 + REG_VALUE(r)*8);
+		o(0x24);
+		break;
+
+	    default:
+		assert(mode == x86_64_mode_integer);
+		/* simple type */
+		/* XXX: implicit cast ? */
+		r = gv(RC_INT);
+		orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
+		break;
+	}
+	args_size += size;
+
+	vpop();
+	--nb_args;
+	onstack++;
     }
 
@@ -933,33 +1358,47 @@
        may break these temporary registers. Let's use R10 and R11
        instead of them */
-    gen_reg = nb_reg_args;
-    sse_reg = nb_sse_args;
+    assert(gen_reg <= REGN);
+    assert(sse_reg <= 8);
     for(i = 0; i < nb_args; i++) {
-        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT ||
-            (vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
-        } else if (is_sse_float(vtop->type.t)) {
-            int j = --sse_reg;
-            if (j < 8) {
-                gv(RC_FLOAT); /* only one float register */
-                /* movaps %xmm0, %xmmN */
-                o(0x280f);
-                o(0xc0 + (sse_reg << 3));
-            }
-        } else {
-            int j = --gen_reg;
+        mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, &reg_count);
+        /* Alter stack entry type so that gv() knows how to treat it */
+        vtop->type = type;
+        if (mode == x86_64_mode_sse) {
+            if (reg_count == 2) {
+                sse_reg -= 2;
+                gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
+                if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
+                    /* movaps %xmm0, %xmmN */
+                    o(0x280f);
+                    o(0xc0 + (sse_reg << 3));
+                    /* movaps %xmm1, %xmmN */
+                    o(0x280f);
+                    o(0xc1 + ((sse_reg+1) << 3));
+                }
+            } else {
+                assert(reg_count == 1);
+                --sse_reg;
+                /* Load directly to register */
+                gv(RC_XMM0 << sse_reg);
+            }
+        } else if (mode == x86_64_mode_integer) {
             /* simple type */
             /* XXX: implicit cast ? */
-            if (j < REGN) {
-                int d = arg_regs[j];
-                r = gv(RC_INT);
-                if (j == 2 || j == 3)
-                    /* j=2: r10, j=3: r11 */
-                    d = j + 8;
-                orex(1,d,r,0x89); /* mov */
-                o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+            int d;
+            gen_reg -= reg_count;
+            r = gv(RC_INT);
+            d = arg_prepare_reg(gen_reg);
+            orex(1,d,r,0x89); /* mov */
+            o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+            if (reg_count == 2) {
+                d = arg_prepare_reg(gen_reg+1);
+                orex(1,d,vtop->r2,0x89); /* mov */
+                o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
             }
         }
         vtop--;
     }
+    assert(gen_reg == 0);
+    assert(sse_reg == 0);
 
     /* We shouldn't have many operands on the stack anymore, but the
@@ -977,5 +1416,6 @@
     }
 
-    oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
+    if (vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
+        oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
     gcall_or_jmp(0);
     if (args_size)
@@ -995,6 +1435,7 @@
 void gfunc_prolog(CType *func_type)
 {
-    int i, addr, align, size;
-    int param_index, param_addr, reg_param_index, sse_param_index;
+    X86_64_Mode mode;
+    int i, addr, align, size, reg_count;
+    int param_addr = 0, reg_param_index, sse_param_index;
     Sym *sym;
     CType *type;
@@ -1007,5 +1448,5 @@
     func_ret_sub = 0;
 
-    if (func_type->ref->c == FUNC_ELLIPSIS) {
+    if (sym->f.func_type == FUNC_ELLIPSIS) {
         int seen_reg_num, seen_sse_num, seen_stack_size;
         seen_reg_num = seen_sse_num = 0;
@@ -1016,22 +1457,22 @@
         while ((sym = sym->next) != NULL) {
             type = &sym->type;
-            if (is_sse_float(type->t)) {
-                if (seen_sse_num < 8) {
-                    seen_sse_num++;
-                } else {
-                    seen_stack_size += 8;
-                }
-            } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
-                size = type_size(type, &align);
-                size = (size + 7) & ~7;
-                seen_stack_size += size;
-            } else if ((type->t & VT_BTYPE) == VT_LDOUBLE) {
-                seen_stack_size += LDOUBLE_SIZE;
-            } else {
-                if (seen_reg_num < REGN) {
-                    seen_reg_num++;
-                } else {
-                    seen_stack_size += 8;
-                }
+            mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+            switch (mode) {
+            default:
+            stack_arg:
+                seen_stack_size = ((seen_stack_size + align - 1) & -align) + size;
+                break;
+                
+            case x86_64_mode_integer:
+                if (seen_reg_num + reg_count > REGN)
+		    goto stack_arg;
+		seen_reg_num += reg_count;
+                break;
+                
+            case x86_64_mode_sse:
+                if (seen_sse_num + reg_count > 8)
+		    goto stack_arg;
+		seen_sse_num += reg_count;
+                break;
             }
         }
@@ -1051,6 +1492,8 @@
         for (i = 0; i < 8; i++) {
             loc -= 16;
-            o(0xd60f66); /* movq */
-            gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+	    if (!tcc_state->nosse) {
+		o(0xd60f66); /* movq */
+		gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+	    }
             /* movq $0, loc+8(%rbp) */
             o(0x85c748);
@@ -1064,5 +1507,4 @@
 
     sym = func_type->ref;
-    param_index = 0;
     reg_param_index = 0;
     sse_param_index = 0;
@@ -1071,10 +1513,8 @@
        implicit pointer parameter */
     func_vt = sym->type;
-    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+    mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, &reg_count);
+    if (mode == x86_64_mode_memory) {
         push_arg_reg(reg_param_index);
-        param_addr = loc;
-
         func_vc = loc;
-        param_index++;
         reg_param_index++;
     }
@@ -1082,38 +1522,64 @@
     while ((sym = sym->next) != NULL) {
         type = &sym->type;
-        size = type_size(type, &align);
-        size = (size + 7) & ~7;
-        if (is_sse_float(type->t)) {
-            if (sse_param_index < 8) {
+        mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+        switch (mode) {
+        case x86_64_mode_sse:
+	    if (tcc_state->nosse)
+	        tcc_error("SSE disabled but floating point arguments used");
+            if (sse_param_index + reg_count <= 8) {
                 /* save arguments passed by register */
-                loc -= 8;
-                o(0xd60f66); /* movq */
-                gen_modrm(sse_param_index, VT_LOCAL, NULL, loc);
+                loc -= reg_count * 8;
                 param_addr = loc;
+                for (i = 0; i < reg_count; ++i) {
+                    o(0xd60f66); /* movq */
+                    gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
+                    ++sse_param_index;
+                }
             } else {
+                addr = (addr + align - 1) & -align;
                 param_addr = addr;
                 addr += size;
             }
-            sse_param_index++;
-
-        } else if ((type->t & VT_BTYPE) == VT_STRUCT ||
-                   (type->t & VT_BTYPE) == VT_LDOUBLE) {
+            break;
+            
+        case x86_64_mode_memory:
+        case x86_64_mode_x87:
+            addr = (addr + align - 1) & -align;
             param_addr = addr;
             addr += size;
-        } else {
-            if (reg_param_index < REGN) {
+            break;
+            
+        case x86_64_mode_integer: {
+            if (reg_param_index + reg_count <= REGN) {
                 /* save arguments passed by register */
-                push_arg_reg(reg_param_index);
+                loc -= reg_count * 8;
                 param_addr = loc;
+                for (i = 0; i < reg_count; ++i) {
+                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
+                    ++reg_param_index;
+                }
             } else {
+                addr = (addr + align - 1) & -align;
                 param_addr = addr;
-                addr += 8;
-            }
-            reg_param_index++;
+                addr += size;
+            }
+            break;
+        }
+	default: break; /* nothing to be done for x86_64_mode_none */
         }
         sym_push(sym->v & ~SYM_FIELD, type,
                  VT_LOCAL | VT_LVAL, param_addr);
-        param_index++;
-    }
+    }
+
+#ifdef CONFIG_TCC_BCHECK
+    /* leave some room for bound checking code */
+    if (tcc_state->do_bounds_check) {
+        func_bound_offset = lbounds_section->data_offset;
+        func_bound_ind = ind;
+        oad(0xb8, 0); /* lbound section pointer */
+	o(0xc78948);  /* mov  %rax,%rdi ## first arg in %rdi, this must be ptr */
+	oad(0xb8, 0); /* call to function */
+    }
+#endif
 }
 
@@ -1123,4 +1589,35 @@
     int v, saved_ind;
 
+#ifdef CONFIG_TCC_BCHECK
+    if (tcc_state->do_bounds_check
+	&& func_bound_offset != lbounds_section->data_offset)
+    {
+        addr_t saved_ind;
+        addr_t *bounds_ptr;
+        Sym *sym_data;
+
+        /* add end of table info */
+        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
+        *bounds_ptr = 0;
+
+        /* generate bound local allocation */
+        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
+                               func_bound_offset, lbounds_section->data_offset);
+        saved_ind = ind;
+        ind = func_bound_ind;
+        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+        ind = ind + 5 + 3;
+        gen_static_call(TOK___bound_local_new);
+        ind = saved_ind;
+
+        /* generate bound check local freeing */
+        o(0x5250); /* save returned value, if any */
+        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+        oad(0xb8, 0); /* mov xxx, %rax */
+        o(0xc78948);  /* mov %rax,%rdi # first arg in %rdi, this must be ptr */
+        gen_static_call(TOK___bound_local_delete);
+        o(0x585a); /* restore returned value, if any */
+    }
+#endif
     o(0xc9); /* leave */
     if (func_ret_sub == 0) {
@@ -1146,5 +1643,5 @@
 int gjmp(int t)
 {
-    return psym(0xe9, t);
+    return gjmp2(0xe9, t);
 }
 
@@ -1162,11 +1659,38 @@
 }
 
+ST_FUNC void gtst_addr(int inv, int a)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+	inv ^= (vtop--)->c.i;
+	a -= ind + 2;
+	if (a == (char)a) {
+	    g(inv - 32);
+	    g(a);
+	} else {
+	    g(0x0f);
+	    oad(inv - 16, a - 4);
+	}
+    } else if ((v & ~1) == VT_JMP) {
+	if ((v & 1) != inv) {
+	    gjmp_addr(a);
+	    gsym(vtop->c.i);
+	} else {
+	    gsym(vtop->c.i);
+	    o(0x05eb);
+	    gjmp_addr(a);
+	}
+	vtop--;
+    }
+}
+
 /* generate a test. set 'inv' to invert test. Stack entry is popped */
-int gtst(int inv, int t)
-{
-    int v, *p;
-
-    v = vtop->r & VT_VALMASK;
-    if (v == VT_CMP) {
+ST_FUNC int gtst(int inv, int t)
+{
+    int v = vtop->r & VT_VALMASK;
+
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
         /* fast case : can jump directly since flags are set */
 	if (vtop->c.i & 0x100)
@@ -1180,43 +1704,28 @@
 	       otherwise if unordered we don't want to jump.  */
 	    vtop->c.i &= ~0x100;
-	    if (!inv == (vtop->c.i != TOK_NE))
+            if (inv == (vtop->c.i == TOK_NE))
 	      o(0x067a);  /* jp +6 */
 	    else
 	      {
 	        g(0x0f);
-		t = psym(0x8a, t); /* jp t */
+		t = gjmp2(0x8a, t); /* jp t */
 	      }
 	  }
         g(0x0f);
-        t = psym((vtop->c.i - 16) ^ inv, t);
+        t = gjmp2((vtop->c.i - 16) ^ inv, t);
     } else if (v == VT_JMP || v == VT_JMPI) {
         /* && or || optimization */
         if ((v & 1) == inv) {
             /* insert vtop->c jump list in t */
-            p = &vtop->c.i;
-            while (*p != 0)
-                p = (int *)(cur_text_section->data + *p);
-            *p = t;
-            t = vtop->c.i;
+            uint32_t n1, n = vtop->c.i;
+            if (n) {
+                while ((n1 = read32le(cur_text_section->data + n)))
+                    n = n1;
+                write32le(cur_text_section->data + n, t);
+                t = vtop->c.i;
+            }
         } else {
             t = gjmp(t);
             gsym(vtop->c.i);
-        }
-    } else {
-        if (is_float(vtop->type.t) ||
-            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
-            vpushi(0);
-            gen_op(TOK_NE);
-        }
-        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-            /* constant jmp optimization */
-            if ((vtop->c.i != 0) != inv)
-                t = gjmp(t);
-        } else {
-            v = gv(RC_INT);
-            orex(0,v,v,0x85);
-            o(0xc0 + REG_VALUE(v) * 9);
-            g(0x0f);
-            t = psym(0x85 ^ inv, t);
         }
     }
@@ -1240,5 +1749,5 @@
         opc = 0;
     gen_op8:
-        if (cc && (!ll || (int)vtop->c.ll == vtop->c.ll)) {
+        if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) {
             /* constant case */
             vswap();
@@ -1359,5 +1868,5 @@
 
 /* generate a floating point operation 'v = t1 op t2' instruction. The
-   two operands are guaranted to have the same floating point type */
+   two operands are guaranteed to have the same floating point type */
 /* XXX: need to use ST1 too */
 void gen_opf(int op)
@@ -1401,5 +1910,8 @@
             if (swapped)
                 o(0xc9d9); /* fxch %st(1) */
-            o(0xe9da); /* fucompp */
+            if (op == TOK_EQ || op == TOK_NE)
+                o(0xe9da); /* fucompp */
+            else
+                o(0xd9de); /* fcompp */
             o(0xe0df); /* fnstsw %ax */
             if (op == TOK_EQ) {
@@ -1445,5 +1957,5 @@
             }
             ft = vtop->type.t;
-            fc = vtop->c.ul;
+            fc = vtop->c.i;
             o(0xde); /* fxxxp %st, %st(1) */
             o(0xc1 + (a << 3));
@@ -1454,5 +1966,5 @@
             /* if saved lvalue, then we must reload it */
             r = vtop->r;
-            fc = vtop->c.ul;
+            fc = vtop->c.i;
             if ((r & VT_VALMASK) == VT_LLOCAL) {
                 SValue v1;
@@ -1460,5 +1972,5 @@
                 v1.type.t = VT_PTR;
                 v1.r = VT_LOCAL | VT_LVAL;
-                v1.c.ul = fc;
+                v1.c.i = fc;
                 load(r, &v1);
                 fc = 0;
@@ -1478,18 +1990,20 @@
 
             if (swapped) {
-                o(0x7e0ff3); /* movq */
-                gen_modrm(1, r, vtop->sym, fc);
-
-                if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
-                    o(0x66);
-                }
-                o(0x2e0f); /* ucomisd %xmm0, %xmm1 */
-                o(0xc8);
+                gv(RC_FLOAT);
+                vswap();
+            }
+            assert(!(vtop[-1].r & VT_LVAL));
+            
+            if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+                o(0x66);
+            if (op == TOK_EQ || op == TOK_NE)
+                o(0x2e0f); /* ucomisd */
+            else
+                o(0x2f0f); /* comisd */
+
+            if (vtop->r & VT_LVAL) {
+                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
             } else {
-                if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
-                    o(0x66);
-                }
-                o(0x2e0f); /* ucomisd */
-                gen_modrm(0, r, vtop->sym, fc);
+                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
             }
 
@@ -1498,9 +2012,5 @@
             vtop->c.i = op | 0x100;
         } else {
-            /* no memory reference possible for long double operations */
-            if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
-                load(TREG_XMM0, vtop);
-                swapped = !swapped;
-            }
+            assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
             switch(op) {
             default:
@@ -1519,45 +2029,40 @@
             }
             ft = vtop->type.t;
-            fc = vtop->c.ul;
-            if ((ft & VT_BTYPE) == VT_LDOUBLE) {
-                o(0xde); /* fxxxp %st, %st(1) */
-                o(0xc1 + (a << 3));
+            fc = vtop->c.i;
+            assert((ft & VT_BTYPE) != VT_LDOUBLE);
+            
+            r = vtop->r;
+            /* if saved lvalue, then we must reload it */
+            if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_PTR;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.i = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+            
+            assert(!(vtop[-1].r & VT_LVAL));
+            if (swapped) {
+                assert(vtop->r & VT_LVAL);
+                gv(RC_FLOAT);
+                vswap();
+            }
+            
+            if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                o(0xf2);
             } else {
-                /* if saved lvalue, then we must reload it */
-                r = vtop->r;
-                if ((r & VT_VALMASK) == VT_LLOCAL) {
-                    SValue v1;
-                    r = get_reg(RC_INT);
-                    v1.type.t = VT_PTR;
-                    v1.r = VT_LOCAL | VT_LVAL;
-                    v1.c.ul = fc;
-                    load(r, &v1);
-                    fc = 0;
-                }
-                if (swapped) {
-                    /* movq %xmm0,%xmm1 */
-                    o(0x7e0ff3);
-                    o(0xc8);
-                    load(TREG_XMM0, vtop);
-                    /* subsd  %xmm1,%xmm0 (f2 0f 5c c1) */
-                    if ((ft & VT_BTYPE) == VT_DOUBLE) {
-                        o(0xf2);
-                    } else {
-                        o(0xf3);
-                    }
-                    o(0x0f);
-                    o(0x58 + a);
-                    o(0xc1);
-                } else {
-                    if ((ft & VT_BTYPE) == VT_DOUBLE) {
-                        o(0xf2);
-                    } else {
-                        o(0xf3);
-                    }
-                    o(0x0f);
-                    o(0x58 + a);
-                    gen_modrm(0, r, vtop->sym, fc);
-                }
-            }
+                o(0xf3);
+            }
+            o(0x0f);
+            o(0x58 + a);
+            
+            if (vtop->r & VT_LVAL) {
+                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
+            } else {
+                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
+            }
+
             vtop--;
         }
@@ -1594,7 +2099,7 @@
         vtop->r = TREG_ST0;
     } else {
-        save_reg(TREG_XMM0);
+        int r = get_reg(RC_FLOAT);
         gv(RC_INT);
-        o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT));
+        o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
         if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
             (VT_INT | VT_UNSIGNED) ||
@@ -1603,6 +2108,6 @@
         }
         o(0x2a0f);
-        o(0xc0 + (vtop->r & VT_VALMASK)); /* cvtsi2sd */
-        vtop->r = TREG_XMM0;
+        o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
+        vtop->r = r;
     }
 }
@@ -1616,13 +2121,17 @@
     bt = ft & VT_BTYPE;
     tbt = t & VT_BTYPE;
-
+    
     if (bt == VT_FLOAT) {
         gv(RC_FLOAT);
         if (tbt == VT_DOUBLE) {
-            o(0xc0140f); /* unpcklps */
-            o(0xc05a0f); /* cvtps2pd */
+            o(0x140f); /* unpcklps */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+            o(0x5a0f); /* cvtps2pd */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
         } else if (tbt == VT_LDOUBLE) {
+            save_reg(RC_ST0);
             /* movss %xmm0,-0x10(%rsp) */
-            o(0x44110ff3);
+            o(0x110ff3);
+            o(0x44 + REG_VALUE(vtop->r)*8);
             o(0xf024);
             o(0xf02444d9); /* flds -0x10(%rsp) */
@@ -1632,9 +2141,13 @@
         gv(RC_FLOAT);
         if (tbt == VT_FLOAT) {
-            o(0xc0140f66); /* unpcklpd */
-            o(0xc05a0f66); /* cvtpd2ps */
+            o(0x140f66); /* unpcklpd */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+            o(0x5a0f66); /* cvtpd2ps */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
         } else if (tbt == VT_LDOUBLE) {
+            save_reg(RC_ST0);
             /* movsd %xmm0,-0x10(%rsp) */
-            o(0x44110ff2);
+            o(0x110ff2);
+            o(0x44 + REG_VALUE(vtop->r)*8);
             o(0xf024);
             o(0xf02444dd); /* fldl -0x10(%rsp) */
@@ -1642,17 +2155,21 @@
         }
     } else {
+        int r;
         gv(RC_ST0);
+        r = get_reg(RC_FLOAT);
         if (tbt == VT_DOUBLE) {
             o(0xf0245cdd); /* fstpl -0x10(%rsp) */
             /* movsd -0x10(%rsp),%xmm0 */
-            o(0x44100ff2);
+            o(0x100ff2);
+            o(0x44 + REG_VALUE(r)*8);
             o(0xf024);
-            vtop->r = TREG_XMM0;
+            vtop->r = r;
         } else if (tbt == VT_FLOAT) {
             o(0xf0245cd9); /* fstps -0x10(%rsp) */
             /* movss -0x10(%rsp),%xmm0 */
-            o(0x44100ff3);
+            o(0x100ff3);
+            o(0x44 + REG_VALUE(r)*8);
             o(0xf024);
-            vtop->r = TREG_XMM0;
+            vtop->r = r;
         }
     }
@@ -1685,5 +2202,5 @@
     }
     orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
-    o(0xc0 + (REG_VALUE(r) << 3));
+    o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8);
     vtop->r = r;
 }
@@ -1695,4 +2212,44 @@
     vtop--;
 }
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    /* mov %rsp,addr(%rbp)*/
+    gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+#ifdef TCC_TARGET_PE
+/* Save result of gen_vla_alloc onto the stack */
+ST_FUNC void gen_vla_result(int addr) {
+    /* mov %rax,addr(%rbp)*/
+    gen_modrm64(0x89, TREG_RAX, VT_LOCAL, NULL, addr);
+}
+#endif
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+    /* alloca does more than just adjust %rsp on Windows */
+    vpush_global_sym(&func_old_type, TOK_alloca);
+    vswap(); /* Move alloca ref past allocation size */
+    gfunc_call(1);
+#else
+    int r;
+    r = gv(RC_INT); /* allocation size */
+    /* sub r,%rsp */
+    o(0x2b48);
+    o(0xe0 | REG_VALUE(r));
+    /* We align to 16 bytes rather than align */
+    /* and ~15, %rsp */
+    o(0xf0e48348);
+    vpop();
+#endif
+}
+
 
 /* end of x86-64 code generator */
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c	(revision 331)
@@ -0,0 +1,298 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_X86_64
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_X86_64_32S
+#define R_DATA_PTR  R_X86_64_64
+#define R_JMP_SLOT  R_X86_64_JUMP_SLOT
+#define R_GLOB_DAT  R_X86_64_GLOB_DAT
+#define R_COPY      R_X86_64_COPY
+#define R_RELATIVE  R_X86_64_RELATIVE
+
+#define R_NUM       R_X86_64_NUM
+
+#define ELF_START_ADDR 0x400000
+#define ELF_PAGE_SIZE  0x200000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+        case R_X86_64_GOTPC32:
+        case R_X86_64_GOTPC64:
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+        case R_X86_64_GOTTPOFF:
+        case R_X86_64_GOT32:
+        case R_X86_64_GOT64:
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_COPY:
+        case R_X86_64_RELATIVE:
+        case R_X86_64_GOTOFF64:
+            return 0;
+
+        case R_X86_64_PC32:
+        case R_X86_64_PC64:
+        case R_X86_64_PLT32:
+        case R_X86_64_PLTOFF64:
+        case R_X86_64_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_JUMP_SLOT:
+        case R_X86_64_COPY:
+        case R_X86_64_RELATIVE:
+            return NO_GOTPLT_ENTRY;
+
+	/* The following relocs wouldn't normally need GOT or PLT
+	   slots, but we need them for simplicity in the link
+	   editor part.  See our caller for comments.  */
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+        case R_X86_64_PC32:
+        case R_X86_64_PC64:
+            return AUTO_GOTPLT_ENTRY;
+
+        case R_X86_64_GOTTPOFF:
+            return BUILD_GOT_ONLY;
+
+        case R_X86_64_GOT32:
+        case R_X86_64_GOT64:
+        case R_X86_64_GOTPC32:
+        case R_X86_64_GOTPC64:
+        case R_X86_64_GOTOFF64:
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+        case R_X86_64_PLT32:
+        case R_X86_64_PLTOFF64:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    int modrm;
+    unsigned plt_offset, relofs;
+
+    modrm = 0x25;
+
+    /* empty PLT: create PLT0 entry that pushes the library identifier
+       (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+       (GOT + 2 * PTR_SIZE) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 16);
+        p[0] = 0xff; /* pushl got + PTR_SIZE */
+        p[1] = modrm + 0x10;
+        write32le(p + 2, PTR_SIZE);
+        p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+        p[7] = modrm;
+        write32le(p + 8, PTR_SIZE * 2);
+    }
+    plt_offset = plt->data_offset;
+
+    /* The PLT slot refers to the relocation entry it needs via offset.
+       The reloc entry is created below, so its offset is the current
+       data_offset */
+    relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+    /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+    p = section_ptr_add(plt, 16);
+    p[0] = 0xff; /* jmp *(got + x) */
+    p[1] = modrm;
+    write32le(p + 2, got_offset);
+    p[6] = 0x68; /* push $xxx */
+    /* On x86-64, the relocation is referred to by _index_ */
+    write32le(p + 7, relofs / sizeof (ElfW_Rel));
+    p[11] = 0xe9; /* jmp plt_start */
+    write32le(p + 12, -(plt->data_offset));
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
+        add32le(p + 2, x);
+        add32le(p + 8, x - 6);
+        p += 16;
+        while (p < p_end) {
+            add32le(p + 2, x + s1->plt->data - p);
+            p += 16;
+        }
+    }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+    qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index, esym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+
+    switch (type) {
+        case R_X86_64_64:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                qrel->r_offset = rel->r_offset;
+                if (esym_index) {
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
+                    qrel->r_addend = rel->r_addend;
+                    qrel++;
+                    break;
+                } else {
+                    qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                    qrel->r_addend = read64le(ptr) + val;
+                    qrel++;
+                }
+            }
+            add64le(ptr, val);
+            break;
+        case R_X86_64_32:
+        case R_X86_64_32S:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* XXX: this logic may depend on TCC's codegen
+                   now TCC uses R_X86_64_32 even for a 64bit pointer */
+                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                /* Use sign extension! */
+                qrel->r_addend = (int)read32le(ptr) + val;
+                qrel++;
+            }
+            add32le(ptr, val);
+            break;
+
+        case R_X86_64_PC32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
+                    /* Use sign extension! */
+                    qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
+                    qrel++;
+                    break;
+                }
+            }
+            goto plt32pc32;
+
+        case R_X86_64_PLT32:
+            /* fallthrough: val already holds the PLT slot address */
+
+        plt32pc32:
+        {
+            long long diff;
+            diff = (long long)val - addr;
+            if (diff < -2147483648LL || diff > 2147483647LL) {
+                tcc_error("internal error: relocation failed");
+            }
+            add32le(ptr, diff);
+        }
+            break;
+
+        case R_X86_64_PLTOFF64:
+            add64le(ptr, val - s1->got->sh_addr + rel->r_addend);
+            break;
+
+        case R_X86_64_PC64:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64);
+                    qrel->r_addend = read64le(ptr) + rel->r_addend;
+                    qrel++;
+                    break;
+                }
+            }
+            add64le(ptr, val - addr);
+            break;
+
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_JUMP_SLOT:
+            /* They don't need addend */
+            write64le(ptr, val - rel->r_addend);
+            break;
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+            add32le(ptr, s1->got->sh_addr - addr +
+                         s1->sym_attrs[sym_index].got_offset - 4);
+            break;
+        case R_X86_64_GOTPC32:
+            add32le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+            break;
+        case R_X86_64_GOTPC64:
+            add64le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+            break;
+        case R_X86_64_GOTTPOFF:
+            add32le(ptr, val - s1->got->sh_addr);
+            break;
+        case R_X86_64_GOT32:
+            /* we load the got offset */
+            add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+            break;
+        case R_X86_64_GOT64:
+            /* we load the got offset */
+            add64le(ptr, s1->sym_attrs[sym_index].got_offset);
+            break;
+        case R_X86_64_GOTOFF64:
+            add64le(ptr, val - s1->got->sh_addr);
+            break;
+        case R_X86_64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            break;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
