From da8c62f75d893449e232944fc62566c020b4d010 Mon Sep 17 00:00:00 2001
From: grischka <grischka>
Date: Wed, 11 Oct 2017 18:13:43 +0200
Subject: [PATCH] various stuff

win32/Makefile ("for cygwin") removed
- On cygwin, the normal ./configure && make can be used with either
  cygwin's "GCC for Win32 Toolchain"
      ./configure --cross-prefix=i686-w64-mingw32-
  or with an existing tcc:
      ./configure --cc=<old-tccdir>/tcc.exe

tcctest.c:
- exclude test_high_clobbers() on _WIN64 (does not work)

tests2/95_bitfield.c:
- use 'signed char' for ARM (where default 'char' is unsigned)

tests:
- remove -I "expr" diff option to allow tests with
  busybox-diff.

libtcc.c, tcc.c:
- removed -iwithprefix option.  It is supposed to be
  combined with -iprefix which we don't have either.

tccgen.c:
- fix assignments and return of 'void', as in
     void f() {
         void *p, *q;
         *p = *q:
         return *p;
     }
  This appears to be allowed but should do nothing.

tcc.h, libtcc.c, tccpp.c:
- Revert "Introduce VIP sysinclude paths which are always searched first"
  This reverts commit 1d5e386b0a78393ac6b670c209a185849ec798a1.

  The patch was giving tcc's system includes priority over -I which
  is not how it should be.

tccelf.c:
- add DT_TEXTREL tag only if text relocations are actually
  used (which is likely not the case on x86_64)
- prepare_dynamic_rel(): avoid relocation of unresolved
  (weak) symbols

tccrun.c:
- for HAVE_SELINUX, use two mappings to the same (real) file.
  (it was so once except the RX mapping wasn't used at all).

tccpe.c:
- fix relocation constant used for x86_64 (by Andrei E. Warentin)
- #ifndef _WIN32 do "chmod 755 ..." to get runnable exes on cygwin.

tccasm.c:
- keep forward asm labels static, otherwise they will endup
  in dynsym eventually.

configure, Makefile:
- mingw32: respect ./configure options --bindir --docdir --libdir
- allow overriding tcc when building libtcc1.a and libtcc.def with
      make XTCC=<tcc program to use>
- use $(wildcard ...) for install to allow installing just
  a cross compiler for example
      make cross-arm
      make install
- use name <target>-libtcc1.a

build-tcc.bat:
- add  options: -clean, -b bindir
---
 Makefile                             | 113 +++++++-------
 configure                            |  68 ++++-----
 include/stdarg.h                     |   5 -
 lib/Makefile                         |  14 +-
 libtcc.c                             |  39 ++---
 libtcc.h                             |   3 -
 tcc.c                                |   5 +-
 tcc.h                                |  35 ++---
 tccasm.c                             |   2 +
 tccelf.c                             | 218 ++++++++++++---------------
 tccgen.c                             |  38 +++--
 tccpe.c                              |  35 ++---
 tccpp.c                              |  49 +++---
 tccrun.c                             |  53 ++++---
 tcctok.h                             |  16 +-
 tests/Makefile                       |   4 +
 tests/pp/13.expect                   |   1 -
 tests/pp/15.c                        |   4 +-
 tests/pp/15.expect                   |   2 -
 tests/pp/Makefile                    |   4 +-
 tests/tcctest.c                      |   7 +-
 tests/tests2/95_bitfields.c          |   2 +-
 tests/tests2/96_nodata_wanted.c      |   2 +-
 tests/tests2/96_nodata_wanted.expect |   2 -
 tests/tests2/Makefile                |   2 +-
 win32/Makefile                       | 148 ------------------
 win32/build-tcc.bat                  | 105 +++++++------
 win32/lib/crt1.c                     |  21 +--
 win32/lib/wincrt1.c                  |  80 ++++------
 win32/tcc-win32.txt                  |  19 +--
 30 files changed, 433 insertions(+), 663 deletions(-)
 delete mode 100644 win32/Makefile

diff --git a/Makefile b/Makefile
index 3a5c0004..88881499 100644
--- a/Makefile
+++ b/Makefile
@@ -98,16 +98,17 @@ TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
 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),libtcc1-$X.a)
+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 ;
+cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
 
-install: install$(CFGWIN)
-uninstall: uninstall$(CFGWIN)
+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
@@ -143,10 +144,10 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx))
 
 ifneq ($(X),)
 ifeq ($(CONFIG_WIN32),yes)
-DEF-win += -DTCC_LIBTCC1="\"libtcc1-$T.a\""
-DEF-unx += -DTCC_LIBTCC1="\"lib/libtcc1-$T.a\""
+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
 else
-DEF-all += -DTCC_LIBTCC1="\"libtcc1-$T.a\""
+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
 DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
 endif
 endif
@@ -217,21 +218,22 @@ libtcc.so: LDFLAGS+=-fPIC
 # windows dynamic libtcc library
 libtcc.dll : $(LIBTCC_OBJ)
 	$(CC) -shared -o $@ $^ $(LDFLAGS)
-
-libtcc.def : libtcc.dll tcc$(EXESUF)
-	./tcc$(EXESUF) -impdef $< -o $@
-
 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 : tcc$(EXESUF) FORCE
-	@$(MAKE) -C lib DEFINES="$(DEF-$T)"
+	@$(MAKE) -C lib DEFINES='$(DEF-$T)'
 
 # Cross libtcc1.a
-libtcc1-%.a : %-tcc$(EXESUF) FORCE
-	@$(MAKE) -C lib DEFINES="$(DEF-$*)" CROSS_TARGET=$*
+%-libtcc1.a : %-tcc$(EXESUF) FORCE
+	@$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
 
-.PRECIOUS: libtcc1-%.a
+.PRECIOUS: %-libtcc1.a
 FORCE:
 
 # --------------------------------------------------------------------------
@@ -252,35 +254,29 @@ tcc-doc.info: tcc-doc.texi
 INSTALL = install -m644
 INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
 STRIP_yes = -s
-install-strip: install
-install-strip: CONFIG_strip = yes
 
-TRY-INSTALL = $(if $(wildcard $1),mkdir -p $2 && $(INSTALL) $1 $2)
-LIBTCC1_W = $(wildcard $(filter %-win32.a %-wince.a,$(LIBTCC1_CROSS)))
-LIBTCC1_U = $(wildcard $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS)))
-PROGS_X = $(wildcard $(PROGS_CROSS))
+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:
-	mkdir -p "$(bindir)"
-	$(INSTALLBIN) $(PROGS) $(PROGS_X) "$(bindir)"
-	mkdir -p "$(tccdir)"
-	$(INSTALL) $(LIBTCC1) $(LIBTCC1_U) "$(tccdir)"
-	mkdir -p "$(tccdir)/include"
-	$(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include"
-	mkdir -p "$(libdir)"
-	$(INSTALL) $(LIBTCC) "$(libdir)"
-	mkdir -p "$(includedir)"
-	$(INSTALL) $(TOPSRC)/libtcc.h "$(includedir)"
-	$(call TRY-INSTALL,tcc.1,"$(mandir)/man1")
-	$(call TRY-INSTALL,tcc-doc.info,"$(infodir)")
-	$(call TRY-INSTALL,tcc-doc.html,"$(docdir)")
-ifneq "$(LIBTCC1_W)" ""
-	mkdir -p "$(tccdir)/win32/lib"
-	$(INSTALL) $(TOPSRC)/win32/lib/*.def $(LIBTCC1_W) "$(tccdir)/win32/lib"
-	mkdir -p "$(tccdir)/win32/include"
-	cp -r $(TOPSRC)/win32/include/. "$(tccdir)/win32/include"
-	$(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/win32/include"
+	$(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
@@ -293,32 +289,31 @@ uninstall-unx:
 
 # install progs & libs on windows
 install-win:
-	mkdir -p "$(tccdir)"
-	$(INSTALL) $(PROGS) $(subst libtcc.a,,$(LIBTCC)) $(PROGS_X) "$(tccdir)"
-	mkdir -p "$(tccdir)/lib"
-	$(INSTALL) $(TOPSRC)/win32/lib/*.def "$(tccdir)/lib"
-	$(INSTALL) libtcc1.a $(LIBTCC1_W) "$(tccdir)/lib"
-	mkdir -p "$(tccdir)/include"
-	cp -r $(TOPSRC)/win32/include/. "$(tccdir)/include"
-	$(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/include"
-	mkdir -p "$(tccdir)/examples"
-	cp -r $(TOPSRC)/win32/examples/. "$(tccdir)/examples"
-	$(INSTALL) $(TOPSRC)/tests/libtcc_test.c "$(tccdir)/examples"
-	mkdir -p "$(tccdir)/libtcc"
-	$(INSTALL) $(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)) "$(tccdir)/libtcc"
-	mkdir -p "$(tccdir)/doc"
-	$(INSTALL) $(TOPSRC)/win32/tcc-win32.txt $(wildcard tcc-doc.html) "$(tccdir)/doc"
-ifneq "$(LIBTCC1_U)" ""
-	$(INSTALL) $(LIBTCC1_U) "$(tccdir)/lib"
-	mkdir -p "$(tccdir)/lib/include";
-	$(INSTALL) $(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h "$(tccdir)/lib/include"
+	$(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 ($(CONFIG_WIN32)-$(shell which install >/dev/null 2>&1 || echo no),yes-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)"
 
 # --------------------------------------------------------------------------
diff --git a/configure b/configure
index 78f2072e..1ee3acb8 100755
--- a/configure
+++ b/configure
@@ -56,7 +56,6 @@ case $targetos in
     DLLSUF=".dylib"
     ;;
   MINGW*|MSYS*|CYGWIN*)
-    confvars="$confvars WIN32"
     mingw32=yes
     ;;
   DragonFly|OpenBSD|FreeBSD|NetBSD)
@@ -126,8 +125,6 @@ for opt do
   ;;
   --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
   ;;
-  --enable-mingw32) confvars="$confvars WIN32"; mingw32="yes"
-  ;;
   --enable-cross) confvars="$confvars cross"
   ;;
   --disable-static) confvars="$confvars static=no"
@@ -142,6 +139,8 @@ for opt do
   ;;
   --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"
@@ -216,22 +215,12 @@ if test "$mingw32" = "yes" ; then
     if test "$cc" = gcc; then
       test -z "$LDFLAGS" && LDFLAGS="-static"
     fi
-    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"
+    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"
@@ -263,12 +252,11 @@ else
     if test x"$tccdir" = x""; then
       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
 cat << EOF
 Usage: configure [options]
@@ -302,7 +290,6 @@ Advanced options (experts only):
   --enable-static          make libtcc.a instead of libtcc.dll (win32)
   --disable-rpath          disable use of -rpath with the above
   --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
-  --enable-mingw32         build windows version on linux with mingw32
   --enable-cross           build cross compilers
   --with-selinux           use mmap for executable memory (with tcc -run)
   --sysincludepaths=...    specify system include paths, colon separated
@@ -310,7 +297,7 @@ Advanced options (experts only):
   --crtprefix=...          specify locations of crt?.o, colon separated
   --elfinterp=...          specify elf interpreter
   --triplet=...            specify system library/include directory triplet
-  --config-uClibc,-musl... enable specific configuration for some systems
+  --config-uClibc,-musl,-mingw32... enable system specific configurations
 EOF
 #echo "NOTE: The object files are build at the place where configure is launched"
 exit 1
@@ -320,15 +307,14 @@ cc="${cross_prefix}${cc}"
 ar="${cross_prefix}${ar}"
 strip="${cross_prefix}${strip}"
 
-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
-  gcc_major="$($CONFTEST version)"
-  gcc_minor="$($CONFTEST minor)"
-fi
-
 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
+    gcc_major="$($CONFTEST version)"
+    gcc_minor="$($CONFTEST minor)"
+  fi
   bigendian="$($CONFTEST bigendian)"
   if test "$mingw32" = "no" ; then
 
@@ -401,13 +387,13 @@ fi
 
 fcho() { if test -n "$2"; then echo "$1$2"; fi }
 
-echo "Binary  directory   $bindir"
-echo "TinyCC directory    $tccdir"
-echo "Library directory   $libdir"
-echo "Include directory   $includedir"
-echo "Manual directory    $mandir"
-echo "Info directory      $infodir"
-echo "Doc directory       $docdir"
+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)"
@@ -471,8 +457,6 @@ print_mak CONFIG_LDDIR "$tcc_lddir"
 print_mak CONFIG_TRIPLET "$triplet"
 print_mak_int TCC_CPU_VERSION "$cpuver"
 
-echo "#define GCC_MAJOR $gcc_major" >> $TMPH
-echo "#define GCC_MINOR $gcc_minor" >> $TMPH
 if test "$cpu" = "aarch64" ; then
   echo "ARCH=arm64" >> config.mak
 else
diff --git a/include/stdarg.h b/include/stdarg.h
index a42acae5..10ce733b 100644
--- a/include/stdarg.h
+++ b/include/stdarg.h
@@ -16,12 +16,7 @@ typedef struct {
     char *reg_save_area;
 } __va_list_struct;
 
-/* Avoid conflicting definition for va_list on musl libc */
-#if !defined __DEFINED_va_list || defined __TCC_NEEDS_va_list
 typedef __va_list_struct va_list[1];
-#undef __DEFINED_va_list
-#define __DEFINED_va_list
-#endif
 
 void __va_start(__va_list_struct *ap, void *fp);
 void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
diff --git a/lib/Makefile b/lib/Makefile
index 3b582d4e..0c1ec54d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -7,20 +7,20 @@ include $(TOP)/Makefile
 VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
 T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
 X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
-BIN = $(TOP)/libtcc1$(if $(CROSS_TARGET),-$(CROSS_TARGET)).a
+BIN = $(TOP)/$(X)libtcc1.a
 
-TCC = $(TOP)/$(X)tcc$(EXESUF)
-XCC = $(TCC)
-XAR = $(TCC) -ar
+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>lib-usegcc=yes
-armlib-usegcc ?= no
+# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
+arm-libtcc1-usegcc ?= no
 
-ifeq "$($(X)$(T)lib-usegcc)" "yes"
+ifeq "$($(T)-libtcc1-usegcc)" "yes"
  XCC = $(CC)
  XAR = $(AR)
  XFLAGS = $(CFLAGS) -fPIC
diff --git a/libtcc.c b/libtcc.c
index 9ef538e3..43a07ef2 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -104,10 +104,8 @@ static void tcc_set_lib_path_w32(TCCState *s)
     char path[1024], *p;
     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);
 }
@@ -440,7 +438,7 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
         CString str;
 
         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')
@@ -804,6 +802,8 @@ LIBTCCAPI TCCState *tcc_new(void)
 #endif
 #elif defined(TCC_TARGET_ARM64)
     tcc_define_symbol(s, "__aarch64__", NULL);
+#elif defined TCC_TARGET_C67
+    tcc_define_symbol(s, "__C67__", NULL);
 #endif
 
 #ifdef TCC_TARGET_PE
@@ -827,13 +827,13 @@ LIBTCCAPI TCCState *tcc_new(void)
 # if defined(__FreeBSD_kernel__)
     tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
 # endif
-#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 PTR_SIZE == 4
@@ -853,14 +853,6 @@ LIBTCCAPI TCCState *tcc_new(void)
     tcc_define_symbol(s, "__LP64__", NULL);
 #endif
 
-#if defined(TCC_MUSL)
-    tcc_define_symbol(s, "__TCC_NEEDS_va_list", "");
-    tcc_define_symbol(s, "__builtin_va_list", "va_list");
-    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 */
-
 #ifdef TCC_TARGET_PE
     tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
     tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
@@ -887,6 +879,11 @@ LIBTCCAPI TCCState *tcc_new(void)
     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 */
@@ -906,7 +903,6 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
 
     /* free include paths */
     dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
-    dynarray_reset(&s1->tccinclude_paths, &s1->nb_tccinclude_paths);
     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);
@@ -947,7 +943,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
     if (!s->nostdinc) {
         /* default include paths */
         /* -isystem paths have already been handled */
-        tcc_add_tccinclude_path(s, CONFIG_TCC_TCCINCLUDEPATHS);
         tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
     }
 
@@ -985,12 +980,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
     return 0;
 }
 
-LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname)
-{
-    tcc_split_path(s, &s->tccinclude_paths, &s->nb_tccinclude_paths, pathname);
-    return 0;
-}
-
 LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
 {
     tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
@@ -1547,7 +1536,6 @@ static const TCCOption tcc_options[] = {
     { "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 },
-    { "iwithprefix", TCC_OPTION_iwithprefix, TCC_OPTION_HAS_ARG },
     { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
     { "nostdinc", TCC_OPTION_nostdinc, 0 },
     { "nostdlib", TCC_OPTION_nostdlib, 0 },
@@ -1682,7 +1670,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
     int last_o = -1;
     int x;
     CString linker_arg; /* collect -Wl options */
-    char buf[1024];
     int tool = 0, arg_start = 0, noaction = optind;
     char **argv = *pargv;
     int argc = *pargc;
@@ -1827,10 +1814,6 @@ reparse:
         case TCC_OPTION_isystem:
             tcc_add_sysinclude_path(s, optarg);
             break;
-        case TCC_OPTION_iwithprefix:
-            snprintf(buf, sizeof buf, "{B}/%s", optarg);
-            tcc_add_tccinclude_path(s, buf);
-            break;
 	case TCC_OPTION_include:
 	    dynarray_add(&s->cmd_include_files,
 			 &s->nb_cmd_include_files, tcc_strdup(optarg));
diff --git a/libtcc.h b/libtcc.h
index fc37251c..a1b31e30 100644
--- a/libtcc.h
+++ b/libtcc.h
@@ -32,9 +32,6 @@ LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
 /*****************************/
 /* preprocessor */
 
-/* add in tcc include path, searched before anything else */
-LIBTCCAPI int tcc_add_tccinclude_path(TCCState *s, const char *pathname);
-
 /* add include path */
 LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
 
diff --git a/tcc.c b/tcc.c
index 53ee84ed..c347a06e 100644
--- a/tcc.c
+++ b/tcc.c
@@ -86,7 +86,6 @@ static const char help2[] =
     "  -Wp,-opt                      same as -opt\n"
     "  -include file                 include 'file' above each input file\n"
     "  -isystem dir                  add 'dir' to system include path\n"
-    "  -iwithprefix dir              set tcc's private include/library subdir\n"
     "  -static                       link to static libraries (not recommended)\n"
     "  -dumpversion                  print version\n"
     "  -print-search-dirs            print search paths\n"
@@ -181,7 +180,6 @@ static void print_search_dirs(TCCState *s)
 {
     printf("install: %s\n", s->tcc_lib_path);
     /* print_dirs("programs", NULL, 0); */
-    print_dirs("tcc-include", s->tccinclude_paths, s->nb_tccinclude_paths);
     print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
     print_dirs("libraries", s->library_paths, s->nb_library_paths);
 #ifndef TCC_TARGET_PE
@@ -197,7 +195,7 @@ static void set_environment(TCCState *s)
 
     path = getenv("C_INCLUDE_PATH");
     if(path != NULL) {
-        tcc_add_include_path(s, path);
+        tcc_add_sysinclude_path(s, path);
     }
     path = getenv("CPATH");
     if(path != NULL) {
@@ -278,6 +276,7 @@ redo:
             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;
diff --git a/tcc.h b/tcc.h
index 32bb6082..da26298f 100644
--- a/tcc.h
+++ b/tcc.h
@@ -101,10 +101,12 @@ extern long double strtold (const char *__nptr, char **__endptr);
 # 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
 
 /* -------------------------------------------- */
@@ -195,21 +197,14 @@ extern long double strtold (const char *__nptr, char **__endptr);
 /* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */
 
 /* system include paths */
-#ifndef CONFIG_TCC_TCCINCLUDEPATHS
-# ifdef TCC_TARGET_PE
-#  define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include;{B}/include/winapi"
-# else
-#  define CONFIG_TCC_TCCINCLUDEPATHS "{B}/include"
-# endif
-#endif
-
 #ifndef CONFIG_TCC_SYSINCLUDEPATHS
-# ifndef TCC_TARGET_PE
-#  define CONFIG_TCC_SYSINCLUDEPATHS \
-    ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
-    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
+# ifdef TCC_TARGET_PE
+#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
 # else
-#  define CONFIG_TCC_SYSINCLUDEPATHS ""
+#  define CONFIG_TCC_SYSINCLUDEPATHS \
+        "{B}/include" \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
 # endif
 #endif
 
@@ -283,12 +278,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
 #define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
 #endif
 
-#ifdef TCC_TARGET_PE
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
 /* -------------------------------------------- */
 
 #include "libtcc.h"
@@ -722,10 +711,7 @@ struct TCCState {
     DLLReference **loaded_dlls;
     int nb_loaded_dlls;
 
-    /* include paths, search order */
-    char **tccinclude_paths;
-    int nb_tccinclude_paths;
-
+    /* include paths */
     char **include_paths;
     int nb_include_paths;
 
@@ -1616,7 +1602,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
 ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
 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);
-#ifndef TCC_TARGET_ARM
+#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
@@ -1628,7 +1614,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
 # define ST_PE_IMPORT 0x20
 # define ST_PE_STDCALL 0x40
 #endif
-
 /* ------------ tccrun.c ----------------- */
 #ifdef TCC_IS_NATIVE
 #ifdef CONFIG_TCC_STATIC
diff --git a/tccasm.c b/tccasm.c
index 1e20dc60..ac1618a5 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -75,6 +75,8 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
 	    sym->type.t &= ~VT_EXTERN;
 	    /* Mark that this asm symbol doesn't need to be fed back.  */
 	    sym->a.dllimport = 1;
+	} else {
+	    sym->type.t |= VT_STATIC;
 	}
     }
     return sym;
diff --git a/tccelf.c b/tccelf.c
index 225cd9d5..22ce5df9 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -828,6 +828,12 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
         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:
@@ -1238,14 +1244,6 @@ static void tcc_output_binary(TCCState *s1, FILE *f,
     }
 }
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#define HAVE_PHDR       1
-#define EXTRA_RELITEMS  14
-#else
-#define HAVE_PHDR      1
-#define EXTRA_RELITEMS 9
-#endif
-
 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
 {
     int sym_index = ELFW(R_SYM) (rel->r_info);
@@ -1413,13 +1411,12 @@ static void bind_libs_dynsyms(TCCState *s1)
     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);
-        /* XXX: avoid adding a symbol if already present because of
-                -rdynamic ? */
         sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
-        if (sym_index && sym->st_shndx != SHN_UNDEF)
-            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) {
+        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);
@@ -1451,10 +1448,11 @@ static void export_global_syms(TCCState *s1)
 /* 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 void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
+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++) {
@@ -1463,12 +1461,11 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
            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;
+            !(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 ||
             (s->sh_flags & SHF_ALLOC) ||
@@ -1480,13 +1477,14 @@ static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
             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 dyn_rel_off;
+    unsigned long data_offset;
     addr_t rel_addr;
     addr_t rel_size;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -1542,7 +1540,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
            the program header table itself if needed. These are done later as
            they require section layout to be done first. */
         if (interp)
-            ph += 1 + HAVE_PHDR;
+            ph += 2;
 
         /* dynamic relocation table information, for .dynamic section */
         dyninf->rel_addr = dyninf->rel_size = 0;
@@ -1684,19 +1682,14 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
     if (interp) {
         ph = &phdr[0];
 
-        if (HAVE_PHDR)
-        {
-            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++;
-        }
+        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;
@@ -1727,12 +1720,9 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
    sections */
 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
 {
-    Section *dynamic;
-
-    dynamic = dyninf->dynamic;
+    Section *dynamic = dyninf->dynamic;
 
     /* put dynamic section entries */
-    dynamic->data_offset = dyninf->dyn_rel_off;
     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);
@@ -2009,22 +1999,20 @@ static int elf_output_file(TCCState *s1, const char *filename)
     ElfW(Phdr) *phdr;
     ElfW(Sym) *sym;
     Section *strsec, *interp, *dynamic, *dynstr;
+    int textrel;
 
     file_type = s1->output_type;
     s1->nb_errors = 0;
-
-    /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
-    if (file_type != TCC_OUTPUT_OBJ) {
-        tcc_add_runtime(s1);
-    }
-
+    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);
         relocate_common_syms();
-
         tcc_add_linker_symbols(s1);
 
         if (!s1->static_link) {
@@ -2057,53 +2045,70 @@ static int elf_output_file(TCCState *s1, const char *filename)
 
             if (file_type == TCC_OUTPUT_EXE) {
                 bind_exe_dynsyms(s1);
-
-                if (s1->nb_errors) {
-                    ret = -1;
+                if (s1->nb_errors)
                     goto the_end;
-                }
-
                 bind_libs_dynsyms(s1);
-            } else /* shared library case: simply export all global symbols */
+            } else {
+                /* shared library case: simply export all global symbols */
                 export_global_syms(s1);
-
-            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, s1->enable_new_dtags ? DT_RUNPATH : 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 */
-            dyninf.dyn_rel_off = 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);
         }
+        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;
 
@@ -2111,41 +2116,16 @@ static int elf_output_file(TCCState *s1, const char *filename)
     sec_order = tcc_malloc(sizeof(int) * shnum);
     sec_order[0] = 0;
 
-    /* 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 */
-    alloc_sec_names(s1, file_type, strsec);
-
-    /* allocate program segment headers */
-    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
-
     /* 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 (phnum > 0) {
+    if (file_type != TCC_OUTPUT_OBJ) {
         fill_unloadable_phdr(phdr, phnum, interp, dynamic);
         if (dynamic) {
-            dyninf.dynamic = dynamic;
-            dyninf.dynstr = dynstr;
-
+            dynamic->data_offset = dyninf.data_offset;
             fill_dynamic(s1, &dyninf);
 
             /* put in GOT the dynamic section address and relocate PLT */
@@ -2162,22 +2142,20 @@ static int elf_output_file(TCCState *s1, const char *filename)
                 }
             }
         }
-    }
 
-    /* if building executable or DLL, then relocate each section
-       except the GOT which is already relocated */
-    if (file_type != TCC_OUTPUT_OBJ) {
+        /* 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);
+        /* 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);
diff --git a/tccgen.c b/tccgen.c
index 02e40de9..7d554b5b 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -116,6 +116,12 @@ ST_FUNC int ieee_finite(double d)
     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)
 {
     if (!(vtop->r & VT_LVAL))
@@ -267,9 +273,6 @@ ST_FUNC int tccgen_compile(TCCState *s1)
     parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
     next();
     decl(VT_CONST);
-    if (tok != TOK_EOF)
-        expect("declaration");
-
     gen_inline_functions(s1);
     check_vstack();
     /* end of translation unit info */
@@ -2411,6 +2414,9 @@ static void gen_cast(CType *type)
         df = is_float(dbt);
         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 */
             /* XXX: in ISOC, cannot do it if error in convert */
@@ -3096,6 +3102,8 @@ ST_FUNC void vstore(void)
             /* ... and discard */
             vpop();
         }
+    } else if (dbt == VT_VOID) {
+        --vtop;
     } else {
 #ifdef CONFIG_TCC_BCHECK
             /* bound check case */
@@ -5925,7 +5933,10 @@ static void block(int *bsym, int *csym, int is_expr)
         if (tok != ';') {
             gexpr();
             gen_assign_cast(&func_vt);
-            gfunc_return(&func_vt);
+            if ((func_vt.t & VT_BTYPE) == VT_VOID)
+                vtop--;
+            else
+                gfunc_return(&func_vt);
         }
         skip(';');
         /* jump unless last stmt in top-level block */
@@ -6483,7 +6494,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
 		*(double *)ptr = vtop->c.d;
 		break;
 	    case VT_LDOUBLE:
-#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+#if defined TCC_IS_NATIVE_387
                 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
                     memcpy(ptr, &vtop->c.ld, 10);
 #ifdef __TINYC__
@@ -7091,17 +7102,22 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym)
                 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_CONST || tok < TOK_UIDENT)
+            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 (tok == ';') {
 	    if ((btype.t & VT_BTYPE) == VT_STRUCT) {
diff --git a/tccpe.c b/tccpe.c
index 366f0e7e..a67023dd 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -26,10 +26,12 @@
 #ifndef _WIN32
 #define stricmp strcasecmp
 #define strnicmp strncasecmp
+#include <sys/stat.h> /* chmod() */
 #endif
 
 #ifdef TCC_TARGET_X86_64
 # define ADDR3264 ULONGLONG
+# 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
@@ -38,6 +40,7 @@
 
 #elif defined TCC_TARGET_ARM
 # define ADDR3264 DWORD
+# 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
@@ -46,6 +49,7 @@
 
 #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
@@ -54,22 +58,6 @@
 
 #endif
 
-#if 0
-#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
-#endif
-
-/* ----------------------------------------------------------- */
 #ifndef IMAGE_NT_SIGNATURE
 /* ----------------------------------------------------------- */
 /* definitions below are from winnt.h */
@@ -241,14 +229,19 @@ typedef struct _IMAGE_BASE_RELOCATION {
 #define IMAGE_REL_BASED_MIPS_JMPADDR     5
 #define IMAGE_REL_BASED_SECTION          6
 #define IMAGE_REL_BASED_REL32            7
+#define IMAGE_REL_BASED_DIR64           10
 
 #pragma pack(pop)
 
 /* ----------------------------------------------------------- */
 #endif /* ndef IMAGE_NT_SIGNATURE */
 /* ----------------------------------------------------------- */
-#pragma pack(push, 1)
 
+#ifndef IMAGE_REL_BASED_DIR64
+# define IMAGE_REL_BASED_DIR64 10
+#endif
+
+#pragma pack(push, 1)
 struct pe_header
 {
     IMAGE_DOS_HEADER doshdr;
@@ -281,7 +274,6 @@ struct pe_rsrc_reloc {
     DWORD size;
     WORD type;
 };
-
 #pragma pack(pop)
 
 /* ------------------------------------------------------------- */
@@ -732,6 +724,9 @@ static int pe_write(struct pe_info *pe)
     fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
     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)
         printf("-------------------------------\n");
@@ -1017,7 +1012,7 @@ static void pe_build_reloc (struct pe_info *pe)
             }
             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;
             }
@@ -1471,7 +1466,7 @@ static void pe_print_sections(TCCState *s1, const char *fname)
 /* ------------------------------------------------------------- */
 /* helper function for load/store to insert one more indirection */
 
-#ifndef TCC_TARGET_ARM
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
 {
     int r2;
diff --git a/tccpp.c b/tccpp.c
index 3d11dc3d..76f9e428 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -591,7 +591,7 @@ ST_FUNC int handle_eob(void)
 
     /* 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 = 1;
 #else
@@ -1803,8 +1803,7 @@ ST_FUNC void preprocess(int is_bof)
         /* store current file in stack, but increment stack later below */
         *s1->include_stack_ptr = file;
         i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
-        n = 2 + s1->nb_tccinclude_paths + s1->nb_include_paths +
-            s1->nb_sysinclude_paths;
+        n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
         for (; i < n; ++i) {
             char buf1[sizeof file->filename];
             CachedInclude *e;
@@ -1826,14 +1825,8 @@ ST_FUNC void preprocess(int is_bof)
 
             } else {
                 /* search in all the include paths */
-                int k, j = i - 2;
-
-                if (j < (k = s1->nb_tccinclude_paths))
-                    path = s1->tccinclude_paths[j];
-                else if ((j -= k) < s1->nb_include_paths)
-                    path = s1->include_paths[j];
-                else if ((j -= s1->nb_include_paths) < s1->nb_sysinclude_paths)
-                    path = s1->sysinclude_paths[j];
+                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), "/");
             }
@@ -2635,6 +2628,8 @@ static inline void next_nomacro1(void)
                 tcc_close();
                 s1->include_stack_ptr--;
                 p = file->buf_ptr;
+                if (p == file->buffer)
+                    tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
                 goto redo_no_start;
             }
         }
@@ -2968,7 +2963,7 @@ maybe_newline:
 keep_tok_flags:
     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
 }
 
@@ -3585,7 +3580,8 @@ ST_INLN void unget_tok(int last_tok)
 
 ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
 {
-    char *buf;
+    CString cstr;
+    int i;
 
     s1->include_stack_ptr = s1->include_stack;
     s1->ifdef_stack_ptr = s1->ifdef_stack;
@@ -3601,25 +3597,24 @@ ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
     set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
     set_idnum('.', is_asm ? IS_ID : 0);
 
-    buf = tcc_malloc(3 + strlen(file->filename));
-    sprintf(buf, "\"%s\"", file->filename);
-    tcc_define_symbol(s1, "__BASE_FILE__", buf);
-    tcc_free(buf);
+    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);
 
-    if (s1->nb_cmd_include_files) {
-	CString cstr;
-	int i;
-	cstr_new(&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);
-	}
+    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);
     }
+    cstr_free(&cstr);
 
     if (is_asm)
         tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
diff --git a/tccrun.c b/tccrun.c
index 85957b88..b9a052b1 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -45,15 +45,13 @@ 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);
+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_del_function_table(void *);
 #endif
 
-// #define HAVE_SELINUX
-
 /* ------------------------------------------------------------- */
 /* Do all relocations (needed before using tcc_get_symbol())
    Returns -1 on error. */
@@ -61,25 +59,36 @@ static void win64_del_function_table(void *);
 LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
 {
     int size;
+    addr_t ptr_diff = 0;
 
     if (TCC_RELOCATE_AUTO != ptr)
-        return tcc_relocate_ex(s1, ptr);
+        return tcc_relocate_ex(s1, ptr, 0);
 
-    size = tcc_relocate_ex(s1, NULL);
+    size = tcc_relocate_ex(s1, NULL, 0);
     if (size < 0)
         return -1;
 
 #ifdef HAVE_SELINUX
-    /* Use mmap instead of malloc for Selinux. */
-    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE,
-        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-    if (ptr == MAP_FAILED)
-        tcc_error("tccrun: could not map memory");
+{
+    /* 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); /* no more errors expected */
+    tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
     dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
     return 0;
 }
@@ -91,6 +100,7 @@ ST_FUNC void tcc_run_free(TCCState *s1)
     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
@@ -166,7 +176,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
 
 /* 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 offset, length, fill, i, k;
@@ -199,7 +209,12 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
             if (k != !(s->sh_flags & SHF_EXECINSTR))
                 continue;
             offset += fill;
-            s->sh_addr = mem ? mem + offset : 0;
+            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",
@@ -242,13 +257,15 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
             continue;
         length = s->data_offset;
         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);
         else
             memcpy(ptr, s->data, length);
         /* mark executable sections as executable in memory */
         if (s->sh_flags & SHF_EXECINSTR)
-            set_pages_executable(ptr, length);
+            set_pages_executable((char*)ptr + ptr_diff, length);
     }
     return 0;
 }
@@ -263,15 +280,17 @@ static void set_pages_executable(void *ptr, unsigned long length)
     VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
 #else
     void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
     addr_t start, end;
-#ifndef PAGESIZE
-# define PAGESIZE 4096
-#endif
+#  ifndef PAGESIZE
+#   define PAGESIZE 4096
+#  endif
     start = (addr_t)ptr & ~(PAGESIZE - 1);
     end = (addr_t)ptr + length;
     end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
     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
diff --git a/tcctok.h b/tcctok.h
index 5380ff3e..317f64cd 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -120,6 +120,8 @@
      DEF(TOK_FASTCALL1, "fastcall")
      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__")
@@ -134,23 +136,19 @@
      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")
      DEF(TOK_builtin_return_address, "__builtin_return_address")
      DEF(TOK_builtin_expect, "__builtin_expect")
-#ifdef TCC_TARGET_X86_64
-#ifdef TCC_TARGET_PE
+     /*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")
-#else
+#elif defined TCC_TARGET_X86_64
      DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
-#endif
-#endif
-     DEF(TOK_REGPARM1, "regparm")
-     DEF(TOK_REGPARM2, "__regparm__")
-
-#ifdef TCC_TARGET_ARM64
+#elif defined TCC_TARGET_ARM64
      DEF(TOK___va_start, "__va_start")
      DEF(TOK___va_arg, "__va_arg")
 #endif
diff --git a/tests/Makefile b/tests/Makefile
index 39dee7f4..6a617176 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -234,8 +234,12 @@ vla_test-run: vla_test$(EXESUF)
 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"
diff --git a/tests/pp/13.expect b/tests/pp/13.expect
index 6eb2bec5..c7a32305 100644
--- a/tests/pp/13.expect
+++ b/tests/pp/13.expect
@@ -1,3 +1,2 @@
-# `modelist' label. Each video mode record looks like:
 .text
 endtext:
diff --git a/tests/pp/15.c b/tests/pp/15.c
index 3bbc3ca2..cf13f9a8 100644
--- a/tests/pp/15.c
+++ b/tests/pp/15.c
@@ -12,7 +12,7 @@ return n(A)n(++)n(+)n(+)n(B);
 return n(0x1E)n(-1);
 
 // unlike gcc but correct
-XXX: return n(x)+n(x)-n(1)+n(1)-2;
+// 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);
+// XXX: return n(x)n(x)n(1)n(2)n(x);
diff --git a/tests/pp/15.expect b/tests/pp/15.expect
index f6522400..b4f885e9 100644
--- a/tests/pp/15.expect
+++ b/tests/pp/15.expect
@@ -3,5 +3,3 @@ return A+++B;
 return A+ ++B;
 return A+++ +B;
 return 0x1E -1;
-XXX: return x+x-1 +1 -2;
-XXX: return x x 1 2 x;
diff --git a/tests/pp/Makefile b/tests/pp/Makefile
index 21c99698..687aa52a 100644
--- a/tests/pp/Makefile
+++ b/tests/pp/Makefile
@@ -12,7 +12,7 @@ TESTS = $(call files,c) $(call files,S)
 
 all test : $(sort $(TESTS))
 
-DIFF_OPTS = -Nu -b -B -I "^\#"
+DIFF_OPTS = -Nu -b -B
 
 # Filter source directory in warnings/errors (out-of-tree builds)
 FILTER = 2>&1 | sed 's,$(SRC)/,,g'
@@ -40,7 +40,7 @@ clean:
 	rm -f *.output
 
 02.test : DIFF_OPTS += -w
-15.test : DIFF_OPTS += -I"^XXX:"
+# 15.test : DIFF_OPTS += -I"^XXX:"
 
 # diff options:
 # -b ighore space changes
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 78772430..099fc354 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -3235,6 +3235,7 @@ void asm_local_statics (void)
 }
 #endif
 
+static
 unsigned int set;
 
 void fancy_copy (unsigned *in, unsigned *out)
@@ -3247,7 +3248,7 @@ void fancy_copy2 (unsigned *in, unsigned *out)
   asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
 }
 
-#ifdef __x86_64__
+#if defined __x86_64__ && !defined _WIN64
 void clobber_r12(void)
 {
     asm volatile("mov $1, %%r12" ::: "r12");
@@ -3256,7 +3257,7 @@ void clobber_r12(void)
 
 void test_high_clobbers(void)
 {
-#ifdef __x86_64__
+#if defined __x86_64__ && !defined _WIN64
     register long val asm("r12");
     long val2;
     /* This tests if asm clobbers correctly save/restore callee saved
@@ -3265,11 +3266,9 @@ void test_high_clobbers(void)
        correctly capture the data flow, but good enough for us.  */
     asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
     clobber_r12();
-#ifndef _WIN64
     asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
     printf("asmhc: 0x%x\n", val2);
 #endif
-#endif
 }
 
 static long cpu_number;
diff --git a/tests/tests2/95_bitfields.c b/tests/tests2/95_bitfields.c
index 683becfd..f025c575 100644
--- a/tests/tests2/95_bitfields.c
+++ b/tests/tests2/95_bitfields.c
@@ -70,7 +70,7 @@
 {
     struct M P __s {
 	int a;
-	char b;
+	signed char b;
 	int x : 12, y : 4, : 0, : 4, z : 3;
 	char d;
     };
diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c
index b5949388..cc211d36 100644
--- a/tests/tests2/96_nodata_wanted.c
+++ b/tests/tests2/96_nodata_wanted.c
@@ -78,7 +78,7 @@ te1:;
     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);
+    /*printf("# %d/%d\n", dl, tl);*/
 }
 
 #endif
diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect
index 6e54f248..2749109a 100644
--- a/tests/tests2/96_nodata_wanted.expect
+++ b/tests/tests2/96_nodata_wanted.expect
@@ -17,9 +17,7 @@ data:
   333 44 555555 6 7
 size of data/text:
   non-zero/non-zero
-# 111/193
 
 [test_data_suppression_on]
 size of data/text:
   zero/zero
-# 0/0
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index 6bff6183..190b2d9b 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -70,7 +70,7 @@ all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
 T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)
 T2 = $(TCC) $(FLAGS) -run $< $(ARGS)
 T3 = $(FILTER) >$*.output 2>&1 || true \
-     && diff -Nbu -I "^\#" $(filter %.expect,$^) $*.output \
+     && diff -Nbu $(filter %.expect,$^) $*.output \
      && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
 
 # run single test and update .expect file, e.g. "make tests2.37+"
diff --git a/win32/Makefile b/win32/Makefile
deleted file mode 100644
index 5bd60bd0..00000000
--- a/win32/Makefile
+++ /dev/null
@@ -1,148 +0,0 @@
-#
-# This Makefile builds native Windows tcc for both 32 and 64 bits generator.
-# It requires Cygwin 64 and gcc to bootstrap a first tcc version which is used
-# by a second stage to compile tcc it self.
-# Generated binaries do not require cygwin to run.
-# You can launch 'tarball' target to build a tar.gz you can install on any
-# Windows machines.
-
-CPU	= $(shell if `gcc -v 2>&1 | grep Target | grep -q x86_64`; then echo 64; else echo 32; fi)
-VERSION	= $(shell cat ../VERSION)
-BOOTCC	= gcc
-CFLAGS	= -s -static -fno-strict-aliasing -Wno-incompatible-pointer-types -DTCC_TARGET_PE
-#WINPWD	= `cygpath --mixed $(PWD)`
-#@echo "#define CONFIG_TCCDIR \"$(WINPWD)\""
-
-ifeq ($(CPU), 64)
-NATIVE	= -m$(CPU) -DTCC_TARGET_X86_64
-ARCH	= x86_64
-else
-NATIVE	= -m$(CPU) -DTCC_TARGET_I386
-ARCH	= i386
-endif
-
-TARGET	= $(CPU)
-
-ifeq ($(TARGET), 64)
-TFLAGS	= -m$(TARGET) -DTCC_TARGET_X86_64
-TARCH	= x86_64
-else
-TFLAGS	= -m$(TARGET) -DTCC_TARGET_I386
-TARCH	= i386
-endif
-
-all: pre bootstrap libs rebuild
-	@chmod 775 *.exe
-	@ls -ls *.exe
-
-pre:
-	@echo ARCH=$(TARCH) 1> ../config.mak
-	@echo TARGETOS=Windows  1>> ../config.mak
-	@echo CONFIG_WIN32=yes 1>> ../config.mak
-	@echo TOPSRC=$$\(TOP\) 1>> ../config.mak
-	@echo "#define TCC_VERSION \"$(VERSION)\"" 1>../config.h
-	@echo "#ifdef TCC_TARGET_X86_64" 1>>../config.h
-	@echo "#define TCC_LIBTCC1 \"libtcc1-64.a\"" 1>>../config.h
-	@echo "#else" 1>>../config.h
-	@echo "#define TCC_LIBTCC1 \"libtcc1-32.a\"" 1>>../config.h
-	@echo "#endif" 1>>../config.h
-	@echo @set VERSION $(VERSION) 1>../config.texi
-	@rm -f *tcc.exe tiny_*.exe *tcc.dll lib/*.a
-	@rm -r -f libtcc doc
-	@mkdir libtcc
-	@mkdir doc
-	@cp ../include/*.h include
-	@cp ../tcclib.h include
-	@cp ../libtcc.h include
-	@cp tcc-win32.txt doc
-	@cp ../tests/libtcc_test.c examples
-
-PHONY += pre
-
-bootstrap:
-	@echo Bootstrapping 32bits and 64bits tools with $(BOOTCC) -m$(CPU)
-	@$(BOOTCC) $(CFLAGS) -DTCC_TARGET_I386   -o i386-win32-tcc.exe   ../tcc.c
-	@$(BOOTCC) $(CFLAGS) -DTCC_TARGET_X86_64 -o x86_64-win32-tcc.exe ../tcc.c
-	@$(BOOTCC) $(CFLAGS) $(NATIVE)           -o tcc.exe              ../tcc.c
-	@$(BOOTCC) $(CFLAGS) $(NATIVE) -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c
-
-PHONY += bootstrap
-
-lib/libtcc1-32.a:
-	@echo Building $*.a with tcc -m32
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/libtcc1.c 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86.S 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c ../lib/alloca86-bt.S 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1.c 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/crt1w.c
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1.c 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/wincrt1w.c
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllcrt1.c 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/dllmain.c 
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -c lib/chkstk.S
-	@./tcc -m32 -ar lib/libtcc1-32.a libtcc1.o alloca86.o alloca86-bt.o crt1.o wincrt1.o crt1w.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o
-	@rm *.o
-
-lib/libtcc1-64.a:
-	@echo Building $*.a with tcc -m64
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/libtcc1.c 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64.S 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c ../lib/alloca86_64-bt.S 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1.c 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/crt1w.c
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1.c 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/wincrt1w.c
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllcrt1.c 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/dllmain.c 
-	@./tcc -O2 -B. -m64 -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -c lib/chkstk.S 
-	@./tcc -m64 -ar lib/libtcc1-64.a libtcc1.o alloca86_64.o alloca86_64-bt.o crt1.o wincrt1.o crt1w.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o
-	@rm *.o
-
-libs: lib/libtcc1-32.a lib/libtcc1-64.a
-
-PHONY += libs
-
-rebuild:
-	@echo Rebuild using tcc itself - default $(TARGET)bits
-	@./$(TARCH)-win32-tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -o tcc.exe ../tcc.c
-	@./tcc -O2 -B. $(TFLAGS) -DTCC_TARGET_PE -DLIBTCC_AS_DLL -o libtcc.dll -shared ../libtcc.c
-	@./tcc -O2 -B. -m32 -DTCC_TARGET_PE -DTCC_TARGET_I386 -o tmp-tcc.exe ../tcc.c && mv tmp-tcc.exe i386-win32-tcc.exe
-	@./tcc -O2 -B. -m$(TARGET) -DTCC_TARGET_PE -DTCC_TARGET_X86_64 -o tmp-tcc.exe ../tcc.c && mv tmp-tcc.exe x86_64-win32-tcc.exe
-
-PHONY += rebuild
-
-test:
-	@(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc hello-exe hello-run)
-	@(cd ../tests; $(MAKE) -k TCC=$(PWD)/tcc vla_test-run tests2-dir pp-dir)
-ifeq ($(CPU), 64)
-	@(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc hello-exe hello-run)
-	@(cd ../tests; $(MAKE) -k TCC=$(PWD)/i386-win32-tcc vla_test-run tests2-dir pp-dir)
-endif
-
-PHONY += test
-
-TARNAME	= tcc-$(VERSION)-$(ARCH)-win32
-
-tarball:
-	@rm -r -f $(TARNAME)
-	@mkdir $(TARNAME)
-	@cp -r doc $(TARNAME)
-	@cp -r examples $(TARNAME)
-	@cp -r include $(TARNAME)
-	@cp -r lib $(TARNAME)
-	@cp -r libtcc $(TARNAME)
-	@cp -r build-tcc.bat $(TARNAME)
-	@cp -r i386-win32-tcc.exe $(TARNAME)
-	@cp -r libtcc.def $(TARNAME)
-	@cp -r libtcc.dll $(TARNAME)
-	@cp -r Makefile $(TARNAME)
-	@cp -r tcc.exe $(TARNAME)
-	@cp -r tcc-win32.txt $(TARNAME)
-	@cp -r x86_64-win32-tcc.exe $(TARNAME)
-	@tar czf $(TARNAME).tar.gz $(TARNAME)
-	@rm -r -f $(TARNAME)
-
-PHONY += tarball
-
-clean:
-	rm -f *.o *.exe *.dll lib/*.a *.pdb *.obj *.exp *.def *.lib
diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat
index 3c3a7267..ceb4411f 100644
--- a/win32/build-tcc.bat
+++ b/win32/build-tcc.bat
@@ -4,13 +4,31 @@
 
 @echo off
 setlocal
-
-set CC=gcc -Os -s -static
+if (%1)==(-clean) goto :cleanup
+set CC=gcc
 set /p VERSION= < ..\VERSION
 set INST=
+set BIN=
 set DOC=no
+set EXES_ONLY=no
 goto :a0
-
+:a2
+shift
+:a3
+shift
+:a0
+if not (%1)==(-c) goto :a1
+set CC=%~2
+if (%2)==(cl) set CC=@call :cl
+goto :a2
+:a1
+if (%1)==(-t) set T=%2&& goto :a2
+if (%1)==(-v) set VERSION=%~2&& goto :a2
+if (%1)==(-i) set INST=%2&& goto :a2
+if (%1)==(-b) set BIN=%2&& goto :a2
+if (%1)==(-d) set DOC=yes&& goto :a3
+if (%1)==(-x) set EXES_ONLY=yes&& goto :a3
+if (%1)==() goto :p1
 :usage
 echo usage: build-tcc.bat [ options ... ]
 echo options:
@@ -18,10 +36,35 @@ echo   -c prog              use prog (gcc/tcc/cl) to compile tcc
 echo   -c "prog options"    use prog with options to compile tcc
 echo   -t 32/64             force 32/64 bit default target
 echo   -v "version"         set tcc version
-echo   -i dir               install tcc into dir
+echo   -i tccdir            install tcc into tccdir
+echo   -b bindir            optionally install binaries into bindir elsewhere
 echo   -d                   create tcc-doc.html too (needs makeinfo)
+echo   -x                   just create the executables
+echo   -clean               delete all previously produced files and directories
 exit /B 1
 
+@rem ------------------------------------------------------
+@rem sub-routines
+
+:cleanup
+set LOG=echo
+%LOG% removing files:
+for %%f in (*tcc.exe libtcc.dll lib\*.a) do call :del_file %%f
+for %%f in (..\config.h ..\config.texi) do call :del_file %%f
+for %%f in (include\*.h) do @if exist ..\%%f call :del_file %%f
+for %%f in (include\tcclib.h examples\libtcc_test.c) do call :del_file %%f
+for %%f in (*.o *.obj *.def *.pdb *.lib *.exp *.ilk) do call :del_file %%f
+%LOG% removing directories:
+for %%f in (doc libtcc) do call :del_dir %%f
+%LOG% done.
+exit /B 0
+:del_file
+if exist %1 del %1 && %LOG%   %1
+exit /B 0
+:del_dir
+if exist %1 rmdir /Q/S %1 && %LOG%   %1
+exit /B 0
+
 :cl
 @echo off
 set CMD=cl
@@ -37,52 +80,16 @@ echo on
 %CMD% -O1 -W2 -Zi -MT -GS- -nologo -link -opt:ref,icf
 @exit /B %ERRORLEVEL%
 
-:a2
-shift
-:a1
-shift
-:a0
-if not (%1)==(-c) goto :a3
-set CC=%~2
-if (%2)==(cl) set CC=@call :cl
-goto :a2
-:a3
-if not (%1)==(-t) goto :a4
-set T=%2
-goto :a2
-:a4
-if not (%1)==(-v) goto :a5
-set VERSION=%~2
-goto :a2
-:a5
-if not (%1)==(-i) goto :a6
-set INST=%2
-goto :a2
-:a6
-if not (%1)==(-d) goto :a7
-set DOC=yes
-goto :a1
-:a7
-if not (%1)==() goto :usage
+@rem ------------------------------------------------------
+@rem main program
 
-if not "%CC%"=="@call :cl" goto :p1
-set VSCOMNTOOLS=%VS150COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS140COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS130COMNTOOLS%
-if "%VSCOMNTOOLS%"=="" set VSCOMNTOOLS=%VS120COMNTOOLS%
-if %T%_==32_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\vcvars32.bat"
-if %T%_==64_ set CLVARS="%VSCOMNTOOLS%..\..\VC\bin\amd64\vcvars64.bat"
-if %T%_==_ set T=32& if %Platform%_==X64_ set T=64
-if %CLVARS%_==_ goto :p1
-if exist %CLVARS% call %CLVARS%
 :p1
-
 if not %T%_==_ goto :p2
 set T=32
 if %PROCESSOR_ARCHITECTURE%_==AMD64_ set T=64
 if %PROCESSOR_ARCHITEW6432%_==AMD64_ set T=64
 :p2
-
+if "%CC:~-3%"=="gcc" set CC=%CC% -Os -s -static
 set D32=-DTCC_TARGET_PE -DTCC_TARGET_I386
 set D64=-DTCC_TARGET_PE -DTCC_TARGET_X86_64
 set P32=i386-win32
@@ -91,13 +98,14 @@ if %T%==64 goto :t64
 set D=%D32%
 set DX=%D64%
 set PX=%P64%
-goto :t96
+goto :p3
 :t64
 set D=%D64%
 set DX=%D32%
 set PX=%P32%
-:t96
+goto :p3
 
+:p3
 @echo on
 
 :config.h
@@ -116,7 +124,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f
 %CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
 %CC% -o %PX%-tcc.exe ..\tcc.c %DX%
 
-@if (%TCC_FILES%)==(no) goto :files-done
+@if (%EXES_ONLY%)==(yes) goto :files-done
 
 if not exist libtcc mkdir libtcc
 if not exist doc mkdir doc
@@ -170,8 +178,11 @@ for %%f in (*.o *.def) do @del %%f
 :copy-install
 @if (%INST%)==() goto :the_end
 if not exist %INST% mkdir %INST%
+@if (%BIN%)==() set BIN=%INST%
+if not exist %BIN% mkdir %BIN%
+for %%f in (*tcc.exe *tcc.dll) do @copy>nul %%f %BIN%\%%f
 @if not exist %INST%\lib mkdir %INST%\lib
-for %%f in (*tcc.exe *tcc.dll lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f
+for %%f in (lib\*.a lib\*.def) do @copy>nul %%f %INST%\%%f
 for %%f in (include examples libtcc doc) do @xcopy>nul /s/i/q/y %%f %INST%\%%f
 
 :the_end
diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c
index 53e5545e..0e04fc01 100644
--- a/win32/lib/crt1.c
+++ b/win32/lib/crt1.c
@@ -16,11 +16,6 @@
 #define _PC_53          0x00010000 // 53 bits
 #define _PC_64          0x00000000 // 64 bits
 
-typedef struct
-{
-    int newmode;
-} _startupinfo;
-
 #ifdef _UNICODE
 #define __tgetmainargs __wgetmainargs
 #define _tstart _wstart
@@ -33,6 +28,7 @@ typedef struct
 #define _runtmain _runmain
 #endif
 
+typedef struct { int newmode; } _startupinfo;
 int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
 void __cdecl __set_app_type(int apptype);
 unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
@@ -44,23 +40,19 @@ int _dowildcard;
 void _tstart(void)
 {
     __TRY__
-    int ret;
-    _startupinfo start_info;
+    _startupinfo start_info = {0};
 
     // Sets the current application type
     __set_app_type(_CONSOLE_APP);
 
     // Set default FP precision to 53 bits (8-byte double)
-    // _MCW_PC (Precision control) is not supported on
-    // the ARM and x64 architectures
-#ifdef __i386
+    // _MCW_PC (Precision control) is not supported on ARM
+#if defined __i386__ || defined __x86_64__
     _controlfp(_PC_53, _MCW_PC);
 #endif
 
-    start_info.newmode = 0;
     __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info);
-    ret = _tmain(__argc, __targv, _tenviron);
-    exit(ret);
+    exit(_tmain(__argc, __targv, _tenviron));
 }
 
 int _runtmain(int argc, /* as tcc passed in */ char **argv)
@@ -78,8 +70,7 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv)
     __argc = argc;
     __targv = argv;
 #endif
-
-#ifdef __i386
+#if defined __i386__ || defined __x86_64__
     _controlfp(_PC_53, _MCW_PC);
 #endif
     return _tmain(__argc, __targv, _tenviron);
diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c
index 83e2f746..ce3a63f1 100644
--- a/win32/lib/wincrt1.c
+++ b/win32/lib/wincrt1.c
@@ -23,71 +23,53 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
 #define _runtwinmain _runwinmain
 #endif
 
-typedef struct
-{
-    int newmode;
-} _startupinfo; // CLI Vs GUI
-
+typedef struct { int newmode; } _startupinfo;
 int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
 
+static int go_winmain(TCHAR *arg1)
+{
+    STARTUPINFO si;
+    _TCHAR *szCmd, *p;
+    int fShow;
+
+    GetStartupInfo(&si);
+    if (si.dwFlags & STARTF_USESHOWWINDOW)
+        fShow = si.wShowWindow;
+    else
+        fShow = SW_SHOWDEFAULT;
+
+    szCmd = NULL, p = GetCommandLine();
+    if (arg1)
+        szCmd = _tcsstr(p, arg1);
+    if (NULL == szCmd)
+        szCmd = _tcsdup(__T(""));
+    else if (szCmd > p && szCmd[-1] == __T('"'))
+        --szCmd;
+#if defined __i386__ || defined __x86_64__
+    _controlfp(0x10000, 0x30000);
+#endif
+    return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
+}
+
 int _twinstart(void)
 {
     __TRY__
-    _TCHAR *szCmd, *p;
-    STARTUPINFO startinfo;
     _startupinfo start_info_con = {0};
-    int fShow;
-    int ret;
-
     __set_app_type(__GUI_APP);
-    _controlfp(0x10000, 0x30000);
-
-    start_info_con.newmode = 0;
     __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info_con);
-
-    p = GetCommandLine();
-    if (__argc > 1)
-        szCmd = _tcsstr(p, __targv[1]);
-    if (NULL == szCmd)
-        szCmd = __T("");
-    else if (szCmd > p && szCmd[-1] == __T('\"'))
-        --szCmd;
-
-    GetStartupInfo(&startinfo);
-    fShow = startinfo.wShowWindow;
-    if (0 == (startinfo.dwFlags & STARTF_USESHOWWINDOW))
-        fShow = SW_SHOWDEFAULT;
-
-    ret = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
-    exit(ret);
+    exit(go_winmain(__argc > 1 ? __targv[1] : NULL));
 }
 
 int _runtwinmain(int argc, /* as tcc passed in */ char **argv)
 {
-    _TCHAR *szCmd, *p;
-
 #ifdef UNICODE
     _startupinfo start_info = {0};
-
     __tgetmainargs(&__argc, &__targv, &_tenviron, 0, &start_info);
     /* may be wrong when tcc has received wildcards (*.c) */
-    if (argc < __argc) {
-        __targv += __argc - argc;
-        __argc = argc;
-    }
+    if (argc < __argc)
+        __targv += __argc - argc, __argc = argc;
 #else
-    __argc = argc;
-    __targv = argv;
+    __argc = argc, __targv = argv;
 #endif
-
-    p = GetCommandLine();
-    szCmd = NULL;
-    if (argc > 1)
-        szCmd = _tcsstr(p, __targv[1]);
-    if (NULL == szCmd)
-        szCmd = __T("");
-    else if (szCmd > p && szCmd[-1] == __T('\"'))
-        --szCmd;
-    _controlfp(0x10000, 0x30000);
-    return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT);
+    return go_winmain(__argc > 1 ? __targv[1] : NULL);
 }
diff --git a/win32/tcc-win32.txt b/win32/tcc-win32.txt
index 3609684c..751a8e07 100644
--- a/win32/tcc-win32.txt
+++ b/win32/tcc-win32.txt
@@ -108,6 +108,8 @@
     ------------------------
     * You can use the MinGW and MSYS tools available at
         http://www.mingw.org
+        http://www.mingw-w64.org
+        http://www.msys2.org
 
       Untar the TCC archive and type in the MSYS shell:
         ./configure [--prefix installpath]
@@ -116,29 +118,22 @@
 
       The default install location is c:\Program Files\tcc
 
+      Cygwin can be used too with its mingw cross-compiler installed:
+        ./configure --cross-prefix=i686-w64-mingw32-
+        (the prefix may vary)
+
     * Alternatively you can compile TCC with just GCC from MinGW using
         > build-tcc.bat (from the win32 directory)
 
       Also MSVC can be used with the "VSTools Developer Command Prompt":
         > build-tcc.bat -c cl
 
-      or with a tcc (needs to be in a different directory)
+      or with an existing tcc (needs to be in a different directory)
         > build-tcc.bat -c some-tcc-dir\tcc.exe
 
       Also you can copy/install everything into another directory:
         > build-tcc.bat -i <dir>
 
-    * You can also bootstrap a native tcc Windows toolchain with cygwin.
-       https://www.cygwin.com/
-
-      Install Base, gcc, make
-      Launch Cygwin Terminal
-        > make
-      or to force 32bit executables (including 64bit backend)
-        > make TARGET=32
-      or to force 64bit executables (including 32bit backend)
-        > make TARGET=64
-
     Limitations:
     ------------
     - On the object file level, currently TCC supports only the ELF format,