diff --git a/Makefile b/Makefile
index 08ef48a4..b27e5fa0 100644
--- a/Makefile
+++ b/Makefile
@@ -113,11 +113,13 @@ ifdef CONFIG_CROSS
 PROGS+=$(PROGS_CROSS)
 endif
 
+# NOTALLINONE = 1
+
 all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)
 
 # Host Tiny C Compiler
-tcc$(EXESUF): $(NATIVE_FILES)
-	$(CC) -o $@ $< $(NATIVE_TARGET) $(CFLAGS) $(LIBS)
+tcc$(EXESUF): tcc.o libtcc.a
+	$(CC) -o $@ $^ $(LIBS)
 
 # Cross Tiny C Compilers
 i386-tcc$(EXESUF): $(I386_FILES)
@@ -151,10 +153,22 @@ arm-tcc-vfp-eabi$(EXESUF): $(ARM_FILES)
 	$(CC) -o $@ $< -DTCC_TARGET_ARM -DTCC_ARM_EABI $(CFLAGS) $(LIBS)
 
 # libtcc generation and test
-libtcc.o: $(NATIVE_FILES)
-	$(CC) -o $@ -c libtcc.c $(NATIVE_TARGET) $(CFLAGS)
 
-libtcc.a: libtcc.o
+ifdef NOTALLINONE
+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))
+$(LIBTCC_OBJ) : DEFINES += -DNOTALLINONE
+else
+LIBTCC_OBJ = libtcc.o
+LIBTCC_INC = $(NATIVE_FILES)
+endif
+
+tcc.o : DEFINES += -DNOTALLINONE
+
+$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
+	$(CC) -o $@ -c $< $(NATIVE_TARGET) $(CFLAGS) $(DEFINES)
+
+libtcc.a: $(LIBTCC_OBJ)
 	$(AR) rcs $@ $^
 
 libtcc_test$(EXESUF): tests/libtcc_test.c libtcc.a
@@ -260,19 +274,18 @@ tar:
 	rm -rf /tmp/$(TCC-VERSION)
 
 # in tests subdir
-test clean:
+%est:
 	$(MAKE) -C tests $@
 
+clean:
+	rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF)
+	$(MAKE) -C tests $@
+
+distclean: clean
+	rm -vf config.h config.mak config.texi tcc.1
+
 config.mak:
 	@echo Running configure ...
 	@./configure
 
-# clean
-clean: local_clean
-local_clean:
-	rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.out libtcc_test$(EXESUF)
-
-distclean: clean
-	rm -vf config.h config.mak config.texi tcc.1
-
 endif # ifeq ($(TOP),.)
diff --git a/arm-gen.c b/arm-gen.c
index e0866ffd..e9bc3a02 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -20,11 +20,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifdef TARGET_DEFS_ONLY
+
 #ifdef TCC_ARM_EABI
 #define TCC_ARM_VFP
 #endif
 
-
 /* number of available registers */
 #ifdef TCC_ARM_VFP
 #define NB_REGS            13
@@ -75,32 +76,6 @@ enum {
 #endif
 };
 
-const int reg_classes[NB_REGS] = {
-    /* r0 */ RC_INT | RC_R0,
-    /* r1 */ RC_INT | RC_R1,
-    /* r2 */ RC_INT | RC_R2,
-    /* r3 */ RC_INT | RC_R3,
-    /* r12 */ RC_INT | RC_R12,
-    /* f0 */ RC_FLOAT | RC_F0,
-    /* f1 */ RC_FLOAT | RC_F1,
-    /* f2 */ RC_FLOAT | RC_F2,
-    /* f3 */ RC_FLOAT | RC_F3,
-#ifdef TCC_ARM_VFP
- /* d4/s8 */ RC_FLOAT | RC_F4,
-/* d5/s10 */ RC_FLOAT | RC_F5,
-/* d6/s12 */ RC_FLOAT | RC_F6,
-/* d7/s14 */ RC_FLOAT | RC_F7,
-#endif
-};
-
-static int two2mask(int a,int b) {
-  return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
-}
-
-static int regmask(int r) {
-  return reg_classes[r]&~(RC_INT|RC_FLOAT);
-}
-
 #ifdef TCC_ARM_VFP
 #define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
 #endif
@@ -171,10 +146,42 @@ static CType float_type, double_type, func_float_type, func_double_type;
 #define ELF_PAGE_SIZE  0x1000
 
 /******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* r0 */ RC_INT | RC_R0,
+    /* r1 */ RC_INT | RC_R1,
+    /* r2 */ RC_INT | RC_R2,
+    /* r3 */ RC_INT | RC_R3,
+    /* r12 */ RC_INT | RC_R12,
+    /* f0 */ RC_FLOAT | RC_F0,
+    /* f1 */ RC_FLOAT | RC_F1,
+    /* f2 */ RC_FLOAT | RC_F2,
+    /* f3 */ RC_FLOAT | RC_F3,
+#ifdef TCC_ARM_VFP
+ /* d4/s8 */ RC_FLOAT | RC_F4,
+/* d5/s10 */ RC_FLOAT | RC_F5,
+/* d6/s12 */ RC_FLOAT | RC_F6,
+/* d7/s14 */ RC_FLOAT | RC_F7,
+#endif
+};
+
 static unsigned long func_sub_sp_offset,last_itod_magic;
 static int leaffunc;
 
-void o(unsigned long i)
+static int two2mask(int a,int b) {
+  return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
+}
+
+static int regmask(int r) {
+  return reg_classes[r]&~(RC_INT|RC_FLOAT);
+}
+
+/******************************************************/
+
+void o(unsigned int i)
 {
   /* this is a good place to start adding big-endian support*/
   int ind1;
@@ -304,7 +311,7 @@ void stuff_const_harder(unsigned long op,unsigned long v) {
   }
 }
 
-unsigned long encbranch(int pos,int addr,int fail)
+ST_FUNC unsigned long encbranch(int pos,int addr,int fail)
 {
   addr-=pos+8;
   addr/=4;
@@ -1571,7 +1578,7 @@ void gen_opf(int op)
 
 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
    and 'long long' cases. */
-void gen_cvt_itof1(int t)
+ST_FUNC void gen_cvt_itof1(int t)
 {
   int r,r2,bt;
   bt=vtop->type.t & VT_BTYPE;
@@ -1732,4 +1739,5 @@ void ggoto(void)
 
 /* end of ARM code generator */
 /*************************************************************/
-
+#endif
+/*************************************************************/
diff --git a/c67-gen.c b/c67-gen.c
index 88224fd5..b3531945 100644
--- a/c67-gen.c
+++ b/c67-gen.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifdef TARGET_DEFS_ONLY
+
 //#define ASSEMBLY_LISTING_C67
 
 /* number of available registers */
@@ -85,62 +87,18 @@ enum {
     TREG_C67_B13,
 };
 
-const int reg_classes[NB_REGS] = {
-						/* eax */ RC_INT | RC_FLOAT | RC_EAX,
-						// only allow even regs for floats (allow for doubles)
-    /* ecx */ RC_INT | RC_ECX,
-								/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
-								// only allow even regs for floats (allow for doubles)
-    /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
-    /* A4  */ RC_C67_A4,
-    /* A5  */ RC_C67_A5,
-    /* B4  */ RC_C67_B4,
-    /* B5  */ RC_C67_B5,
-    /* A6  */ RC_C67_A6,
-    /* A7  */ RC_C67_A7,
-    /* B6  */ RC_C67_B6,
-    /* B7  */ RC_C67_B7,
-    /* A8  */ RC_C67_A8,
-    /* A9  */ RC_C67_A9,
-    /* B8  */ RC_C67_B8,
-    /* B9  */ RC_C67_B9,
-    /* A10  */ RC_C67_A10,
-    /* A11  */ RC_C67_A11,
-    /* B10  */ RC_C67_B10,
-    /* B11  */ RC_C67_B11,
-    /* A12  */ RC_C67_A10,
-    /* A13  */ RC_C67_A11,
-    /* B12  */ RC_C67_B10,
-    /* B13  */ RC_C67_B11
-};
-
 /* return registers for function */
 #define REG_IRET TREG_C67_A4	/* single word int return register */
 #define REG_LRET TREG_C67_A5	/* second word return register (for long long) */
 #define REG_FRET TREG_C67_A4	/* float return register */
 
-
 #define ALWAYS_ASSERT(x) \
 do {\
    if (!(x))\
        error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
 } while (0)
 
-// although tcc thinks it is passing parameters on the stack,
-// the C67 really passes up to the first 10 params in special
-// regs or regs pairs (for 64 bit params).  So keep track of
-// the stack offsets so we can translate to the appropriate 
-// reg (pair)
-
-
-#define NoCallArgsPassedOnStack 10
-int NoOfCurFuncArgs;
-int TranslateStackToReg[NoCallArgsPassedOnStack];
-int ParamLocOnStack[NoCallArgsPassedOnStack];
-int TotalBytesPushedOnStack;
-
 /* defined if function parameters must be evaluated in reverse order */
-
 //#define INVERT_FUNC_PARAMS
 
 /* defined if structures are passed as pointers. Otherwise structures
@@ -171,7 +129,52 @@ int TotalBytesPushedOnStack;
 #define ELF_PAGE_SIZE  0x1000
 
 /******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
 
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* eax */ RC_INT | RC_FLOAT | RC_EAX, 
+    // only allow even regs for floats (allow for doubles)
+    /* ecx */ RC_INT | RC_ECX,
+    /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
+    // only allow even regs for floats (allow for doubles)
+    /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
+    /* A4  */ RC_C67_A4,
+    /* A5  */ RC_C67_A5,
+    /* B4  */ RC_C67_B4,
+    /* B5  */ RC_C67_B5,
+    /* A6  */ RC_C67_A6,
+    /* A7  */ RC_C67_A7,
+    /* B6  */ RC_C67_B6,
+    /* B7  */ RC_C67_B7,
+    /* A8  */ RC_C67_A8,
+    /* A9  */ RC_C67_A9,
+    /* B8  */ RC_C67_B8,
+    /* B9  */ RC_C67_B9,
+    /* A10  */ RC_C67_A10,
+    /* A11  */ RC_C67_A11,
+    /* B10  */ RC_C67_B10,
+    /* B11  */ RC_C67_B11,
+    /* A12  */ RC_C67_A10,
+    /* A13  */ RC_C67_A11,
+    /* B12  */ RC_C67_B10,
+    /* B13  */ RC_C67_B11
+};
+
+// although tcc thinks it is passing parameters on the stack,
+// the C67 really passes up to the first 10 params in special
+// regs or regs pairs (for 64 bit params).  So keep track of
+// the stack offsets so we can translate to the appropriate 
+// reg (pair)
+
+#define NoCallArgsPassedOnStack 10
+int NoOfCurFuncArgs;
+int TranslateStackToReg[NoCallArgsPassedOnStack];
+int ParamLocOnStack[NoCallArgsPassedOnStack];
+int TotalBytesPushedOnStack;
+
+/******************************************************/
 static unsigned long func_sub_sp_offset;
 static int func_ret_sub;
 
@@ -2545,5 +2548,7 @@ void ggoto(void)
     vtop--;
 }
 
-/* end of X86 code generator */
+/* end of C67 code generator */
+/*************************************************************/
+#endif
 /*************************************************************/
diff --git a/i386-asm.c b/i386-asm.c
index 6e1314cf..a378191b 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -19,7 +19,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#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
@@ -398,7 +402,8 @@ static void parse_operand(TCCState *s1, Operand *op)
     op->type |= indir;
 }
 
-static void gen_expr32(ExprValue *pe)
+/* XXX: unify with C code output ? */
+ST_FUNC void gen_expr32(ExprValue *pe)
 {
     gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
 }
@@ -554,7 +559,7 @@ static inline void asm_modrm(int reg, Operand *op)
     }
 }
 
-static void asm_opcode(TCCState *s1, int opcode)
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
 {
     const ASMInstr *pa;
     int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
@@ -966,9 +971,6 @@ static void asm_opcode(TCCState *s1, int opcode)
 #endif
 }
 
-#define NB_SAVED_REGS 3
-#define NB_ASM_REGS 8
-
 /* return the constraint priority (we allocate first the lowest
    numbered constraints) */
 static inline int constraint_priority(const char *str)
@@ -1030,7 +1032,7 @@ static const char *skip_constraint_modifiers(const char *p)
 
 #define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
 
-static void asm_compute_constraints(ASMOperand *operands,
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
                                     int nb_operands, int nb_outputs,
                                     const uint8_t *clobber_regs,
                                     int *pout_reg)
@@ -1262,7 +1264,7 @@ static void asm_compute_constraints(ASMOperand *operands,
 #endif
 }
 
-static void subst_asm_operand(CString *add_str,
+ST_FUNC void subst_asm_operand(CString *add_str,
                               SValue *sv, int modifier)
 {
     int r, reg, size, val;
@@ -1356,7 +1358,7 @@ static void subst_asm_operand(CString *add_str,
 }
 
 /* generate prolog and epilog code for asm statment */
-static void asm_gen_code(ASMOperand *operands, int nb_operands,
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
                          int nb_outputs, int is_output,
                          uint8_t *clobber_regs,
                          int out_reg)
@@ -1450,7 +1452,7 @@ static void asm_gen_code(ASMOperand *operands, int nb_operands,
     }
 }
 
-static void asm_clobber(uint8_t *clobber_regs, const char *str)
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
 {
     int reg;
     TokenSym *ts;
diff --git a/i386-gen.c b/i386-gen.c
index 161be937..9a8ceeeb 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -18,8 +18,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifdef TARGET_DEFS_ONLY
+
 /* number of available registers */
-#define NB_REGS             4
+#define NB_REGS         4
+#define NB_ASM_REGS     8
 
 /* a register can belong to several classes. The classes must be
    sorted from more general to more precise (see gv2() code which does
@@ -42,13 +45,6 @@ enum {
     TREG_ST0,
 };
 
-const int reg_classes[NB_REGS] = {
-    /* eax */ RC_INT | RC_EAX,
-    /* ecx */ RC_INT | RC_ECX,
-    /* edx */ RC_INT | RC_EDX,
-    /* st0 */ RC_FLOAT | RC_ST0,
-};
-
 /* return registers for function */
 #define REG_IRET TREG_EAX /* single word int return register */
 #define REG_LRET TREG_EDX /* second word return register (for long long) */
@@ -70,6 +66,9 @@ const int reg_classes[NB_REGS] = {
 /* maximum alignment (for aligned attribute support) */
 #define MAX_ALIGN     8
 
+
+#define psym oad
+
 /******************************************************/
 /* ELF defines */
 
@@ -85,6 +84,16 @@ const int reg_classes[NB_REGS] = {
 #define ELF_PAGE_SIZE  0x1000
 
 /******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* eax */ RC_INT | RC_EAX,
+    /* ecx */ RC_INT | RC_ECX,
+    /* edx */ RC_INT | RC_EDX,
+    /* st0 */ RC_FLOAT | RC_ST0,
+};
 
 static unsigned long func_sub_sp_offset;
 static int func_ret_sub;
@@ -93,7 +102,7 @@ static unsigned long func_bound_offset;
 #endif
 
 /* XXX: make it faster ? */
-void g(int c)
+ST_FUNC void g(int c)
 {
     int ind1;
     ind1 = ind + 1;
@@ -103,7 +112,7 @@ void g(int c)
     ind = ind1;
 }
 
-void o(unsigned int c)
+ST_FUNC void o(unsigned int c)
 {
     while (c) {
         g(c);
@@ -111,13 +120,13 @@ void o(unsigned int c)
     }
 }
 
-void gen_le16(int v)
+ST_FUNC void gen_le16(int v)
 {
     g(v);
     g(v >> 8);
 }
 
-void gen_le32(int c)
+ST_FUNC void gen_le32(int c)
 {
     g(c);
     g(c >> 8);
@@ -126,7 +135,7 @@ void gen_le32(int c)
 }
 
 /* output a symbol and patch all calls to it */
-void gsym_addr(int t, int a)
+ST_FUNC void gsym_addr(int t, int a)
 {
     int n, *ptr;
     while (t) {
@@ -137,7 +146,7 @@ void gsym_addr(int t, int a)
     }
 }
 
-void gsym(int t)
+ST_FUNC void gsym(int t)
 {
     gsym_addr(t, ind);
 }
@@ -147,7 +156,7 @@ void gsym(int t)
 #define psym oad
 
 /* instruction + 4 bytes data. Return the address of the data */
-static int oad(int c, int s)
+ST_FUNC int oad(int c, int s)
 {
     int ind1;
 
@@ -162,14 +171,14 @@ static int oad(int c, int s)
 }
 
 /* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addr32(int r, Sym *sym, int c)
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
 {
     if (r & VT_SYM)
         greloc(cur_text_section, sym, ind, R_386_32);
     gen_le32(c);
 }
 
-static void gen_addrpc32(int r, Sym *sym, int c)
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
 {
     if (r & VT_SYM)
         greloc(cur_text_section, sym, ind, R_386_PC32);
@@ -200,7 +209,7 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c)
 }
 
 /* load 'r' from value 'sv' */
-void load(int r, SValue *sv)
+ST_FUNC void load(int r, SValue *sv)
 {
     int v, t, ft, fc, fr;
     SValue v1;
@@ -269,7 +278,7 @@ void load(int r, SValue *sv)
 }
 
 /* store register 'r' in lvalue 'v' */
-void store(int r, SValue *v)
+ST_FUNC void store(int r, SValue *v)
 {
     int fr, bt, ft, fc;
 
@@ -349,7 +358,7 @@ static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
 /* 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)
+ST_FUNC void gfunc_call(int nb_args)
 {
     int size, align, r, args_size, i, func_call;
     Sym *func_sym;
@@ -442,7 +451,7 @@ void gfunc_call(int nb_args)
 #endif
 
 /* generate function prolog of type 't' */
-void gfunc_prolog(CType *func_type)
+ST_FUNC void gfunc_prolog(CType *func_type)
 {
     int addr, align, size, func_call, fastcall_nb_regs;
     int param_index, param_addr;
@@ -524,7 +533,7 @@ void gfunc_prolog(CType *func_type)
 }
 
 /* generate function epilog */
-void gfunc_epilog(void)
+ST_FUNC void gfunc_epilog(void)
 {
     int v, saved_ind;
 
@@ -595,13 +604,13 @@ void gfunc_epilog(void)
 }
 
 /* generate a jump to a label */
-int gjmp(int t)
+ST_FUNC int gjmp(int t)
 {
     return psym(0xe9, t);
 }
 
 /* generate a jump to a fixed address */
-void gjmp_addr(int a)
+ST_FUNC void gjmp_addr(int a)
 {
     int r;
     r = a - ind - 2;
@@ -614,7 +623,7 @@ void gjmp_addr(int a)
 }
 
 /* generate a test. set 'inv' to invert test. Stack entry is popped */
-int gtst(int inv, int t)
+ST_FUNC int gtst(int inv, int t)
 {
     int v, *p;
 
@@ -659,7 +668,7 @@ int gtst(int inv, int t)
 }
 
 /* generate an integer binary operation */
-void gen_opi(int op)
+ST_FUNC void gen_opi(int op)
 {
     int r, fr, opc, c;
 
@@ -793,7 +802,7 @@ void gen_opi(int op)
 /* generate a floating point operation 'v = t1 op t2' instruction. The
    two operands are guaranted to have the same floating point type */
 /* XXX: need to use ST1 too */
-void gen_opf(int op)
+ST_FUNC void gen_opf(int op)
 {
     int a, ft, fc, swapped, r;
 
@@ -905,7 +914,7 @@ void gen_opf(int op)
 
 /* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
    and 'long long' cases. */
-void gen_cvt_itof(int t)
+ST_FUNC void gen_cvt_itof(int t)
 {
     save_reg(TREG_ST0);
     gv(RC_INT);
@@ -935,7 +944,7 @@ void gen_cvt_itof(int t)
 
 /* convert fp to int 't' type */
 /* XXX: handle long long case */
-void gen_cvt_ftoi(int t)
+ST_FUNC void gen_cvt_ftoi(int t)
 {
     int r, r2, size;
     Sym *sym;
@@ -986,14 +995,14 @@ void gen_cvt_ftoi(int t)
 }
 
 /* convert from one floating point type to another */
-void gen_cvt_ftof(int t)
+ST_FUNC void gen_cvt_ftof(int t)
 {
     /* all we have to do on i386 is to put the float in a register */
     gv(RC_FLOAT);
 }
 
 /* computed goto support */
-void ggoto(void)
+ST_FUNC void ggoto(void)
 {
     gcall_or_jmp(1);
     vtop--;
@@ -1003,7 +1012,7 @@ void ggoto(void)
 #ifdef CONFIG_TCC_BCHECK
 
 /* generate a bounded pointer addition */
-void gen_bounded_ptr_add(void)
+ST_FUNC void gen_bounded_ptr_add(void)
 {
     Sym *sym;
 
@@ -1026,7 +1035,7 @@ void gen_bounded_ptr_add(void)
 
 /* patch pointer addition in vtop so that pointer dereferencing is
    also tested */
-void gen_bounded_ptr_deref(void)
+ST_FUNC void gen_bounded_ptr_deref(void)
 {
     int func;
     int size, align;
@@ -1068,4 +1077,5 @@ void gen_bounded_ptr_deref(void)
 
 /* end of X86 code generator */
 /*************************************************************/
-
+#endif
+/*************************************************************/
diff --git a/libtcc.c b/libtcc.c
index 7ef1f0b4..9be8c1c6 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -23,344 +23,70 @@
 /********************************************************/
 /* global variables */
 
-/* display benchmark infos */
-int total_lines;
-int total_bytes;
-
-/* parser */
-static struct BufferedFile *file;
-static int ch, tok;
-static CValue tokc;
-static CString tokcstr; /* current parsed string, if any */
-/* additional informations about token */
-static int tok_flags;
-#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 */
-
-static int *macro_ptr, *macro_ptr_allocated;
-static int *unget_saved_macro_ptr;
-static int unget_saved_buffer[TOK_MAX_SIZE + 1];
-static int unget_buffer_enabled;
-static 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) */
- 
-static Section *text_section, *data_section, *bss_section; /* predefined sections */
-static Section *cur_text_section; /* current section where function code is
-                              generated */
-#ifdef CONFIG_TCC_ASM
-static Section *last_text_section; /* to handle .previous asm directive */
-#endif
-
-#ifdef CONFIG_TCC_BCHECK
-/* bound check related sections */
-static Section *bounds_section; /* contains global data bound description */
-static Section *lbounds_section; /* contains local data bound description */
-#endif
-
-/* symbol sections */
-static Section *symtab_section, *strtab_section;
-
-/* debug sections */
-static Section *stab_section, *stabstr_section;
-
-/* loc : local variable index
-   ind : output code index
-   rsym: return symbol
-   anon_sym: anonymous symbol index
-*/
-static int rsym, anon_sym, ind, loc;
-/* expression generation modifiers */
-static int const_wanted; /* true if constant wanted */
-static int nocode_wanted; /* true if no code generation wanted for an expression */
-static int global_expr;  /* true if compound literals must be allocated
-                            globally (used during initializers parsing */
-static CType func_vt; /* current function return type (used by return
-                         instruction) */
-static int func_vc;
-static int last_line_num, last_ind, func_ind; /* debug last line number and pc */
-static int tok_ident;
-static TokenSym **table_ident;
-static TokenSym *hash_ident[TOK_HASH_SIZE];
-static char token_buf[STRING_MAX_SIZE + 1];
-static char *funcname;
-static Sym *global_stack, *local_stack;
-static Sym *define_stack;
-static Sym *global_label_stack, *local_label_stack;
-/* symbol allocator */
-#define SYM_POOL_NB (8192 / sizeof(Sym))
-static Sym *sym_free_first;
-static void **sym_pools;
-static int nb_sym_pools;
-
-static SValue vstack[VSTACK_SIZE], *vtop;
-/* some predefined types */
-static CType char_pointer_type, func_old_type, int_type;
-
 /* use GNU C extensions */
-static int gnu_ext = 1;
+ST_DATA int gnu_ext = 1;
 
-/* use Tiny C extensions */
-static int tcc_ext = 1;
-
-/* max number of callers shown if error */
-#ifdef CONFIG_TCC_BACKTRACE
-int num_callers = 6;
-void *rt_prog_main;
-const char **rt_bound_error_msg;
-#endif
+/* use TinyCC extensions */
+ST_DATA int tcc_ext = 1;
 
 /* XXX: get rid of this ASAP */
-static struct TCCState *tcc_state;
+ST_DATA struct TCCState *tcc_state;
 
-/********************************************************/
-/* function prototypes */
-
-/* tccpp.c */
-static void next(void);
-char *get_tok_str(int v, CValue *cv);
-
-/* tccgen.c */
-static void parse_expr_type(CType *type);
-static void expr_type(CType *type);
-static void unary_type(CType *type);
-static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
-                  int case_reg, int is_expr);
-static int expr_const(void);
-static void expr_eq(void);
-static void gexpr(void);
-static void gen_inline_functions(void);
-static void decl(int l);
-static void decl_initializer(CType *type, Section *sec, unsigned long c, 
-                             int first, int size_only);
-static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
-                                   int has_init, int v, int scope);
-int gv(int rc);
-void gv2(int rc1, int rc2);
-void move_reg(int r, int s);
-void save_regs(int n);
-void save_reg(int r);
-void vpop(void);
-void vswap(void);
-void vdup(void);
-int get_reg(int rc);
-int get_reg_ex(int rc,int rc2);
-
-void gen_op(int op);
-void force_charshort_cast(int t);
-static void gen_cast(CType *type);
-void vstore(void);
-static Sym *sym_find(int v);
-static Sym *sym_push(int v, CType *type, int r, int c);
-
-/* type handling */
-static int type_size(CType *type, int *a);
-static inline CType *pointed_type(CType *type);
-static int pointed_size(CType *type);
-static int lvalue_type(int t);
-static int parse_btype(CType *type, AttributeDef *ad);
-static void type_decl(CType *type, AttributeDef *ad, int *v, int td);
-static int compare_types(CType *type1, CType *type2, int unqualified);
-static int is_compatible_types(CType *type1, CType *type2);
-static int is_compatible_parameter_types(CType *type1, CType *type2);
-
-int ieee_finite(double d);
-void vpushi(int v);
-void vpushll(long long v);
-void vrott(int n);
-void vnrott(int n);
-void lexpand_nr(void);
-static void vpush_global_sym(CType *type, int v);
-void vset(CType *type, int r, int v);
-void type_to_str(char *buf, int buf_size, 
-                 CType *type, const char *varstr);
-static Sym *get_sym_ref(CType *type, Section *sec,
-                        unsigned long offset, unsigned long size);
-static Sym *external_global_sym(int v, CType *type, int r);
-
-/* section generation */
-static void section_realloc(Section *sec, unsigned long new_size);
-static void *section_ptr_add(Section *sec, unsigned long size);
-static void put_extern_sym(Sym *sym, Section *section, 
-                           unsigned long value, unsigned long size);
-static void greloc(Section *s, Sym *sym, unsigned long addr, int type);
-static int put_elf_str(Section *s, const char *sym);
-static int put_elf_sym(Section *s, 
-                       unsigned long value, unsigned long size,
-                       int info, int other, int shndx, const char *name);
-static int add_elf_sym(Section *s, uplong value, unsigned long size,
-                       int info, int other, int sh_num, const char *name);
-static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
-                          int type, int symbol);
-static void put_stabs(const char *str, int type, int other, int desc, 
-                      unsigned long value);
-static void put_stabs_r(const char *str, int type, int other, int desc, 
-                        unsigned long value, Section *sec, int sym_index);
-static void put_stabn(int type, int other, int desc, int value);
-static void put_stabd(int type, int other, int desc);
-static int tcc_add_dll(TCCState *s, const char *filename, int flags);
-
-#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 */
-static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
-
-/* tcccoff.c */
-int tcc_output_coff(TCCState *s1, FILE *f);
-
-/* tccpe.c */
-int pe_load_file(struct TCCState *s1, const char *filename, int fd);
-int pe_output_file(struct TCCState *s1, const char *filename);
-int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
-
-/* tccasm.c */
-#ifdef CONFIG_TCC_ASM
-static void asm_expr(TCCState *s1, ExprValue *pe);
-static int asm_int_expr(TCCState *s1);
-static int find_constraint(ASMOperand *operands, int nb_operands, 
-                           const char *name, const char **pp);
-
-static int tcc_assemble(TCCState *s1, int do_preprocess);
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int num_callers = 6;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
 #endif
 
-static void asm_instr(void);
-static void asm_global_instr(void);
-
-/********************************************************/
-/* libtcc.c */
-
-static Sym *__sym_malloc(void);
-static inline Sym *sym_malloc(void);
-static inline void sym_free(Sym *sym);
-Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
-static void free_section(Section *s);
-static void section_realloc(Section *sec, unsigned long new_size);
-static void *section_ptr_add(Section *sec, unsigned long size);
-Section *find_section(TCCState *s1, const char *name);
-static void put_extern_sym2(
-    Sym *sym, Section *section,
-    unsigned long value, unsigned long size, int can_add_underscore);
-static void put_extern_sym(
-    Sym *sym, Section *section,
-    unsigned long value, unsigned long size);
-static void greloc(Section *s, Sym *sym, unsigned long offset, int type);
-
-static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap);
-static void strcat_printf(char *buf, int buf_size, const char *fmt, ...);
-
-/* CString handling */
-static void cstr_realloc(CString *cstr, int new_size);
-static inline void cstr_ccat(CString *cstr, int ch);
-static void cstr_cat(CString *cstr, const char *str);
-static void cstr_wccat(CString *cstr, int ch);
-static void cstr_new(CString *cstr);
-static void cstr_free(CString *cstr);
-#define cstr_reset(cstr) cstr_free(cstr)
-static void add_char(CString *cstr, int c);
-
-static Sym *sym_push2(Sym **ps, int v, int t, long c);
-static Sym *sym_find2(Sym *s, int v);
-static inline Sym *struct_find(int v);
-static inline Sym *sym_find(int v);
-static Sym *sym_push(int v, CType *type, int r, int c);
-static Sym *global_identifier_push(int v, int t, int c);
-static void sym_pop(Sym **ptop, Sym *b);
-
-BufferedFile *tcc_open(TCCState *s1, const char *filename);
-void tcc_close(BufferedFile *bf);
-static int tcc_compile(TCCState *s1);
-
-void expect(const char *msg);
-void skip(int c);
-static void test_lvalue(void);
-void *resolve_sym(TCCState *s1, const char *sym);
-
-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)
-{
-    if (c >= 'a' && c <= 'z')
-        return c - 'a' + 'A';
-    else
-        return c;
-}
-
 /********************************************************/
 
+#ifndef NOTALLINONE
+#include "tccpp.c"
+#include "tccgen.c"
+#include "tccelf.c"
+#include "tccrun.c"
 #ifdef TCC_TARGET_I386
 #include "i386-gen.c"
 #endif
-
 #ifdef TCC_TARGET_ARM
 #include "arm-gen.c"
 #endif
-
 #ifdef TCC_TARGET_C67
 #include "c67-gen.c"
 #endif
-
 #ifdef TCC_TARGET_X86_64
 #include "x86_64-gen.c"
 #endif
-
-#include "tccpp.c"
-#include "tccgen.c"
-
 #ifdef CONFIG_TCC_ASM
-
+#include "tccasm.c"
 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
 #include "i386-asm.c"
 #endif
-
-#include "tccasm.c"
-#else
-static void asm_instr(void)
-{
-    error("inline asm() not supported");
-}
-static void asm_global_instr(void)
-{
-    error("inline asm() not supported");
-}
 #endif
-
-#include "tccelf.c"
-
 #ifdef TCC_TARGET_COFF
 #include "tcccoff.c"
 #endif
-
 #ifdef TCC_TARGET_PE
 #include "tccpe.c"
 #endif
-
-#include "tccrun.c"
+#endif /* ALL_IN_ONE */
 
 /********************************************************/
+#ifndef CONFIG_TCC_ASM
+ST_FUNC void asm_instr(void)
+{
+    error("inline asm() not supported");
+}
+ST_FUNC void asm_global_instr(void)
+{
+    error("inline asm() not supported");
+}
+#endif
+
+/********************************************************/
+
 #ifdef _WIN32
-char *normalize_slashes(char *path)
+static char *normalize_slashes(char *path)
 {
     char *p;
     for (p = path; *p; ++p)
@@ -369,10 +95,10 @@ char *normalize_slashes(char *path)
     return path;
 }
 
-HMODULE tcc_module;
+static HMODULE tcc_module;
 
 /* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
-void tcc_set_lib_path_w32(TCCState *s)
+static void tcc_set_lib_path_w32(TCCState *s)
 {
     char path[1024], *p;
     GetModuleFileNameA(tcc_module, path, sizeof path);
@@ -396,18 +122,8 @@ BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
 #endif
 
 /********************************************************/
-
-/* we use our own 'finite' function to avoid potential problems with
-   non standard math libs */
-/* XXX: endianness dependent */
-int ieee_finite(double d)
-{
-    int *p = (int *)&d;
-    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
-}
-
 /* copy a string and truncate it. */
-char *pstrcpy(char *buf, int buf_size, const char *s)
+PUB_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
 {
     char *q, *q_end;
     int c;
@@ -427,7 +143,7 @@ char *pstrcpy(char *buf, int buf_size, const char *s)
 }
 
 /* strcat and truncate. */
-char *pstrcat(char *buf, int buf_size, const char *s)
+PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
 {
     int len;
     len = strlen(buf);
@@ -437,7 +153,7 @@ char *pstrcat(char *buf, int buf_size, const char *s)
 }
 
 /* extract the basename of a file */
-char *tcc_basename(const char *name)
+PUB_FUNC char *tcc_basename(const char *name)
 {
     char *p = strchr(name, 0);
     while (p > name && !IS_PATHSEP(p[-1]))
@@ -445,21 +161,27 @@ char *tcc_basename(const char *name)
     return p;
 }
 
-char *tcc_fileextension (const char *name)
+PUB_FUNC char *tcc_fileextension (const char *name)
 {
     char *b = tcc_basename(name);
     char *e = strrchr(b, '.');
     return e ? e : strchr(b, 0);
 }
 
+/********************************************************/
 /* memory management */
+
+#undef free
+#undef malloc
+#undef realloc
+
 #ifdef MEM_DEBUG
 int mem_cur_size;
 int mem_max_size;
 unsigned malloc_usable_size(void*);
 #endif
 
-void tcc_free(void *ptr)
+PUB_FUNC void tcc_free(void *ptr)
 {
 #ifdef MEM_DEBUG
     mem_cur_size -= malloc_usable_size(ptr);
@@ -467,7 +189,7 @@ void tcc_free(void *ptr)
     free(ptr);
 }
 
-void *tcc_malloc(unsigned long size)
+PUB_FUNC void *tcc_malloc(unsigned long size)
 {
     void *ptr;
     ptr = malloc(size);
@@ -481,7 +203,7 @@ void *tcc_malloc(unsigned long size)
     return ptr;
 }
 
-void *tcc_mallocz(unsigned long size)
+PUB_FUNC void *tcc_mallocz(unsigned long size)
 {
     void *ptr;
     ptr = tcc_malloc(size);
@@ -489,7 +211,7 @@ void *tcc_mallocz(unsigned long size)
     return ptr;
 }
 
-void *tcc_realloc(void *ptr, unsigned long size)
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
 {
     void *ptr1;
 #ifdef MEM_DEBUG
@@ -505,7 +227,7 @@ void *tcc_realloc(void *ptr, unsigned long size)
     return ptr1;
 }
 
-char *tcc_strdup(const char *str)
+PUB_FUNC char *tcc_strdup(const char *str)
 {
     char *ptr;
     ptr = tcc_malloc(strlen(str) + 1);
@@ -513,7 +235,7 @@ char *tcc_strdup(const char *str)
     return ptr;
 }
 
-void tcc_memstats(void)
+PUB_FUNC void tcc_memstats(void)
 {
 #ifdef MEM_DEBUG
     printf("memory in use: %d\n", mem_cur_size);
@@ -524,7 +246,10 @@ void tcc_memstats(void)
 #define malloc(s) use_tcc_malloc(s)
 #define realloc(p, s) use_tcc_realloc(p, s)
 
-void dynarray_add(void ***ptab, int *nb_ptr, void *data)
+/********************************************************/
+/* dynarrays */
+
+PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data)
 {
     int nb, nb_alloc;
     void **pp;
@@ -546,7 +271,7 @@ void dynarray_add(void ***ptab, int *nb_ptr, void *data)
     *nb_ptr = nb;
 }
 
-void dynarray_reset(void *pp, int *n)
+PUB_FUNC void dynarray_reset(void *pp, int *n)
 {
     void **p;
     for (p = *(void***)pp; *n; ++p, --*n)
@@ -556,43 +281,18 @@ void dynarray_reset(void *pp, int *n)
     *(void**)pp = NULL;
 }
 
-/* symbol allocator */
-static Sym *__sym_malloc(void)
+/* we use our own 'finite' function to avoid potential problems with
+   non standard math libs */
+/* XXX: endianness dependent */
+ST_FUNC int ieee_finite(double d)
 {
-    Sym *sym_pool, *sym, *last_sym;
-    int i;
-
-    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
-    dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
-
-    last_sym = sym_free_first;
-    sym = sym_pool;
-    for(i = 0; i < SYM_POOL_NB; i++) {
-        sym->next = last_sym;
-        last_sym = sym;
-        sym++;
-    }
-    sym_free_first = last_sym;
-    return last_sym;
+    int *p = (int *)&d;
+    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
 }
 
-static inline Sym *sym_malloc(void)
-{
-    Sym *sym;
-    sym = sym_free_first;
-    if (!sym)
-        sym = __sym_malloc();
-    sym_free_first = sym->next;
-    return sym;
-}
+/********************************************************/
 
-static inline void sym_free(Sym *sym)
-{
-    sym->next = sym_free_first;
-    sym_free_first = sym;
-}
-
-Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
 {
     Section *sec;
 
@@ -633,7 +333,7 @@ static void free_section(Section *s)
 }
 
 /* realloc section and set its content to zero */
-static void section_realloc(Section *sec, unsigned long new_size)
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
 {
     unsigned long size;
     unsigned char *data;
@@ -653,7 +353,7 @@ static void section_realloc(Section *sec, unsigned long new_size)
 
 /* reserve at least 'size' bytes in section 'sec' from
    sec->data_offset. */
-static void *section_ptr_add(Section *sec, unsigned long size)
+ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
 {
     unsigned long offset, offset1;
 
@@ -667,7 +367,7 @@ static void *section_ptr_add(Section *sec, unsigned long size)
 
 /* return a reference to a section, and create it if it does not
    exists */
-Section *find_section(TCCState *s1, const char *name)
+ST_FUNC Section *find_section(TCCState *s1, const char *name)
 {
     Section *sec;
     int i;
@@ -682,7 +382,7 @@ Section *find_section(TCCState *s1, const char *name)
 
 /* update sym->c so that it points to an external symbol in section
    'section' with value 'value' */
-static void put_extern_sym2(Sym *sym, Section *section, 
+ST_FUNC void put_extern_sym2(Sym *sym, Section *section, 
                             unsigned long value, unsigned long size,
                             int can_add_underscore)
 {
@@ -779,14 +479,14 @@ static void put_extern_sym2(Sym *sym, Section *section,
     }
 }
 
-static void put_extern_sym(Sym *sym, Section *section, 
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, 
                            unsigned long value, unsigned long size)
 {
     put_extern_sym2(sym, section, value, size, 1);
 }
 
 /* add a new relocation entry to symbol 'sym' in section 's' */
-static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
 {
     int c = 0;
     if (sym) {
@@ -798,6 +498,8 @@ static void greloc(Section *s, Sym *sym, unsigned long offset, int type)
     put_elf_reloc(symtab_section, s, offset, type, c);
 }
 
+/********************************************************/
+
 static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
 {
     int len;
@@ -813,7 +515,7 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
     va_end(ap);
 }
 
-void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
+static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
 {
     char buf[2048];
     BufferedFile **f;
@@ -850,7 +552,7 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
         s1->nb_errors++;
 }
 
-void tcc_set_error_func(TCCState *s, void *error_opaque,
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
                         void (*error_func)(void *opaque, const char *msg))
 {
     s->error_opaque = error_opaque;
@@ -858,7 +560,7 @@ void tcc_set_error_func(TCCState *s, void *error_opaque,
 }
 
 /* error without aborting current compilation */
-void error_noabort(const char *fmt, ...)
+PUB_FUNC void error_noabort(const char *fmt, ...)
 {
     TCCState *s1 = tcc_state;
     va_list ap;
@@ -868,7 +570,7 @@ void error_noabort(const char *fmt, ...)
     va_end(ap);
 }
 
-void error(const char *fmt, ...)
+PUB_FUNC void error(const char *fmt, ...)
 {
     TCCState *s1 = tcc_state;
     va_list ap;
@@ -885,12 +587,12 @@ void error(const char *fmt, ...)
     }
 }
 
-void expect(const char *msg)
+PUB_FUNC void expect(const char *msg)
 {
     error("%s expected", msg);
 }
 
-void warning(const char *fmt, ...)
+PUB_FUNC void warning(const char *fmt, ...)
 {
     TCCState *s1 = tcc_state;
     va_list ap;
@@ -903,233 +605,10 @@ void warning(const char *fmt, ...)
     va_end(ap);
 }
 
-void skip(int c)
-{
-    if (tok != c)
-        error("'%c' expected", c);
-    next();
-}
-
-static void test_lvalue(void)
-{
-    if (!(vtop->r & VT_LVAL))
-        expect("lvalue");
-}
-
-/* CString handling */
-
-static void cstr_realloc(CString *cstr, int new_size)
-{
-    int size;
-    void *data;
-
-    size = cstr->size_allocated;
-    if (size == 0)
-        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);
-    if (!data)
-        error("memory full");
-    cstr->data_allocated = data;
-    cstr->size_allocated = size;
-    cstr->data = data;
-}
-
-/* add a byte */
-static inline void cstr_ccat(CString *cstr, int ch)
-{
-    int size;
-    size = cstr->size + 1;
-    if (size > cstr->size_allocated)
-        cstr_realloc(cstr, size);
-    ((unsigned char *)cstr->data)[size - 1] = ch;
-    cstr->size = size;
-}
-
-static void cstr_cat(CString *cstr, const char *str)
-{
-    int c;
-    for(;;) {
-        c = *str;
-        if (c == '\0')
-            break;
-        cstr_ccat(cstr, c);
-        str++;
-    }
-}
-
-/* add a wide char */
-static void cstr_wccat(CString *cstr, int ch)
-{
-    int size;
-    size = cstr->size + sizeof(nwchar_t);
-    if (size > cstr->size_allocated)
-        cstr_realloc(cstr, size);
-    *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
-    cstr->size = size;
-}
-
-static void cstr_new(CString *cstr)
-{
-    memset(cstr, 0, sizeof(CString));
-}
-
-/* free string and reset it to NULL */
-static void cstr_free(CString *cstr)
-{
-    tcc_free(cstr->data_allocated);
-    cstr_new(cstr);
-}
-
-#define cstr_reset(cstr) cstr_free(cstr)
-
-/* XXX: unicode ? */
-static void add_char(CString *cstr, int c)
-{
-    if (c == '\'' || c == '\"' || c == '\\') {
-        /* XXX: could be more precise if char or string */
-        cstr_ccat(cstr, '\\');
-    }
-    if (c >= 32 && c <= 126) {
-        cstr_ccat(cstr, c);
-    } else {
-        cstr_ccat(cstr, '\\');
-        if (c == '\n') {
-            cstr_ccat(cstr, 'n');
-        } else {
-            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
-            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
-            cstr_ccat(cstr, '0' + (c & 7));
-        }
-    }
-}
-
-/* push, without hashing */
-static Sym *sym_push2(Sym **ps, int v, int t, long c)
-{
-    Sym *s;
-    s = sym_malloc();
-    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;
-    *ps = s;
-    return s;
-}
-
-/* find a symbol and return its associated structure. 's' is the top
-   of the symbol stack */
-static Sym *sym_find2(Sym *s, int v)
-{
-    while (s) {
-        if (s->v == v)
-            return s;
-        s = s->prev;
-    }
-    return NULL;
-}
-
-/* structure lookup */
-static inline Sym *struct_find(int v)
-{
-    v -= TOK_IDENT;
-    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
-        return NULL;
-    return table_ident[v]->sym_struct;
-}
-
-/* find an identifier */
-static inline Sym *sym_find(int v)
-{
-    v -= TOK_IDENT;
-    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
-        return NULL;
-    return table_ident[v]->sym_identifier;
-}
-
-/* push a given symbol on the symbol stack */
-static Sym *sym_push(int v, CType *type, int r, int c)
-{
-    Sym *s, **ps;
-    TokenSym *ts;
-
-    if (local_stack)
-        ps = &local_stack;
-    else
-        ps = &global_stack;
-    s = sym_push2(ps, v, type->t, c);
-    s->type.ref = type->ref;
-    s->r = r;
-    /* don't record fields or anonymous symbols */
-    /* XXX: simplify */
-    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
-        /* record symbol in token array */
-        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
-        if (v & SYM_STRUCT)
-            ps = &ts->sym_struct;
-        else
-            ps = &ts->sym_identifier;
-        s->prev_tok = *ps;
-        *ps = s;
-    }
-    return s;
-}
-
-/* push a global identifier */
-static Sym *global_identifier_push(int v, int t, int c)
-{
-    Sym *s, **ps;
-    s = sym_push2(&global_stack, v, t, c);
-    /* don't record anonymous symbol */
-    if (v < SYM_FIRST_ANOM) {
-        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
-        /* modify the top most local identifier, so that
-           sym_identifier will point to 's' when popped */
-        while (*ps != NULL)
-            ps = &(*ps)->prev_tok;
-        s->prev_tok = NULL;
-        *ps = s;
-    }
-    return s;
-}
-
-/* pop symbols until top reaches 'b' */
-static void sym_pop(Sym **ptop, Sym *b)
-{
-    Sym *s, *ss, **ps;
-    TokenSym *ts;
-    int v;
-
-    s = *ptop;
-    while(s != b) {
-        ss = s->prev;
-        v = s->v;
-        /* remove symbol in token array */
-        /* XXX: simplify */
-        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
-            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
-            if (v & SYM_STRUCT)
-                ps = &ts->sym_struct;
-            else
-                ps = &ts->sym_identifier;
-            *ps = s->prev_tok;
-        }
-        sym_free(s);
-        s = ss;
-    }
-    *ptop = b;
-}
-
+/********************************************************/
 /* I/O layer */
 
-BufferedFile *tcc_open(TCCState *s1, const char *filename)
+ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename)
 {
     int fd;
     BufferedFile *bf;
@@ -1159,7 +638,7 @@ BufferedFile *tcc_open(TCCState *s1, const char *filename)
     return bf;
 }
 
-void tcc_close(BufferedFile *bf)
+ST_FUNC void tcc_close(BufferedFile *bf)
 {
     total_lines += bf->line_num;
     close(bf->fd);
@@ -1272,7 +751,7 @@ static int tcc_compile(TCCState *s1)
     return s1->nb_errors != 0 ? -1 : 0;
 }
 
-int tcc_compile_string(TCCState *s, const char *str)
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
 {
     BufferedFile bf1, *bf = &bf1;
     int ret, len;
@@ -1301,7 +780,7 @@ int tcc_compile_string(TCCState *s, const char *str)
 }
 
 /* define a preprocessor symbol. A value can also be provided with the '=' operator */
-void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
+LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
 {
     BufferedFile bf1, *bf = &bf1;
 
@@ -1331,7 +810,7 @@ void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
 }
 
 /* undefine a preprocessor symbol */
-void tcc_undefine_symbol(TCCState *s1, const char *sym)
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
 {
     TokenSym *ts;
     Sym *s;
@@ -1369,7 +848,7 @@ static void tcc_cleanup(void)
     macro_ptr = NULL;
 }
 
-TCCState *tcc_new(void)
+LIBTCCAPI TCCState *tcc_new(void)
 {
     TCCState *s;
     char buffer[100];
@@ -1477,6 +956,7 @@ TCCState *tcc_new(void)
                                       ".dynstrtab", 
                                       ".dynhashtab", SHF_PRIVATE);
     s->alacarte_link = 1;
+    s->nocommon = 1;
 
 #ifdef CHAR_IS_UNSIGNED
     s->char_is_unsigned = 1;
@@ -1485,17 +965,15 @@ TCCState *tcc_new(void)
     /* XXX: currently the PE linker is not ready to support that */
     s->leading_underscore = 1;
 #endif
-
     if (s->section_align == 0)
         s->section_align = ELF_PAGE_SIZE;
-
 #ifdef TCC_TARGET_I386
     s->seg_size = 32;
 #endif
     return s;
 }
 
-void tcc_delete(TCCState *s1)
+LIBTCCAPI void tcc_delete(TCCState *s1)
 {
     int i;
 
@@ -1533,7 +1011,7 @@ void tcc_delete(TCCState *s1)
     tcc_free(s1);
 }
 
-int tcc_add_include_path(TCCState *s1, const char *pathname)
+LIBTCCAPI int tcc_add_include_path(TCCState *s1, const char *pathname)
 {
     char *pathname1;
     
@@ -1542,7 +1020,7 @@ int tcc_add_include_path(TCCState *s1, const char *pathname)
     return 0;
 }
 
-int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
 {
     char *pathname1;
     
@@ -1668,7 +1146,7 @@ the_end:
     return ret;
 }
 
-int tcc_add_file(TCCState *s, const char *filename)
+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);
@@ -1676,7 +1154,7 @@ int tcc_add_file(TCCState *s, const char *filename)
         return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
 }
 
-int tcc_add_library_path(TCCState *s, const char *pathname)
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
 {
     char *pathname1;
     
@@ -1687,7 +1165,7 @@ int tcc_add_library_path(TCCState *s, const char *pathname)
 
 /* find and load a dll. Return non zero if not found */
 /* XXX: add '-rpath' option support ? */
-static int tcc_add_dll(TCCState *s, const char *filename, int flags)
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
 {
     char buf[1024];
     int i;
@@ -1702,7 +1180,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags)
 }
 
 /* the library name is the same as the argument of the '-l' option */
-int tcc_add_library(TCCState *s, const char *libraryname)
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
 {
     char buf[1024];
     int i;
@@ -1728,7 +1206,7 @@ int tcc_add_library(TCCState *s, const char *libraryname)
     return -1;
 }
 
-int tcc_add_symbol(TCCState *s, const char *name, void *val)
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val)
 {
     add_elf_sym(symtab_section, (uplong)val, 0,
                 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
@@ -1736,7 +1214,7 @@ int tcc_add_symbol(TCCState *s, const char *name, void *val)
     return 0;
 }
 
-int tcc_set_output_type(TCCState *s, int output_type)
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
 {
     char buf[1024];
 
@@ -1825,7 +1303,7 @@ static const FlagDef warning_defs[] = {
       "implicit-function-declaration" },
 };
 
-static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
+ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
                     const char *name, int value)
 {
     int i;
@@ -1849,9 +1327,8 @@ static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
     return 0;
 }
 
-
 /* set/reset a warning */
-int tcc_set_warning(TCCState *s, const char *warning_name, int value)
+LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value)
 {
     int i;
     const FlagDef *p;
@@ -1876,20 +1353,13 @@ static const FlagDef flag_defs[] = {
 };
 
 /* set/reset a flag */
-int tcc_set_flag(TCCState *s, const char *flag_name, int value)
+PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value)
 {
     return set_flag(s, flag_defs, countof(flag_defs),
                     flag_name, value);
 }
 
-/* set CONFIG_TCCDIR at runtime */
-void tcc_set_lib_path(TCCState *s, const char *path)
-{
-    tcc_free(s->tcc_lib_path);
-    s->tcc_lib_path = tcc_strdup(path);
-}
-
-void tcc_print_stats(TCCState *s, int64_t total_time)
+PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
 {
     double tt;
     tt = (double)total_time / 1000000.0;
@@ -1902,3 +1372,17 @@ void tcc_print_stats(TCCState *s, int64_t total_time)
            tt, (int)(total_lines / tt),
            total_bytes / tt / 1000000.0);
 }
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
+{
+    tcc_free(s->tcc_lib_path);
+    s->tcc_lib_path = tcc_strdup(path);
+}
+
+PUB_FUNC void set_num_callers(int n)
+{
+#ifdef CONFIG_TCC_BACKTRACE
+    num_callers = n;
+#endif
+}
diff --git a/tcc.c b/tcc.c
index aeda4689..6c12b203 100644
--- a/tcc.c
+++ b/tcc.c
@@ -18,13 +18,25 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef TCC_USE_LIBTCC
+#if defined NOTALLINONE || defined TCC_USE_LIBTCC
 #include "tcc.h"
 #else
 #include "libtcc.c"
 #endif
 
-void help(void)
+static char **files;
+static int nb_files, nb_libraries;
+static int multiple_files;
+static int print_search_dirs;
+static int output_type;
+static int reloc_output;
+static const char *outfile;
+static int do_bench = 0;
+
+#define TCC_OPTION_HAS_ARG 0x0001
+#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
+
+static void help(void)
 {
     printf("tcc version " TCC_VERSION " - Tiny C Compiler - Copyright (C) 2001-2006 Fabrice Bellard\n"
            "usage: tcc [-v] [-c] [-o outfile] [-Bdir] [-bench] [-Idir] [-Dsym[=val]] [-Usym]\n"
@@ -65,18 +77,6 @@ void help(void)
            );
 }
 
-static char **files;
-static int nb_files, nb_libraries;
-static int multiple_files;
-static int print_search_dirs;
-static int output_type;
-static int reloc_output;
-static const char *outfile;
-static int do_bench = 0;
-
-#define TCC_OPTION_HAS_ARG 0x0001
-#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
-
 typedef struct TCCOption {
     const char *name;
     uint16_t index;
@@ -213,7 +213,7 @@ static int expand_args(char ***pargv, const char *str)
     return argc;
 }
 
-int parse_args(TCCState *s, int argc, char **argv)
+static int parse_args(TCCState *s, int argc, char **argv)
 {
     int optind;
     const TCCOption *popt;
@@ -304,7 +304,7 @@ int parse_args(TCCState *s, int argc, char **argv)
                 break;
 #ifdef CONFIG_TCC_BACKTRACE
             case TCC_OPTION_bt:
-                num_callers = atoi(optarg);
+                set_num_callers(atoi(optarg));
                 break;
 #endif
 #ifdef CONFIG_TCC_BCHECK
diff --git a/tcc.h b/tcc.h
index 16aba534..ea4ae21a 100644
--- a/tcc.h
+++ b/tcc.h
@@ -18,6 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _TCC_H
+#define _TCC_H
+
 #define _GNU_SOURCE
 #include "config.h"
 
@@ -46,6 +49,7 @@
 #include <direct.h> /* getcwd */
 #define inline __inline
 #define inp next_inp
+#define dlclose FreeLibrary
 #ifdef _WIN64
 #define uplong unsigned long long
 #endif
@@ -56,6 +60,7 @@
 #include <sys/time.h>
 #include <sys/ucontext.h>
 #include <sys/mman.h>
+#include <dlfcn.h>
 #endif
 
 #endif /* !CONFIG_TCCBOOT */
@@ -766,11 +771,11 @@ enum tcc_token {
 #elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
     || defined(__OpenBSD__)
 /* currently incorrect */
-long double strtold(const char *nptr, char **endptr)
+static inline long double strtold(const char *nptr, char **endptr)
 {
     return (long double)strtod(nptr, endptr);
 }
-float strtof(const char *nptr, char **endptr)
+static inline float strtof(const char *nptr, char **endptr)
 {
     return (float)strtod(nptr, endptr);
 }
@@ -790,38 +795,411 @@ extern long double strtold (const char *__nptr, char **__endptr);
 #define PATHCMP strcmp
 #endif
 
-void error(const char *fmt, ...);
-void error_noabort(const char *fmt, ...);
-void warning(const char *fmt, ...);
-
-void tcc_set_lib_path_w32(TCCState *s);
-int tcc_set_flag(TCCState *s, const char *flag_name, int value);
-void tcc_print_stats(TCCState *s, int64_t total_time);
-
-void tcc_free(void *ptr);
-void *tcc_malloc(unsigned long size);
-void *tcc_mallocz(unsigned long size);
-void *tcc_realloc(void *ptr, unsigned long size);
-char *tcc_strdup(const char *str);
-
-char *tcc_basename(const char *name);
-char *tcc_fileextension (const char *name);
-char *pstrcpy(char *buf, int buf_size, const char *s);
-char *pstrcat(char *buf, int buf_size, const char *s);
-void dynarray_add(void ***ptab, int *nb_ptr, void *data);
-void dynarray_reset(void *pp, int *n);
-
-/* true if float/double/long double type */
-static inline int is_float(int t)
-{
-    int bt;
-    bt = t & VT_BTYPE;
-    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
-}
-
 /* 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;
+}
+
+#define PUB_FUNC 
+
+#ifndef NOTALLINONE
+#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 ------------ */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext;
+/* use Tiny C extensions */
+ST_DATA int tcc_ext;
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int num_callers;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+#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 *tcc_basename(const char *name);
+PUB_FUNC char *tcc_fileextension (const char *name);
+PUB_FUNC void tcc_free(void *ptr);
+PUB_FUNC void *tcc_malloc(unsigned long size);
+PUB_FUNC void *tcc_mallocz(unsigned long size);
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
+PUB_FUNC char *tcc_strdup(const char *str);
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+#undef strdup
+#define strdup(s) use_tcc_strdup(s)
+PUB_FUNC void tcc_memstats(void);
+PUB_FUNC void dynarray_add(void ***ptab, int *nb_ptr, void *data);
+PUB_FUNC void dynarray_reset(void *pp, int *n);
+PUB_FUNC void error_noabort(const char *fmt, ...);
+PUB_FUNC void error(const char *fmt, ...);
+PUB_FUNC void expect(const char *msg);
+PUB_FUNC void warning(const char *fmt, ...);
+
+/* other utilities */
+ST_INLN void cstr_ccat(CString *cstr, int ch);
+ST_FUNC void cstr_cat(CString *cstr, const char *str);
+ST_FUNC void cstr_wccat(CString *cstr, int ch);
+ST_FUNC void cstr_new(CString *cstr);
+ST_FUNC void cstr_free(CString *cstr);
+ST_FUNC void add_char(CString *cstr, int c);
+#define cstr_reset(cstr) cstr_free(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 Section *find_section(TCCState *s1, const char *name);
+
+ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, unsigned long 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_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_INLN Sym *struct_find(int v);
+ST_INLN Sym *sym_find(int v);
+ST_FUNC Sym *global_identifier_push(int v, int t, int c);
+
+ST_FUNC BufferedFile *tcc_open(TCCState *s1, const char *filename);
+ST_FUNC void tcc_close(BufferedFile *bf);
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
+PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value);
+PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time);
+PUB_FUNC void set_num_callers(int n);
+
+ST_FUNC int ieee_finite(double d);
+
+/* ------------ tccpp.c ------------ */
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA int *macro_ptr;
+ST_DATA int parse_flags;
+ST_DATA int tok_flags;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+#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 */
+
+#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_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_INLN void tok_str_new(TokenString *s);
+ST_FUNC void tok_str_free(int *str);
+ST_FUNC void tok_str_add(TokenString *s, int t);
+ST_FUNC void tok_str_add_tok(TokenString *s);
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
+ST_FUNC void define_undef(Sym *s);
+ST_INLN Sym *define_find(int v);
+ST_FUNC void free_defines(Sym *b);
+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 parse_define(void);
+ST_FUNC void preprocess(int is_bof);
+ST_FUNC void next_nomacro(void);
+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();
+ST_FUNC int tcc_preprocess(TCCState *s1);
+ST_FUNC void skip(int 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))
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *local_label_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *define_stack;
+ST_DATA CType char_pointer_type, func_old_type, int_type;
+ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
+ST_DATA int rsym, anon_sym, ind, loc;
+
+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 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_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA char *funcname;
+
+ST_INLN int is_float(int t);
+ST_FUNC void test_lvalue(void);
+ST_FUNC void swap(int *p, int *q);
+ST_FUNC void vpushi(int v);
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
+ST_FUNC void vset(CType *type, int r, int v);
+ST_FUNC void vswap(void);
+ST_FUNC void save_reg(int r);
+ST_FUNC int get_reg(int rc);
+ST_FUNC void save_regs(int n);
+ST_FUNC int gv(int rc);
+ST_FUNC void gv2(int rc1, int rc2);
+ST_FUNC void vpop(void);
+ST_FUNC void gen_op(int op);
+ST_FUNC int type_size(CType *type, int *a);
+ST_FUNC void mk_pointer(CType *type);
+ST_FUNC void vstore(void);
+ST_FUNC void inc(int post, int c);
+ST_FUNC int lvalue_type(int t);
+ST_FUNC void indir(void);
+ST_FUNC void unary(void);
+ST_FUNC void expr_prod(void);
+ST_FUNC void expr_sum(void);
+ST_FUNC void gexpr(void);
+ST_FUNC int expr_const(void);
+ST_FUNC void gen_inline_functions(void);
+ST_FUNC void decl(int l);
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
+#endif
+
+/* ------------ tccelf.c ------------ */
+
+#define ARMAG  "!<arch>\012"    /* For COFF and a.out archives */
+
+typedef struct {
+    unsigned int n_strx;         /* index into string table of name */
+    unsigned char n_type;         /* type of symbol */
+    unsigned char n_other;        /* misc info (usually empty) */
+    unsigned short n_desc;        /* description field */
+    unsigned int n_value;        /* value of symbol */
+} Stab_Sym;
+
+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 int put_elf_str(Section *s, const char *sym);
+ST_FUNC int put_elf_sym(Section *s, unsigned long value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int sh_num, 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_stabs(const char *str, int type, int other, int desc, unsigned long value);
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
+ST_FUNC void put_stabn(int type, int other, int desc, int value);
+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 relocate_section(TCCState *s1, Section *s);
+
+ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
+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_get_symbol_err(TCCState *s, const char *name);
+ST_FUNC void tcc_add_bcheck(TCCState *s1);
+
+ST_FUNC void build_got_entries(TCCState *s1);
+ST_FUNC void tcc_add_runtime(TCCState *s1);
+
+#ifndef TCC_TARGET_PE
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
+ST_FUNC int tcc_load_ldscript(TCCState *s1);
+ST_FUNC uint8_t *parse_comment(uint8_t *p);
+ST_FUNC void minp(void);
+ST_INLN void inp(void);
+ST_FUNC int handle_eob(void);
+#endif
+
+/* ------------ xxx-gen.c ------------ */
+
+ST_FUNC void gsym_addr(int t, int a);
+ST_FUNC void gsym(int t);
+ST_FUNC void load(int r, SValue *sv);
+ST_FUNC void store(int r, SValue *v);
+ST_FUNC void gfunc_call(int nb_args);
+ST_FUNC void gfunc_prolog(CType *func_type);
+ST_FUNC void gfunc_epilog(void);
+ST_FUNC int gjmp(int t);
+ST_FUNC void gjmp_addr(int a);
+ST_FUNC int gtst(int inv, int t);
+ST_FUNC void gen_opi(int op);
+ST_FUNC void gen_opf(int op);
+ST_FUNC void gen_cvt_ftoi(int t);
+ST_FUNC void gen_cvt_ftof(int t);
+ST_FUNC void ggoto(void);
+#ifndef TCC_TARGET_C67
+ST_FUNC void o(unsigned int c);
+#endif
+#ifndef TCC_TARGET_ARM
+ST_FUNC void gen_cvt_itof(int t);
+#endif
+
+/* ------------ 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);
+ST_FUNC void gen_addr32(int r, Sym *sym, int c);
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void gen_bounded_ptr_add(void);
+ST_FUNC void gen_bounded_ptr_deref(void);
+#endif
+
+/* ------------ x86_64-gen.c ------------ */
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
+#endif
+
+/* ------------ arm-gen.c ------------ */
+#ifdef TCC_TARGET_ARM
+ST_FUNC unsigned long encbranch(int pos,int addr,int fail);
+ST_FUNC void gen_cvt_itof1(int t);
+#endif
+
+/* ------------ c67-gen.c ------------ */
+#ifdef TCC_TARGET_C67
+#endif
+
+/* ------------ tcccoff.c ------------ */
+
+#ifdef TCC_TARGET_COFF
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
+#endif
+
+/* ------------ tccasm.c ------------ */
+ST_FUNC void asm_instr(void);
+ST_FUNC void asm_global_instr(void);
+
+#ifdef CONFIG_TCC_ASM
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC int asm_int_expr(TCCState *s1);
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
+/* ------------ i386-asm.c ------------ */
+ST_FUNC void gen_expr32(ExprValue *pe);
+ST_FUNC void asm_opcode(TCCState *s1, int opcode);
+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);
+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_clobber(uint8_t *clobber_regs, const char *str);
+#endif
+/* ------------ tccpe.c -------------- */
+#ifdef TCC_TARGET_PE
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
+ST_FUNC int pe_add_dll(struct TCCState *s, const char *libraryname);
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
+ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv));
+/* tiny_impdef.c */
+ST_FUNC char *get_export_names(FILE *fp);
+#endif
+
+/* ------------ tccrun.c ----------------- */
+#if !defined CONFIG_TCC_STATIC && !defined _WIN32
+ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
+#endif
+
+/********************************************************/
+/* include the target specific definitions */
+
+#define TARGET_DEFS_ONLY
+#ifdef TCC_TARGET_I386
+#include "i386-gen.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+#include "x86_64-gen.c"
+#endif
+#ifdef TCC_TARGET_ARM
+#include "arm-gen.c"
+#endif
+#ifdef TCC_TARGET_C67
+#include "c67-gen.c"
+#endif
+#undef TARGET_DEFS_ONLY
+
+ST_DATA const int reg_classes[NB_REGS];
+
+/********************************************************/
+#undef ST_DATA
+#ifndef NOTALLINONE
+#define ST_DATA static
+#else
+#define ST_DATA
+#endif
+/********************************************************/
+#endif /* _TCC_H */
diff --git a/tccasm.c b/tccasm.c
index 56bf6cd0..28161bed 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -18,7 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-static int asm_get_local_label_name(TCCState *s1, unsigned int n)
+#include "tcc.h"
+
+ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
 {
     char buf[64];
     TokenSym *ts;
@@ -28,7 +30,7 @@ static int asm_get_local_label_name(TCCState *s1, unsigned int n)
     return ts->tok;
 }
 
-static void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
 
 /* We do not use the C expression parser to handle symbols. Maybe the
    C expression parser could be tweaked to do so. */
@@ -238,12 +240,12 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
     }
 }
 
-static void asm_expr(TCCState *s1, ExprValue *pe)
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
 {
     asm_expr_sum(s1, pe);
 }
 
-static int asm_int_expr(TCCState *s1)
+ST_FUNC int asm_int_expr(TCCState *s1)
 {
     ExprValue e;
     asm_expr(s1, &e);
@@ -699,7 +701,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
 }
 
 /* Assemble the current file */
-static int tcc_assemble(TCCState *s1, int do_preprocess)
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
 {
     Sym *define_start;
     int ret;
@@ -765,7 +767,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
 /* find a constraint by its number or id (gcc 3 extended
    syntax). return -1 if not found. Return in *pp in char after the
    constraint */
-static int find_constraint(ASMOperand *operands, int nb_operands, 
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, 
                            const char *name, const char **pp)
 {
     int index;
@@ -916,7 +918,7 @@ static void parse_asm_str(CString *astr)
 }
 
 /* parse the GCC asm() instruction */
-static void asm_instr(void)
+ST_FUNC void asm_instr(void)
 {
     CString astr, astr1;
     ASMOperand operands[MAX_ASM_OPERANDS];
@@ -1017,7 +1019,7 @@ static void asm_instr(void)
     cstr_free(&astr1);
 }
 
-static void asm_global_instr(void)
+ST_FUNC void asm_global_instr(void)
 {
     CString astr;
 
diff --git a/tcccoff.c b/tcccoff.c
index 0dcbe50f..0ab9acef 100644
--- a/tcccoff.c
+++ b/tcccoff.c
@@ -18,6 +18,8 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
+#include "tcc.h"
 #include "coff.h"
 
 #define MAXNSCNS 255		/* MAXIMUM NUMBER OF SECTIONS         */
@@ -73,7 +75,7 @@ typedef struct {
     unsigned short dummy4;
 } AUXEF;
 
-int tcc_output_coff(TCCState *s1, FILE *f)
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
 {
     Section *tcc_sect;
     SCNHDR *coff_sec;
diff --git a/tccelf.c b/tccelf.c
index 1b4a804c..25d80d7c 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "tcc.h"
+
 #ifdef TCC_TARGET_X86_64
 #define ElfW_Rel ElfW(Rela)
 #define SHT_RELX SHT_RELA
@@ -33,7 +35,7 @@
 /* XXX: DLL with PLT would only work with x86-64 for now */
 //#define TCC_OUTPUT_DLL_WITH_PLT
 
-static int put_elf_str(Section *s, const char *sym)
+ST_FUNC int put_elf_str(Section *s, const char *sym)
 {
     int offset, len;
     char *ptr;
@@ -95,7 +97,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets)
 }
 
 /* return the symbol number */
-static int put_elf_sym(Section *s, 
+ST_FUNC int put_elf_sym(Section *s, 
                        unsigned long value, unsigned long size,
                        int info, int other, int shndx, const char *name)
 {
@@ -145,7 +147,7 @@ static int put_elf_sym(Section *s,
 
 /* find global ELF symbol 'name' and return its index. Return 0 if not
    found. */
-static int find_elf_sym(Section *s, const char *name)
+ST_FUNC int find_elf_sym(Section *s, const char *name)
 {
     ElfW(Sym) *sym;
     Section *hs;
@@ -185,20 +187,20 @@ static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
 }
 
 /* return elf symbol value */
-void *tcc_get_symbol(TCCState *s, const char *name)
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
 {
     return get_elf_sym_addr(s, name, 0);
 }
 
 /* return elf symbol value or error */
-void *tcc_get_symbol_err(TCCState *s, const char *name)
+ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name)
 {
     return get_elf_sym_addr(s, name, 1);
 }
 
 /* add an elf symbol : check if it is already defined and patch
    it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
-static int add_elf_sym(Section *s, uplong value, unsigned long size,
+ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size,
                        int info, int other, int sh_num, const char *name)
 {
     ElfW(Sym) *esym;
@@ -272,7 +274,7 @@ static int add_elf_sym(Section *s, uplong value, unsigned long size,
 }
 
 /* put relocation */
-static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
                           int type, int symbol)
 {
     char buf[256];
@@ -301,15 +303,7 @@ static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
 
 /* put stab debug information */
 
-typedef struct {
-    unsigned int n_strx;         /* index into string table of name */
-    unsigned char n_type;         /* type of symbol */
-    unsigned char n_other;        /* misc info (usually empty) */
-    unsigned short n_desc;        /* description field */
-    unsigned int n_value;        /* value of symbol */
-} Stab_Sym;
-
-static void put_stabs(const char *str, int type, int other, int desc, 
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
                       unsigned long value)
 {
     Stab_Sym *sym;
@@ -326,7 +320,7 @@ static void put_stabs(const char *str, int type, int other, int desc,
     sym->n_value = value;
 }
 
-static 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);
@@ -335,12 +329,12 @@ static void put_stabs_r(const char *str, int type, int other, int desc,
                   R_DATA_32, sym_index);
 }
 
-static void put_stabn(int type, int other, int desc, int value)
+ST_FUNC void put_stabn(int type, int other, int desc, int value)
 {
     put_stabs(NULL, type, other, desc, value);
 }
 
-static void put_stabd(int type, int other, int desc)
+ST_FUNC void put_stabd(int type, int other, int desc)
 {
     put_stabs(NULL, type, other, desc, 0);
 }
@@ -410,7 +404,7 @@ static void sort_syms(TCCState *s1, Section *s)
 }
 
 /* relocate common symbols in the .bss section */
-static void relocate_common_syms(void)
+ST_FUNC void relocate_common_syms(void)
 {
     ElfW(Sym) *sym, *sym_end;
     unsigned long offset, align;
@@ -434,7 +428,7 @@ static void relocate_common_syms(void)
 
 /* relocate symbol table, resolve undefined symbols if do_resolve is
    true and output error if undefined symbol. */
-static void relocate_syms(TCCState *s1, int do_resolve)
+ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
 {
     ElfW(Sym) *sym, *esym, *sym_end;
     int sym_bind, sh_num, sym_index;
@@ -513,7 +507,7 @@ static unsigned long add_got_table(TCCState *s1, unsigned long val)
 #endif
 
 /* relocate a given section (CPU dependent) */
-static void relocate_section(TCCState *s1, Section *s)
+ST_FUNC void relocate_section(TCCState *s1, Section *s)
 {
     Section *sr;
     ElfW_Rel *rel, *rel_end, *qrel;
@@ -1012,7 +1006,7 @@ static void put_got_entry(TCCState *s1,
 }
 
 /* build GOT and PLT entries */
-static void build_got_entries(TCCState *s1)
+ST_FUNC void build_got_entries(TCCState *s1)
 {
     Section *s, *symtab;
     ElfW_Rel *rel, *rel_end;
@@ -1120,7 +1114,7 @@ static void build_got_entries(TCCState *s1)
     }
 }
 
-static Section *new_symtab(TCCState *s1,
+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)
@@ -1186,7 +1180,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
                 s->sh_num, sym_end);
 }
 
-static void tcc_add_bcheck(TCCState *s1)
+ST_FUNC void tcc_add_bcheck(TCCState *s1)
 {
 #ifdef CONFIG_TCC_BCHECK
     unsigned long *ptr;
@@ -1227,7 +1221,7 @@ static void tcc_add_bcheck(TCCState *s1)
 }
 
 /* add tcc runtime libraries */
-static void tcc_add_runtime(TCCState *s1)
+ST_FUNC void tcc_add_runtime(TCCState *s1)
 {
     tcc_add_bcheck(s1);
 
@@ -1252,7 +1246,7 @@ static void tcc_add_runtime(TCCState *s1)
 /* add various standard linker symbols (must be done after the
    sections are filled (for example after allocating common
    symbols)) */
-static void tcc_add_linker_symbols(TCCState *s1)
+ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
 {
     char buf[1024];
     int i;
@@ -1371,7 +1365,7 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
 
 /* output an ELF file */
 /* XXX: suppress unneeded sections */
-int elf_output_file(TCCState *s1, const char *filename)
+static int elf_output_file(TCCState *s1, const char *filename)
 {
     ElfW(Ehdr) ehdr;
     FILE *f;
@@ -2110,7 +2104,7 @@ int elf_output_file(TCCState *s1, const char *filename)
     return ret;
 }
 
-int tcc_output_file(TCCState *s, const char *filename)
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
 {
     int ret;
 #ifdef TCC_TARGET_PE
@@ -2143,7 +2137,7 @@ typedef struct SectionMergeInfo {
 
 /* load an object file and merge it with current files */
 /* XXX: handle correctly stab (debug) info */
-static 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;
@@ -2412,8 +2406,6 @@ static int tcc_load_object_file(TCCState *s1,
     return ret;
 }
 
-#define ARMAG  "!<arch>\012"    /* For COFF and a.out archives */
-
 typedef struct ArchiveHeader {
     char ar_name[16];           /* name of this member */
     char ar_date[12];           /* file mtime */
@@ -2474,7 +2466,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
 }
 
 /* load a '.a' file */
-static int tcc_load_archive(TCCState *s1, int fd)
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
 {
     ArchiveHeader hdr;
     char ar_size[11];
@@ -2529,7 +2521,7 @@ static int tcc_load_archive(TCCState *s1, int fd)
 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
    is referenced by the user (so it should be added as DT_NEEDED in
    the generated ELF file) */
-static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
 { 
     ElfW(Ehdr) ehdr;
     ElfW(Shdr) *shdr, *sh, *sh1;
@@ -2802,7 +2794,7 @@ static int ld_add_file_list(TCCState *s1, int as_needed)
 
 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
    files */
-static int tcc_load_ldscript(TCCState *s1)
+ST_FUNC int tcc_load_ldscript(TCCState *s1)
 {
     char cmd[64];
     char filename[1024];
diff --git a/tccgen.c b/tccgen.c
index 9866c55e..af1abc11 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -18,7 +18,244 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-void swap(int *p, int *q)
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* loc : local variable index
+   ind : output code index
+   rsym: return symbol
+   anon_sym: anonymous symbol index
+*/
+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;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *define_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *local_label_stack;
+
+ST_DATA SValue vstack[VSTACK_SIZE], *vtop;
+
+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 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_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;
+
+/* ------------------------------------------------------------------------- */
+static void gen_cast(CType *type);
+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 void parse_expr_type(CType *type);
+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, int scope);
+static void expr_eq(void);
+static void unary_type(CType *type);
+static int is_compatible_parameter_types(CType *type1, CType *type2);
+static void expr_type(CType *type);
+
+ST_INLN int is_float(int t)
+{
+    int bt;
+    bt = t & VT_BTYPE;
+    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+ST_FUNC void test_lvalue(void)
+{
+    if (!(vtop->r & VT_LVAL))
+        expect("lvalue");
+}
+
+/* ------------------------------------------------------------------------- */
+/* symbol allocator */
+static Sym *__sym_malloc(void)
+{
+    Sym *sym_pool, *sym, *last_sym;
+    int i;
+
+    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
+    dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
+
+    last_sym = sym_free_first;
+    sym = sym_pool;
+    for(i = 0; i < SYM_POOL_NB; i++) {
+        sym->next = last_sym;
+        last_sym = sym;
+        sym++;
+    }
+    sym_free_first = last_sym;
+    return last_sym;
+}
+
+static inline Sym *sym_malloc(void)
+{
+    Sym *sym;
+    sym = sym_free_first;
+    if (!sym)
+        sym = __sym_malloc();
+    sym_free_first = sym->next;
+    return sym;
+}
+
+ST_INLN void sym_free(Sym *sym)
+{
+    sym->next = sym_free_first;
+    sym_free_first = sym;
+}
+
+/* push, without hashing */
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
+{
+    Sym *s;
+    s = sym_malloc();
+    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;
+    *ps = s;
+    return s;
+}
+
+/* find a symbol and return its associated structure. 's' is the top
+   of the symbol stack */
+ST_FUNC Sym *sym_find2(Sym *s, int v)
+{
+    while (s) {
+        if (s->v == v)
+            return s;
+        s = s->prev;
+    }
+    return NULL;
+}
+
+/* structure lookup */
+ST_INLN Sym *struct_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_struct;
+}
+
+/* find an identifier */
+ST_INLN Sym *sym_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_identifier;
+}
+
+/* push a given symbol on the symbol stack */
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
+{
+    Sym *s, **ps;
+    TokenSym *ts;
+
+    if (local_stack)
+        ps = &local_stack;
+    else
+        ps = &global_stack;
+    s = sym_push2(ps, v, type->t, c);
+    s->type.ref = type->ref;
+    s->r = r;
+    /* don't record fields or anonymous symbols */
+    /* XXX: simplify */
+    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+        /* record symbol in token array */
+        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+        if (v & SYM_STRUCT)
+            ps = &ts->sym_struct;
+        else
+            ps = &ts->sym_identifier;
+        s->prev_tok = *ps;
+        *ps = s;
+    }
+    return s;
+}
+
+/* push a global identifier */
+ST_FUNC Sym *global_identifier_push(int v, int t, int c)
+{
+    Sym *s, **ps;
+    s = sym_push2(&global_stack, v, t, c);
+    /* don't record anonymous symbol */
+    if (v < SYM_FIRST_ANOM) {
+        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
+        /* modify the top most local identifier, so that
+           sym_identifier will point to 's' when popped */
+        while (*ps != NULL)
+            ps = &(*ps)->prev_tok;
+        s->prev_tok = NULL;
+        *ps = s;
+    }
+    return s;
+}
+
+/* pop symbols until top reaches 'b' */
+ST_FUNC void sym_pop(Sym **ptop, Sym *b)
+{
+    Sym *s, *ss, **ps;
+    TokenSym *ts;
+    int v;
+
+    s = *ptop;
+    while(s != b) {
+        ss = s->prev;
+        v = s->v;
+        /* remove symbol in token array */
+        /* XXX: simplify */
+        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+            if (v & SYM_STRUCT)
+                ps = &ts->sym_struct;
+            else
+                ps = &ts->sym_identifier;
+            *ps = s->prev_tok;
+        }
+        sym_free(s);
+        s = ss;
+    }
+    *ptop = b;
+}
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC void swap(int *p, int *q)
 {
     int t;
     t = *p;
@@ -26,7 +263,7 @@ void swap(int *p, int *q)
     *q = t;
 }
 
-void vsetc(CType *type, int r, CValue *vc)
+static void vsetc(CType *type, int r, CValue *vc)
 {
     int v;
 
@@ -48,7 +285,7 @@ void vsetc(CType *type, int r, CValue *vc)
 }
 
 /* push integer constant */
-void vpushi(int v)
+ST_FUNC void vpushi(int v)
 {
     CValue cval;
     cval.i = v;
@@ -56,7 +293,7 @@ void vpushi(int v)
 }
 
 /* push long long constant */
-void vpushll(long long v)
+static void vpushll(long long v)
 {
     CValue cval;
     CType ctype;
@@ -67,8 +304,7 @@ void vpushll(long long v)
 }
 
 /* Return a static symbol pointing to a section */
-static Sym *get_sym_ref(CType *type, Section *sec, 
-                        unsigned long offset, unsigned long size)
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
 {
     int v;
     Sym *sym;
@@ -92,7 +328,7 @@ static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned
 }
 
 /* define a new external reference to a symbol 'v' of type 'u' */
-static Sym *external_global_sym(int v, CType *type, int r)
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
 {
     Sym *s;
 
@@ -139,7 +375,7 @@ static void vpush_global_sym(CType *type, int v)
     vtop->sym = sym;
 }
 
-void vset(CType *type, int r, int v)
+ST_FUNC void vset(CType *type, int r, int v)
 {
     CValue cval;
 
@@ -147,7 +383,7 @@ void vset(CType *type, int r, int v)
     vsetc(type, r, &cval);
 }
 
-void vseti(int r, int v)
+static void vseti(int r, int v)
 {
     CType type;
     type.t = VT_INT;
@@ -155,7 +391,7 @@ void vseti(int r, int v)
     vset(&type, r, v);
 }
 
-void vswap(void)
+ST_FUNC void vswap(void)
 {
     SValue tmp;
 
@@ -164,7 +400,7 @@ void vswap(void)
     vtop[-1] = tmp;
 }
 
-void vpushv(SValue *v)
+static void vpushv(SValue *v)
 {
     if (vtop >= vstack + (VSTACK_SIZE - 1))
         error("memory full");
@@ -172,13 +408,13 @@ void vpushv(SValue *v)
     *vtop = *v;
 }
 
-void vdup(void)
+static void vdup(void)
 {
     vpushv(vtop);
 }
 
 /* save r to the memory stack, and mark it as being free */
-void save_reg(int r)
+ST_FUNC void save_reg(int r)
 {
     int l, saved, size, align;
     SValue *p, sv;
@@ -240,9 +476,10 @@ void save_reg(int r)
     }
 }
 
+#ifdef TCC_TARGET_ARM
 /* find a register of class 'rc2' with at most one reference on stack.
  * If none, call get_reg(rc) */
-int get_reg_ex(int rc, int rc2) 
+ST_FUNC int get_reg_ex(int rc, int rc2)
 {
     int r;
     SValue *p;
@@ -262,9 +499,10 @@ int get_reg_ex(int rc, int rc2)
     }
     return get_reg(rc);
 }
+#endif
 
 /* find a free register of class 'rc'. If none, save one register */
-int get_reg(int rc)
+ST_FUNC int get_reg(int rc)
 {
     int r;
     SValue *p;
@@ -302,7 +540,7 @@ int get_reg(int rc)
 }
 
 /* save registers up to (vtop - n) stack entry */
-void save_regs(int n)
+ST_FUNC void save_regs(int n)
 {
     int r;
     SValue *p, *p1;
@@ -317,7 +555,7 @@ void save_regs(int n)
 
 /* move register 's' to 'r', and flush previous value of r to memory
    if needed */
-void move_reg(int r, int s)
+static void move_reg(int r, int s)
 {
     SValue sv;
 
@@ -331,7 +569,7 @@ void move_reg(int r, int s)
 }
 
 /* get address of vtop (vtop MUST BE an lvalue) */
-void gaddrof(void)
+static void gaddrof(void)
 {
     vtop->r &= ~VT_LVAL;
     /* tricky: if saved lvalue, then we can go back to lvalue */
@@ -341,7 +579,7 @@ void gaddrof(void)
 
 #ifdef CONFIG_TCC_BCHECK
 /* generate lvalue bound code */
-void gbound(void)
+static void gbound(void)
 {
     int lval_type;
     CType type1;
@@ -370,7 +608,7 @@ void gbound(void)
 /* store vtop a register belonging to class 'rc'. lvalues are
    converted to values. Cannot be used if cannot be converted to
    register value (such as structures). */
-int gv(int rc)
+ST_FUNC int gv(int rc)
 {
     int r, rc2, bit_pos, bit_size, size, align, i;
 
@@ -537,7 +775,7 @@ int gv(int rc)
 }
 
 /* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
-void gv2(int rc1, int rc2)
+ST_FUNC void gv2(int rc1, int rc2)
 {
     int v;
 
@@ -569,7 +807,7 @@ void gv2(int rc1, int rc2)
 }
 
 /* wrapper around RC_FRET to return a register by type */
-int rc_fret(int t)
+static int rc_fret(int t)
 {
 #ifdef TCC_TARGET_X86_64
     if (t == VT_LDOUBLE) {
@@ -580,7 +818,7 @@ int rc_fret(int t)
 }
 
 /* wrapper around REG_FRET to return a register by type */
-int reg_fret(int t)
+static int reg_fret(int t)
 {
 #ifdef TCC_TARGET_X86_64
     if (t == VT_LDOUBLE) {
@@ -591,7 +829,7 @@ int reg_fret(int t)
 }
 
 /* expand long long on stack in two int registers */
-void lexpand(void)
+static void lexpand(void)
 {
     int u;
 
@@ -607,7 +845,7 @@ void lexpand(void)
 
 #ifdef TCC_TARGET_ARM
 /* expand long long on stack */
-void lexpand_nr(void)
+ST_FUNC void lexpand_nr(void)
 {
     int u,v;
 
@@ -634,7 +872,7 @@ void lexpand_nr(void)
 #endif
 
 /* build a long long from two ints */
-void lbuild(int t)
+static void lbuild(int t)
 {
     gv2(RC_INT, RC_INT);
     vtop[-1].r2 = vtop[0].r;
@@ -645,7 +883,7 @@ void lbuild(int t)
 /* rotate n first stack elements to the bottom 
    I1 ... In -> I2 ... In I1 [top is right]
 */
-void vrotb(int n)
+static void vrotb(int n)
 {
     int i;
     SValue tmp;
@@ -659,7 +897,7 @@ void vrotb(int n)
 /* rotate n first stack elements to the top 
    I1 ... In -> In I1 ... I(n-1)  [top is right]
  */
-void vrott(int n)
+static void vrott(int n)
 {
     int i;
     SValue tmp;
@@ -687,7 +925,7 @@ void vnrott(int n)
 #endif
 
 /* pop stack value */
-void vpop(void)
+ST_FUNC void vpop(void)
 {
     int v;
     v = vtop->r & VT_VALMASK;
@@ -706,7 +944,7 @@ void vpop(void)
 
 /* convert stack entry to register and duplicate its value in another
    register */
-void gv_dup(void)
+static void gv_dup(void)
 {
     int rc, t, r, r1;
     SValue sv;
@@ -753,7 +991,7 @@ void gv_dup(void)
 
 #ifndef TCC_TARGET_X86_64
 /* generate CPU independent (unsigned) long long operations */
-void gen_opl(int op)
+static void gen_opl(int op)
 {
     int t, a, b, op1, c, i;
     int func;
@@ -990,7 +1228,7 @@ void gen_opl(int op)
 
 /* handle integer constant optimizations and various machine
    independent opt */
-void gen_opic(int op)
+static void gen_opic(int op)
 {
     int c1, c2, t1, t2, n;
     SValue *v1, *v2;
@@ -1130,7 +1368,7 @@ void gen_opic(int op)
 }
 
 /* generate a floating point operation with constant propagation */
-void gen_opif(int op)
+static void gen_opif(int op)
 {
     int c1, c2;
     SValue *v1, *v2;
@@ -1262,7 +1500,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
 }
 
 /* generic gen_op: handles types problems */
-void gen_op(int op)
+ST_FUNC void gen_op(int op)
 {
     int u, t1, t2, bt1, bt2, t;
     CType type1;
@@ -1411,7 +1649,7 @@ void gen_op(int op)
 
 #ifndef TCC_TARGET_ARM
 /* generic itof for unsigned long long case */
-void gen_cvt_itof1(int t)
+static void gen_cvt_itof1(int t)
 {
     if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
         (VT_LLONG | VT_UNSIGNED)) {
@@ -1435,7 +1673,7 @@ void gen_cvt_itof1(int t)
 #endif
 
 /* generic ftoi for unsigned long long case */
-void gen_cvt_ftoi1(int t)
+static void gen_cvt_ftoi1(int t)
 {
     int st;
 
@@ -1461,7 +1699,7 @@ void gen_cvt_ftoi1(int t)
 }
 
 /* force char or short cast */
-void force_charshort_cast(int t)
+static void force_charshort_cast(int t)
 {
     int bits, dbt;
     dbt = t & VT_BTYPE;
@@ -1672,7 +1910,7 @@ static void gen_cast(CType *type)
 }
 
 /* return type size. Put alignment at 'a' */
-static int type_size(CType *type, int *a)
+ST_FUNC int type_size(CType *type, int *a)
 {
     Sym *s;
     int bt;
@@ -1738,7 +1976,7 @@ static inline CType *pointed_type(CType *type)
 }
 
 /* modify type so that its it is a pointer to type. */
-static void mk_pointer(CType *type)
+ST_FUNC void mk_pointer(CType *type)
 {
     Sym *s;
     s = sym_push(SYM_FIELD, type, 0, -1);
@@ -1829,7 +2067,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2)
    printed in the type */
 /* XXX: union */
 /* XXX: add array and function pointers */
-void type_to_str(char *buf, int buf_size, 
+static void type_to_str(char *buf, int buf_size, 
                  CType *type, const char *varstr)
 {
     int bt, v, t;
@@ -2000,7 +2238,7 @@ static void gen_assign_cast(CType *dt)
 }
 
 /* store vtop in lvalue pushed on stack */
-void vstore(void)
+ST_FUNC void vstore(void)
 {
     int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
 
@@ -2161,7 +2399,7 @@ void vstore(void)
 }
 
 /* post defines POST/PRE add. c is the token ++ or -- */
-void inc(int post, int c)
+ST_FUNC void inc(int post, int c)
 {
     test_lvalue();
     vdup(); /* save lvalue */
@@ -2879,7 +3117,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
 }
 
 /* compute the lvalue VT_LVAL_xxx needed to match type t. */
-static int lvalue_type(int t)
+ST_FUNC int lvalue_type(int t)
 {
     int bt, r;
     r = VT_LVAL;
@@ -2896,7 +3134,7 @@ static int lvalue_type(int t)
 }
 
 /* indirection with full error checking and bound check */
-static void indir(void)
+ST_FUNC void indir(void)
 {
     if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
         if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
@@ -2976,7 +3214,7 @@ static void vpush_tokc(int t)
     vsetc(&type, VT_CONST, &tokc);
 }
 
-static void unary(void)
+ST_FUNC void unary(void)
 {
     int n, t, align, size, r;
     CType type;
@@ -3444,7 +3682,7 @@ static void uneq(void)
     }
 }
 
-static void expr_prod(void)
+ST_FUNC void expr_prod(void)
 {
     int t;
 
@@ -3457,7 +3695,7 @@ static void expr_prod(void)
     }
 }
 
-static void expr_sum(void)
+ST_FUNC void expr_sum(void)
 {
     int t;
 
@@ -3745,7 +3983,7 @@ static void expr_eq(void)
     }
 }
 
-static void gexpr(void)
+ST_FUNC void gexpr(void)
 {
     while (1) {
         expr_eq();
@@ -3794,7 +4032,7 @@ static void expr_const1(void)
 }
 
 /* parse an integer constant and return its value. */
-static int expr_const(void)
+ST_FUNC int expr_const(void)
 {
     int c;
     expr_const1();
@@ -4848,7 +5086,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
  no_alloc: ;
 }
 
-void put_func_debug(Sym *sym)
+static void put_func_debug(Sym *sym)
 {
     char buf[512];
 
@@ -4951,7 +5189,7 @@ static void gen_function(Sym *sym)
     nocode_wanted = saved_nocode_wanted;
 }
 
-static void gen_inline_functions(void)
+ST_FUNC void gen_inline_functions(void)
 {
     Sym *sym;
     int *str, inline_generated, i;
@@ -4994,7 +5232,7 @@ static void gen_inline_functions(void)
 }
 
 /* 'l' is VT_LOCAL or VT_CONST to define default storage type */
-static void decl(int l)
+ST_FUNC void decl(int l)
 {
     int v, has_init, r;
     CType type, btype;
diff --git a/tccpe.c b/tccpe.c
index d603a5e7..1b2724d6 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -18,11 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef TCC_TARGET_PE
-
-#define ST_FN static
-#define ST_DATA static
-#define PUB_FN
+#include "tcc.h"
 
 #ifndef _WIN32
 #define stricmp strcasecmp
@@ -300,7 +296,7 @@ enum {
     sec_last
 };
 
-ST_DATA const DWORD pe_sec_flags[] = {
+static const DWORD pe_sec_flags[] = {
     0x60000020, /* ".text"     , */
     0xC0000040, /* ".data"     , */
     0xC0000080, /* ".bss"      , */
@@ -366,7 +362,7 @@ struct pe_info {
 
 /* --------------------------------------------*/
 
-ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
+static const char* get_alt_symbol(char *buffer, const char *symbol)
 {
     const char *p;
     p = strrchr(symbol, '@');
@@ -384,7 +380,7 @@ ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
     return buffer;
 }
 
-ST_FN int pe_find_import(TCCState * s1, const char *symbol)
+static int pe_find_import(TCCState * s1, const char *symbol)
 {
     char buffer[200];
     const char *s;
@@ -399,7 +395,7 @@ ST_FN int pe_find_import(TCCState * s1, const char *symbol)
 
 /*----------------------------------------------------------------------------*/
 
-ST_FN int dynarray_assoc(void **pp, int n, int key)
+static int dynarray_assoc(void **pp, int n, int key)
 {
     int i;
     for (i = 0; i < n; ++i, ++pp)
@@ -415,35 +411,35 @@ ST_FN DWORD umin(DWORD a, DWORD b)
 }
 #endif
 
-ST_FN DWORD umax(DWORD a, DWORD b)
+static DWORD umax(DWORD a, DWORD b)
 {
     return a < b ? b : a;
 }
 
-ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n)
+static DWORD pe_file_align(struct pe_info *pe, DWORD n)
 {
     return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
 }
 
-ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
+static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
 {
     return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
 }
 
-ST_FN void pe_align_section(Section *s, int a)
+static void pe_align_section(Section *s, int a)
 {
     int i = s->data_offset & (a-1);
     if (i)
         section_ptr_add(s, a - i);
 }
 
-ST_FN void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
+static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
 {
     hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
     hdr->opthdr.DataDirectory[dir].Size = size;
 }
 
-ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
+static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
 {
     if (psum) {
         DWORD sum = *psum;
@@ -458,7 +454,7 @@ ST_FN int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
     return len == fwrite(data, 1, len, fp) ? 0 : -1;
 }
 
-ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
+static void pe_fpad(FILE *fp, DWORD new_pos)
 {
     DWORD pos = ftell(fp);
     while (++pos <= new_pos)
@@ -466,7 +462,7 @@ ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
 }
 
 /*----------------------------------------------------------------------------*/
-ST_FN int pe_write(struct pe_info *pe)
+static int pe_write(struct pe_info *pe)
 {
     static const struct pe_header pe_template = {
     {
@@ -745,7 +741,7 @@ ST_FN int pe_write(struct pe_info *pe)
 #endif
 /*----------------------------------------------------------------------------*/
 
-ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
+static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
 {
     int i;
     int dll_index;
@@ -777,7 +773,7 @@ found_dll:
 }
 
 /*----------------------------------------------------------------------------*/
-ST_FN void pe_build_imports(struct pe_info *pe)
+static void pe_build_imports(struct pe_info *pe)
 {
     int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
     DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
@@ -860,14 +856,14 @@ struct pe_sort_sym
     const char *name;
 };
 
-ST_FN int sym_cmp(const void *va, const void *vb)
+static int sym_cmp(const void *va, const void *vb)
 {
     const char *ca = (*(struct pe_sort_sym**)va)->name;
     const char *cb = (*(struct pe_sort_sym**)vb)->name;
     return strcmp(ca, cb);
 }
 
-ST_FN void pe_build_exports(struct pe_info *pe)
+static void pe_build_exports(struct pe_info *pe)
 {
     ElfW(Sym) *sym;
     int sym_index, sym_end;
@@ -967,7 +963,7 @@ ST_FN void pe_build_exports(struct pe_info *pe)
 }
 
 /* ------------------------------------------------------------- */
-ST_FN void pe_build_reloc (struct pe_info *pe)
+static void pe_build_reloc (struct pe_info *pe)
 {
     DWORD offset, block_ptr, addr;
     int count, i;
@@ -1023,7 +1019,7 @@ ST_FN void pe_build_reloc (struct pe_info *pe)
 }
 
 /* ------------------------------------------------------------- */
-ST_FN int pe_section_class(Section *s)
+static int pe_section_class(Section *s)
 {
     int type, flags;
     const char *name;
@@ -1055,7 +1051,7 @@ ST_FN int pe_section_class(Section *s)
     return -1;
 }
 
-ST_FN int pe_assign_addresses (struct pe_info *pe)
+static int pe_assign_addresses (struct pe_info *pe)
 {
     int i, k, o, c;
     DWORD addr;
@@ -1153,7 +1149,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe)
 }
 
 /* ------------------------------------------------------------- */
-ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)
+static void pe_relocate_rva (struct pe_info *pe, Section *s)
 {
     Section *sr = s->reloc;
     ElfW_Rel *rel, *rel_end;
@@ -1173,6 +1169,7 @@ ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)
 }
 
 /*----------------------------------------------------------------------------*/
+
 static int pe_isafunc(int sym_index)
 {
     Section *sr = text_section->reloc;
@@ -1188,7 +1185,7 @@ static int pe_isafunc(int sym_index)
 }
 
 /*----------------------------------------------------------------------------*/
-ST_FN int pe_check_symbols(struct pe_info *pe)
+static int pe_check_symbols(struct pe_info *pe)
 {
     ElfW(Sym) *sym;
     int sym_index, sym_end;
@@ -1282,7 +1279,7 @@ ST_FN int pe_check_symbols(struct pe_info *pe)
 
 /*----------------------------------------------------------------------------*/
 #ifdef PE_PRINT_SECTIONS
-ST_FN void pe_print_section(FILE * f, Section * s)
+static void pe_print_section(FILE * f, Section * s)
 {
     /* just if you'r curious */
     BYTE *p, *e, b;
@@ -1404,7 +1401,7 @@ ST_FN void pe_print_section(FILE * f, Section * s)
     fprintf(f, "\n\n");
 }
 
-ST_FN void pe_print_sections(TCCState *s1, const char *fname)
+static void pe_print_sections(TCCState *s1, const char *fname)
 {
     Section *s;
     FILE *f;
@@ -1420,34 +1417,8 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname)
 #endif
 
 /* ------------------------------------------------------------- */
-/* helper function for load/store to insert one more indirection */
 
-int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
-{
-    int t;
-    if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
-        return 0;
-    t = sv->sym->type.t;
-    if (0 == (t & VT_IMPORT))
-        return 0;
-
-    sv->sym->type.t = t & ~VT_IMPORT;
-    //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
-
-    *++vtop = *sv;
-    vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
-    mk_pointer(&vtop->type);
-    indir();
-    fn(r, vtop);
-    --vtop;
-
-    sv->sym->type.t = t;
-    return 1;
-}
-
-/* ------------------------------------------------------------- */
-
-ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
+static int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
 {
     fseek(fp, offset, 0);
     return len == fread(buffer, 1, len, fp);
@@ -1458,7 +1429,7 @@ ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
  *  as generated by 'windres.exe -O coff ...'.
  */
 
-ST_FN int pe_load_res(TCCState *s1, FILE *fp)
+static int pe_load_res(TCCState *s1, FILE *fp)
 {
     struct pe_rsrc_header hdr;
     Section *rsrc_section;
@@ -1498,14 +1469,14 @@ quit:
 }
 
 /* ------------------------------------------------------------- */
-ST_FN char *trimfront(char *p)
+static char *trimfront(char *p)
 {
     while (*p && (unsigned char)*p <= ' ')
         ++p;
     return p;
 }
 
-ST_FN char *trimback(char *a, char *e)
+static char *trimback(char *a, char *e)
 {
     while (e > a && (unsigned char)e[-1] <= ' ')
         --e;
@@ -1513,7 +1484,7 @@ ST_FN char *trimback(char *a, char *e)
     return a;
 }
 
-ST_FN char *get_line(char *line, int size, FILE *fp)
+static char *get_line(char *line, int size, FILE *fp)
 {
     if (NULL == fgets(line, size, fp))
         return NULL;
@@ -1522,7 +1493,7 @@ ST_FN char *get_line(char *line, int size, FILE *fp)
 }
 
 /* ------------------------------------------------------------- */
-ST_FN int pe_load_def(TCCState *s1, FILE *fp)
+static int pe_load_def(TCCState *s1, FILE *fp)
 {
     DLLReference *dllref;
     int state = 0, ret = -1;
@@ -1571,7 +1542,7 @@ quit:
 #define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
 #include "win32/tools/tiny_impdef.c"
 
-ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
+static int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
 {
     int i = 0;
     char *p, *q;
@@ -1594,7 +1565,7 @@ ST_FN int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
 }
 
 /* ------------------------------------------------------------- */
-PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
 {
     FILE *fp = fdopen(dup(fd), "rb");
     int ret = -1;
@@ -1611,7 +1582,7 @@ PUB_FN int pe_load_file(struct TCCState *s1, const char *filename, int fd)
     return ret;
 }
 
-int pe_add_dll(struct TCCState *s, const char *libname)
+ST_FUNC int pe_add_dll(struct TCCState *s, const char *libname)
 {
     static const char *pat[] = {
         "%s.def", "lib%s.def", "%s.dll", "lib%s.dll", NULL
@@ -1626,6 +1597,32 @@ int pe_add_dll(struct TCCState *s, const char *libname)
     return -1;
 }
 
+/* ------------------------------------------------------------- */
+/* helper function for load/store to insert one more indirection */
+
+ST_FUNC int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv))
+{
+    int t;
+    if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST))
+	return 0;
+    t = sv->sym->type.t;
+    if (0 == (t & VT_IMPORT))
+	return 0;
+
+    sv->sym->type.t = t & ~VT_IMPORT;
+    //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL));
+
+    *++vtop = *sv;
+    vtop->type.t &= ~(VT_ARRAY|VT_IMPORT);
+    mk_pointer(&vtop->type);
+    indir();
+    fn(r, vtop);
+    --vtop;
+
+    sv->sym->type.t = t;
+    return 1;
+}
+
 /* ------------------------------------------------------------- */
 #ifdef TCC_TARGET_X86_64
 #define PE_STDSYM(n,s) n
@@ -1633,7 +1630,7 @@ int pe_add_dll(struct TCCState *s, const char *libname)
 #define PE_STDSYM(n,s) "_" n s
 #endif
 
-ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
+static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
 {
     const char *start_symbol;
     unsigned long addr = 0;
@@ -1690,7 +1687,7 @@ ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
     pe->start_addr = addr;
 }
 
-PUB_FN int pe_output_file(TCCState * s1, const char *filename)
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
 {
     int ret;
     struct pe_info pe;
@@ -1780,5 +1777,3 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename)
 }
 
 /* ------------------------------------------------------------- */
-#endif /* def TCC_TARGET_PE */
-/* ------------------------------------------------------------- */
diff --git a/tccpp.c b/tccpp.c
index ecdaf172..162d0818 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -18,6 +18,49 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+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;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA int *macro_ptr;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+/* ------------------------------------------------------------------------- */
+
+static int *macro_ptr_allocated;
+static 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 const char tcc_keywords[] = 
 #define DEF(id, str) str "\0"
@@ -30,21 +73,115 @@ static const unsigned char tok_two_chars[] =
     "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
     "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
 
-/* true if isid(c) || isnum(c) */
-static unsigned char isidnum_table[256-CH_EOF];
-
-
 struct macro_level {
     struct macro_level *prev;
     int *p;
 };
 
-static void next_nomacro(void);
+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);
+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)
+{
+    if (tok != c)
+        error("'%c' expected", c);
+    next();
+}
 
+/* ------------------------------------------------------------------------- */
+/* CString handling */
+static void cstr_realloc(CString *cstr, int new_size)
+{
+    int size;
+    void *data;
+
+    size = cstr->size_allocated;
+    if (size == 0)
+        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);
+    if (!data)
+        error("memory full");
+    cstr->data_allocated = data;
+    cstr->size_allocated = size;
+    cstr->data = data;
+}
+
+/* add a byte */
+ST_INLN void cstr_ccat(CString *cstr, int ch)
+{
+    int size;
+    size = cstr->size + 1;
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    ((unsigned char *)cstr->data)[size - 1] = ch;
+    cstr->size = size;
+}
+
+ST_FUNC void cstr_cat(CString *cstr, const char *str)
+{
+    int c;
+    for(;;) {
+        c = *str;
+        if (c == '\0')
+            break;
+        cstr_ccat(cstr, c);
+        str++;
+    }
+}
+
+/* add a wide char */
+ST_FUNC void cstr_wccat(CString *cstr, int ch)
+{
+    int size;
+    size = cstr->size + sizeof(nwchar_t);
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
+    cstr->size = size;
+}
+
+ST_FUNC void cstr_new(CString *cstr)
+{
+    memset(cstr, 0, sizeof(CString));
+}
+
+/* free string and reset it to NULL */
+ST_FUNC void cstr_free(CString *cstr)
+{
+    tcc_free(cstr->data_allocated);
+    cstr_new(cstr);
+}
+
+/* XXX: unicode ? */
+ST_FUNC void add_char(CString *cstr, int c)
+{
+    if (c == '\'' || c == '\"' || c == '\\') {
+        /* XXX: could be more precise if char or string */
+        cstr_ccat(cstr, '\\');
+    }
+    if (c >= 32 && c <= 126) {
+        cstr_ccat(cstr, c);
+    } else {
+        cstr_ccat(cstr, '\\');
+        if (c == '\n') {
+            cstr_ccat(cstr, 'n');
+        } else {
+            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
+            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
+            cstr_ccat(cstr, '0' + (c & 7));
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------- */
 /* allocate a new token */
 static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
 {
@@ -82,7 +219,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
 #define TOK_HASH_FUNC(h, c) ((h) * 263 + (c))
 
 /* find a token and add it if not found */
-static TokenSym *tok_alloc(const char *str, int len)
+ST_FUNC TokenSym *tok_alloc(const char *str, int len)
 {
     TokenSym *ts, **pts;
     int i;
@@ -107,7 +244,7 @@ static TokenSym *tok_alloc(const char *str, int len)
 
 /* XXX: buffer overflow */
 /* XXX: float tokens */
-char *get_tok_str(int v, CValue *cv)
+ST_FUNC char *get_tok_str(int v, CValue *cv)
 {
     static char buf[STRING_MAX_SIZE + 1];
     static CString cstr_buf;
@@ -243,13 +380,13 @@ static int tcc_peekc_slow(BufferedFile *bf)
 
 /* return the current character, handling end of block if necessary
    (but not stray) */
-static int handle_eob(void)
+ST_FUNC int handle_eob(void)
 {
     return tcc_peekc_slow(file);
 }
 
 /* read next char from current input file and handle end of input buffer */
-static inline void inp(void)
+ST_INLN void inp(void)
 {
     ch = *(++(file->buf_ptr));
     /* end of buffer/file handling */
@@ -334,7 +471,7 @@ static int handle_stray1(uint8_t *p)
 /* input with '\[\r]\n' handling. Note that this function cannot
    handle other characters after '\', so you cannot call it inside
    strings or comments */
-static void minp(void)
+ST_FUNC void minp(void)
 {
     inp();
     if (ch == '\\') 
@@ -380,7 +517,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
 }
 
 /* C comments */
-static uint8_t *parse_comment(uint8_t *p)
+ST_FUNC uint8_t *parse_comment(uint8_t *p)
 {
     int c;
     
@@ -537,7 +674,7 @@ static uint8_t *parse_pp_string(uint8_t *p,
 
 /* skip block of text until #else, #elif or #endif. skip also pairs of
    #if/#endif */
-void preprocess_skip(void)
+static void preprocess_skip(void)
 {
     int a, start_of_line, c, in_warn_or_error;
     uint8_t *p;
@@ -629,7 +766,7 @@ _default:
    files */
 
 /* save current parse state in 's' */
-void save_parse_state(ParseState *s)
+ST_FUNC void save_parse_state(ParseState *s)
 {
     s->line_num = file->line_num;
     s->macro_ptr = macro_ptr;
@@ -638,7 +775,7 @@ void save_parse_state(ParseState *s)
 }
 
 /* restore parse state from 's' */
-void restore_parse_state(ParseState *s)
+ST_FUNC void restore_parse_state(ParseState *s)
 {
     file->line_num = s->line_num;
     macro_ptr = s->macro_ptr;
@@ -677,7 +814,7 @@ static inline int tok_ext_size(int t)
 
 /* token string handling */
 
-static inline void tok_str_new(TokenString *s)
+ST_INLN void tok_str_new(TokenString *s)
 {
     s->str = NULL;
     s->len = 0;
@@ -685,7 +822,7 @@ static inline void tok_str_new(TokenString *s)
     s->last_line_num = -1;
 }
 
-static void tok_str_free(int *str)
+ST_FUNC void tok_str_free(int *str)
 {
     tcc_free(str);
 }
@@ -707,7 +844,7 @@ static int *tok_str_realloc(TokenString *s)
     return str;
 }
 
-static void tok_str_add(TokenString *s, int t)
+ST_FUNC void tok_str_add(TokenString *s, int t)
 {
     int len, *str;
 
@@ -790,7 +927,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
 }
 
 /* add the current parse token in token string 's' */
-static void tok_str_add_tok(TokenString *s)
+ST_FUNC void tok_str_add_tok(TokenString *s)
 {
     CValue cval;
 
@@ -861,7 +998,7 @@ static void tok_str_add_tok(TokenString *s)
 }
 
 /* defines handling */
-static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
 {
     Sym *s;
 
@@ -872,7 +1009,7 @@ static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
 }
 
 /* undefined a define symbol. Its name is just set to zero */
-static void define_undef(Sym *s)
+ST_FUNC void define_undef(Sym *s)
 {
     int v;
     v = s->v;
@@ -881,7 +1018,7 @@ static void define_undef(Sym *s)
     s->v = 0;
 }
 
-static inline Sym *define_find(int v)
+ST_INLN Sym *define_find(int v)
 {
     v -= TOK_IDENT;
     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -890,7 +1027,7 @@ static inline Sym *define_find(int v)
 }
 
 /* free define stack until top reaches 'b' */
-static void free_defines(Sym *b)
+ST_FUNC void free_defines(Sym *b)
 {
     Sym *top, *top1;
     int v;
@@ -911,7 +1048,7 @@ static void free_defines(Sym *b)
 }
 
 /* label lookup */
-static Sym *label_find(int v)
+ST_FUNC Sym *label_find(int v)
 {
     v -= TOK_IDENT;
     if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
@@ -919,7 +1056,7 @@ static Sym *label_find(int v)
     return table_ident[v]->sym_label;
 }
 
-static Sym *label_push(Sym **ptop, int v, int flags)
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
 {
     Sym *s, **ps;
     s = sym_push2(ptop, v, 0, 0);
@@ -938,7 +1075,7 @@ static Sym *label_push(Sym **ptop, int v, int flags)
 
 /* pop labels until element last is reached. Look if any labels are
    undefined. Define symbols if '&&label' was used. */
-static void label_pop(Sym **ptop, Sym *slast)
+ST_FUNC void label_pop(Sym **ptop, Sym *slast)
 {
     Sym *s, *s1;
     for(s = *ptop; s != slast; s = s1) {
@@ -1017,7 +1154,7 @@ static void tok_print(int *str)
 #endif
 
 /* parse after #define */
-static void parse_define(void)
+ST_FUNC void parse_define(void)
 {
     Sym *s, *first, **ps;
     int v, t, varg, is_vaargs, spc;
@@ -1193,7 +1330,7 @@ static void pragma_parse(TCCState *s1)
 }
 
 /* is_bof is true if first non space token at beginning of file */
-static void preprocess(int is_bof)
+ST_FUNC void preprocess(int is_bof)
 {
     TCCState *s1 = tcc_state;
     int i, c, n, saved_parse_flags;
@@ -1350,7 +1487,7 @@ static void preprocess(int is_bof)
             pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);
             file = f;
             /* add include file debug info */
-            if (tcc_state->do_debug) {
+            if (s1->do_debug) {
                 put_stabs(file->filename, N_BINCL, 0, 0, 0);
             }
             tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
@@ -1598,7 +1735,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
 #define BN_SIZE 2
 
 /* bn = (bn << shift) | or_val */
-void bn_lshift(unsigned int *bn, int shift, int or_val)
+static void bn_lshift(unsigned int *bn, int shift, int or_val)
 {
     int i;
     unsigned int v;
@@ -1609,7 +1746,7 @@ void bn_lshift(unsigned int *bn, int shift, int or_val)
     }
 }
 
-void bn_zero(unsigned int *bn)
+static void bn_zero(unsigned int *bn)
 {
     int i;
     for(i=0;i<BN_SIZE;i++) {
@@ -1619,7 +1756,7 @@ void bn_zero(unsigned int *bn)
 
 /* parse number in null terminated string 'p' and return it in the
    current token */
-void parse_number(const char *p)
+static void parse_number(const char *p)
 {
     int b, t, shift, frac_bits, s, exp_val, ch;
     char *q;
@@ -2353,7 +2490,7 @@ static void next_nomacro_spc(void)
     }
 }
 
-static void next_nomacro(void)
+ST_FUNC void next_nomacro(void)
 {
     do {
         next_nomacro_spc();
@@ -2734,7 +2871,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list,
 }
 
 /* return next token with macro substitution */
-static void next(void)
+ST_FUNC void next(void)
 {
     Sym *nested_list, *s;
     TokenString str;
@@ -2790,7 +2927,7 @@ static void next(void)
 
 /* push back current token and set current token to 'last_tok'. Only
    identifier case handled for labels. */
-static inline void unget_tok(int last_tok)
+ST_INLN void unget_tok(int last_tok)
 {
     int i, n;
     int *q;
@@ -2809,7 +2946,7 @@ static inline void unget_tok(int last_tok)
 
 /* better than nothing, but needs extension to handle '-E' option
    correctly too */
-static void preprocess_init(TCCState *s1)
+ST_FUNC void preprocess_init(TCCState *s1)
 {
     s1->include_stack_ptr = s1->include_stack;
     /* XXX: move that before to avoid having to initialize
@@ -2823,7 +2960,7 @@ static void preprocess_init(TCCState *s1)
     s1->pack_stack_ptr = s1->pack_stack;
 }
 
-void preprocess_new()
+ST_FUNC void preprocess_new()
 {
     int i, c;
     const char *p, *r;
@@ -2852,9 +2989,10 @@ void preprocess_new()
 }
 
 /* Preprocess the current file */
-static int tcc_preprocess(TCCState *s1)
+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;
@@ -2868,8 +3006,8 @@ static int tcc_preprocess(TCCState *s1)
     token_seen = 0;
     line_ref = 0;
     file_ref = NULL;
-
     iptr = s1->include_stack_ptr;
+
     for (;;) {
         next();
         if (tok == TOK_EOF) {
@@ -2904,7 +3042,6 @@ print_line:
         }
         fputs(get_tok_str(tok, &tokc), s1->outfile);
     }
-    free_defines(define_start); 
+    free_defines(define_start);
     return 0;
 }
-
diff --git a/tccrun.c b/tccrun.c
index e984c0fd..e88f87e4 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -1,5 +1,5 @@
 /*
- *  TCC - Tiny C Compiler
+ *  TCC - Tiny C Compiler - Support for -run switch
  *
  *  Copyright (c) 2001-2004 Fabrice Bellard
  *
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* tccrun.c - support for tcc -run */
+#include "tcc.h"
 
 #ifdef _WIN32
 #define ucontext_t CONTEXT
@@ -26,7 +26,7 @@
 
 static void set_pages_executable(void *ptr, unsigned long length);
 static void set_exception_handler(void);
-static int rt_get_caller_pc(unsigned long *paddr, ucontext_t *uc, int level);
+static int rt_get_caller_pc(uplong *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);
 
@@ -173,8 +173,8 @@ static void set_pages_executable(void *ptr, unsigned long length)
     VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
 #else
     unsigned long start, end;
-    start = (unsigned long)ptr & ~(PAGESIZE - 1);
-    end = (unsigned long)ptr + length;
+    start = (uplong)ptr & ~(PAGESIZE - 1);
+    end = (uplong)ptr + length;
     end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
     mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
 #endif
@@ -185,7 +185,7 @@ static void set_pages_executable(void *ptr, unsigned long length)
 
 /* print the position in the source file of PC value 'pc' by reading
    the stabs debug information */
-static unsigned long rt_printline(unsigned long wanted_pc)
+static uplong rt_printline(uplong wanted_pc)
 {
     Stab_Sym *sym, *sym_end;
     char func_name[128], last_func_name[128];
@@ -194,7 +194,7 @@ static unsigned long rt_printline(unsigned long wanted_pc)
     int incl_index, len, last_line_num, i;
     const char *str, *p;
 
-    fprintf(stderr, "0x%08lx:", wanted_pc);
+    fprintf(stderr, "0x%08lx:", (unsigned long)wanted_pc);
 
     func_name[0] = '\0';
     func_addr = 0;
@@ -311,7 +311,7 @@ static unsigned long rt_printline(unsigned long wanted_pc)
 static void rt_error(ucontext_t *uc, const char *fmt, ...)
 {
     va_list ap;
-    unsigned long pc;
+    uplong pc;
     int i;
 
     va_start(ap, fmt);
@@ -327,7 +327,7 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...)
         else
             fprintf(stderr, "by ");
         pc = rt_printline(pc);
-        if (pc == (unsigned long)rt_prog_main && pc)
+        if (pc == (uplong)rt_prog_main && pc)
             break;
     }
     exit(255);
@@ -505,11 +505,15 @@ static void set_exception_handler(void)
     SetUnhandledExceptionFilter(cpu_exception_handler);
 }
 
+#ifdef _WIN64
+#define Eip Rip
+#define Ebp Rbp
+#endif
+
 /* return the PC at frame level 'level'. Return non zero if not found */
-static int rt_get_caller_pc(unsigned long *paddr,
-			    CONTEXT *uc, int level)
+static int rt_get_caller_pc(uplong *paddr, CONTEXT *uc, int level)
 {
-    unsigned long fp;
+    uplong fp;
     int i;
 
     if (level == 0) {
@@ -521,13 +525,16 @@ static int rt_get_caller_pc(unsigned long *paddr,
 	    /* XXX: check address validity with program info */
 	    if (fp <= 0x1000 || fp >= 0xc0000000)
 		return -1;
-	    fp = ((unsigned long *)fp)[0];
+	    fp = ((uplong*)fp)[0];
 	}
-	*paddr = ((unsigned long *)fp)[1];
+	*paddr = ((uplong*)fp)[1];
 	return 0;
     }
 }
 
+#undef Eip
+#undef Ebp
+
 #endif /* _WIN32 */
 #endif /* CONFIG_TCC_BACKTRACE */
 /* ------------------------------------------------------------- */
@@ -584,13 +591,7 @@ void *resolve_sym(TCCState *s1, const char *symbol)
     return NULL;
 }
 
-#elif defined(_WIN32)
-
-#define dlclose FreeLibrary
-
-#else
-
-#include <dlfcn.h>
+#elif !defined(_WIN32)
 
 void *resolve_sym(TCCState *s1, const char *sym)
 {
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 86ec4ea8..d9f7528f 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -20,10 +20,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <assert.h>
+#ifdef TARGET_DEFS_ONLY
 
 /* number of available registers */
-#define NB_REGS             5
+#define NB_REGS         5
+#define NB_ASM_REGS     8
 
 /* a register can belong to several classes. The classes must be
    sorted from more general to more precise (see gv2() code which does
@@ -60,14 +61,6 @@ enum {
 #define REX_BASE(reg) (((reg) >> 3) & 1)
 #define REG_VALUE(reg) ((reg) & 7)
 
-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,
-};
-
 /* return registers for function */
 #define REG_IRET TREG_RAX /* single word int return register */
 #define REG_LRET TREG_RDX /* second word return register (for long long) */
@@ -85,6 +78,9 @@ const int reg_classes[NB_REGS] = {
 /* maximum alignment (for aligned attribute support) */
 #define MAX_ALIGN     8
 
+ST_FUNC void gen_opl(int op);
+ST_FUNC void gen_le64(int64_t c);
+
 /******************************************************/
 /* ELF defines */
 
@@ -100,6 +96,18 @@ const int reg_classes[NB_REGS] = {
 #define ELF_PAGE_SIZE  0x1000
 
 /******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+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,
+};
 
 static unsigned long func_sub_sp_offset;
 static int func_ret_sub;
@@ -184,7 +192,7 @@ static int is_sse_float(int t) {
 }
 
 /* instruction + 4 bytes data. Return the address of the data */
-static int oad(int c, int s)
+ST_FUNC int oad(int c, int s)
 {
     int ind1;
 
@@ -198,7 +206,7 @@ static int oad(int c, int s)
     return s;
 }
 
-static void gen_addr32(int r, Sym *sym, int c)
+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);
@@ -206,7 +214,7 @@ static void gen_addr32(int r, Sym *sym, int c)
 }
 
 /* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addr64(int r, Sym *sym, int64_t c)
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
 {
     if (r & VT_SYM)
         greloc(cur_text_section, sym, ind, R_X86_64_64);
@@ -214,7 +222,7 @@ static void gen_addr64(int r, Sym *sym, int64_t c)
 }
 
 /* output constant with relocation if 'r & VT_SYM' is true */
-static void gen_addrpc32(int r, Sym *sym, int c)
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
 {
     if (r & VT_SYM)
         greloc(cur_text_section, sym, ind, R_X86_64_PC32);
@@ -1537,3 +1545,5 @@ void ggoto(void)
 
 /* end of x86-64 code generator */
 /*************************************************************/
+#endif /* ! TARGET_DEFS_ONLY */
+/******************************************************/