summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xdata/readme.txt5
-rwxr-xr-xdoc/advopt.txt (renamed from data/advopt.txt)14
-rwxr-xr-xdoc/basicopt.txt (renamed from data/basicopt.txt)14
-rwxr-xr-xdoc/keywords.txt (renamed from data/keywords.txt)0
-rwxr-xr-xdoc/manual.txt2
-rwxr-xr-xdoc/nimrodc.txt4
-rwxr-xr-xkoch.nim3
-rwxr-xr-xlib/system/gc.nim16
-rwxr-xr-xlib/system/systhread.nim2
-rwxr-xr-xrod/ccgexprs.nim2
-rwxr-xr-xrod/commands.nim8
-rwxr-xr-xrod/crc.nim8
-rwxr-xr-xrod/extccomp.nim8
-rwxr-xr-xrod/options.nim2
-rwxr-xr-xrod/rst.nim11
-rwxr-xr-xrod/semstmts.nim2
-rwxr-xr-xrod/semtypes.nim2
-rwxr-xr-xrod/tccgen.nim8
-rwxr-xr-xtinyc/arm-gen.c1734
-rwxr-xr-xtinyc/c67-gen.c2548
-rwxr-xr-xtinyc/coff.h446
-rwxr-xr-xtinyc/config.h15
-rwxr-xr-xtinyc/config.mak20
-rwxr-xr-xtinyc/config.texi1
-rwxr-xr-xtinyc/config_edited.h15
-rwxr-xr-xtinyc/elf.h1714
-rwxr-xr-xtinyc/examples/ex1.c8
-rwxr-xr-xtinyc/examples/ex2.c98
-rwxr-xr-xtinyc/examples/ex3.c24
-rwxr-xr-xtinyc/examples/ex4.c26
-rwxr-xr-xtinyc/examples/ex5.c8
-rwxr-xr-xtinyc/i386-asm.c1211
-rwxr-xr-xtinyc/i386-asm.h446
-rwxr-xr-xtinyc/i386-gen.c1034
-rwxr-xr-xtinyc/il-gen.c667
-rwxr-xr-xtinyc/il-opcodes.h251
-rwxr-xr-xtinyc/include/float.h57
-rwxr-xr-xtinyc/include/stdarg.h67
-rwxr-xr-xtinyc/include/stdbool.h10
-rwxr-xr-xtinyc/include/stddef.h20
-rwxr-xr-xtinyc/include/tcclib.h78
-rwxr-xr-xtinyc/include/varargs.h11
-rwxr-xr-xtinyc/lib/alloca86-bt.S45
-rwxr-xr-xtinyc/lib/alloca86.S33
-rwxr-xr-xtinyc/lib/bcheck.c868
-rwxr-xr-xtinyc/lib/libtcc1.c607
-rwxr-xr-xtinyc/libtcc.c2259
-rwxr-xr-xtinyc/libtcc.h108
-rwxr-xr-xtinyc/stab.def234
-rwxr-xr-xtinyc/stab.h17
-rwxr-xr-xtinyc/tcc-doc.html2241
-rwxr-xr-xtinyc/tcc-doc.texi1227
-rwxr-xr-xtinyc/tcc.c553
-rwxr-xr-xtinyc/tcc.h766
-rwxr-xr-xtinyc/tccasm.c1021
-rwxr-xr-xtinyc/tcccoff.c957
-rwxr-xr-xtinyc/tccelf.c2732
-rwxr-xr-xtinyc/tccgen.c5122
-rwxr-xr-xtinyc/tccpe.c1559
-rwxr-xr-xtinyc/tccpp.c2935
-rwxr-xr-xtinyc/tcctok.h469
-rwxr-xr-xtinyc/tests/asmtest.S558
-rwxr-xr-xtinyc/tests/boundtest.c214
-rwxr-xr-xtinyc/tests/gcctestsuite.sh33
-rwxr-xr-xtinyc/tests/libtcc_test.c84
-rwxr-xr-xtinyc/tests/tcctest.c2202
-rwxr-xr-xtinyc/texi2pod.pl427
-rwxr-xr-xtinyc/win32/build-tcc.bat28
-rwxr-xr-xtinyc/win32/examples/dll.c15
-rwxr-xr-xtinyc/win32/examples/fib.c24
-rwxr-xr-xtinyc/win32/examples/hello_dll.c19
-rwxr-xr-xtinyc/win32/examples/hello_win.c159
-rwxr-xr-xtinyc/win32/include/_mingw.h54
-rwxr-xr-xtinyc/win32/include/assert.h71
-rwxr-xr-xtinyc/win32/include/conio.h159
-rwxr-xr-xtinyc/win32/include/ctype.h232
-rwxr-xr-xtinyc/win32/include/dir.h26
-rwxr-xr-xtinyc/win32/include/direct.h95
-rwxr-xr-xtinyc/win32/include/dirent.h96
-rwxr-xr-xtinyc/win32/include/dos.h110
-rwxr-xr-xtinyc/win32/include/errno.h117
-rwxr-xr-xtinyc/win32/include/excpt.h20
-rwxr-xr-xtinyc/win32/include/fcntl.h135
-rwxr-xr-xtinyc/win32/include/fenv.h85
-rwxr-xr-xtinyc/win32/include/float.h224
-rwxr-xr-xtinyc/win32/include/inttypes.h275
-rwxr-xr-xtinyc/win32/include/io.h296
-rwxr-xr-xtinyc/win32/include/limits.h115
-rwxr-xr-xtinyc/win32/include/locale.h100
-rwxr-xr-xtinyc/win32/include/malloc.h87
-rwxr-xr-xtinyc/win32/include/math.h438
-rwxr-xr-xtinyc/win32/include/mem.h8
-rwxr-xr-xtinyc/win32/include/memory.h9
-rwxr-xr-xtinyc/win32/include/process.h158
-rwxr-xr-xtinyc/win32/include/setjmp.h72
-rwxr-xr-xtinyc/win32/include/share.h44
-rwxr-xr-xtinyc/win32/include/signal.h111
-rwxr-xr-xtinyc/win32/include/stdarg.h16
-rwxr-xr-xtinyc/win32/include/stdbool.h10
-rwxr-xr-xtinyc/win32/include/stddef.h23
-rwxr-xr-xtinyc/win32/include/stdint.h184
-rwxr-xr-xtinyc/win32/include/stdio.h413
-rwxr-xr-xtinyc/win32/include/stdlib.h482
-rwxr-xr-xtinyc/win32/include/string.h206
-rwxr-xr-xtinyc/win32/include/sys/fcntl.h8
-rwxr-xr-xtinyc/win32/include/sys/file.h9
-rwxr-xr-xtinyc/win32/include/sys/locking.h52
-rwxr-xr-xtinyc/win32/include/sys/stat.h190
-rwxr-xr-xtinyc/win32/include/sys/time.h3
-rwxr-xr-xtinyc/win32/include/sys/timeb.h82
-rwxr-xr-xtinyc/win32/include/sys/types.h118
-rwxr-xr-xtinyc/win32/include/sys/unistd.h9
-rwxr-xr-xtinyc/win32/include/sys/utime.h89
-rwxr-xr-xtinyc/win32/include/tchar.h367
-rwxr-xr-xtinyc/win32/include/time.h219
-rwxr-xr-xtinyc/win32/include/unistd.h10
-rwxr-xr-xtinyc/win32/include/values.h4
-rwxr-xr-xtinyc/win32/include/varargs.h11
-rwxr-xr-xtinyc/win32/include/wchar.h318
-rwxr-xr-xtinyc/win32/include/wctype.h127
-rwxr-xr-xtinyc/win32/include/winapi/basetsd.h119
-rwxr-xr-xtinyc/win32/include/winapi/basetyps.h144
-rwxr-xr-xtinyc/win32/include/winapi/winbase.h1852
-rwxr-xr-xtinyc/win32/include/winapi/wincon.h207
-rwxr-xr-xtinyc/win32/include/winapi/windef.h240
-rwxr-xr-xtinyc/win32/include/winapi/windows.h176
-rwxr-xr-xtinyc/win32/include/winapi/winerror.h1054
-rwxr-xr-xtinyc/win32/include/winapi/wingdi.h2843
-rwxr-xr-xtinyc/win32/include/winapi/winnetwk.h346
-rwxr-xr-xtinyc/win32/include/winapi/winnls.h651
-rwxr-xr-xtinyc/win32/include/winapi/winnt.h2667
-rwxr-xr-xtinyc/win32/include/winapi/winreg.h159
-rwxr-xr-xtinyc/win32/include/winapi/winsvc.h309
-rwxr-xr-xtinyc/win32/include/winapi/winuser.h3472
-rwxr-xr-xtinyc/win32/include/winapi/winver.h133
-rwxr-xr-xtinyc/win32/lib/chkstk.S29
-rwxr-xr-xtinyc/win32/lib/crt1.c35
-rwxr-xr-xtinyc/win32/lib/dllcrt1.c13
-rwxr-xr-xtinyc/win32/lib/dllmain.c9
-rwxr-xr-xtinyc/win32/lib/gdi32.def337
-rwxr-xr-xtinyc/win32/lib/kernel32.def763
-rwxr-xr-xtinyc/win32/lib/libtcc1.abin0 -> 10252 bytes
-rwxr-xr-xtinyc/win32/lib/msvcrt.def782
-rwxr-xr-xtinyc/win32/lib/user32.def654
-rwxr-xr-xtinyc/win32/lib/wincrt1.c49
-rwxr-xr-xtinyc/win32/libtcc/libtcc.abin0 -> 146642 bytes
-rwxr-xr-xtinyc/win32/libtcc/libtcc.h108
-rwxr-xr-xtinyc/win32/tcc-win32.txt158
-rwxr-xr-xtinyc/win32/tools/tiny_impdef.c393
-rwxr-xr-xtinyc/win32/tools/tiny_libmaker.c310
-rwxr-xr-xtinyc/x86_64-gen.c1419
151 files changed, 63611 insertions, 43 deletions
diff --git a/data/readme.txt b/data/readme.txt
index ee9630eac..91bc41dce 100755
--- a/data/readme.txt
+++ b/data/readme.txt
@@ -1,3 +1,2 @@
-This directory contains data files in Python or ordinary text format. These
-files are required for building Nimrod. Note: I try to get rid of the "data"
-dictionary in the long run.
+The files in this directory used to be required for building Nimrod. Now they 
+are only used for the documentation. 
diff --git a/data/advopt.txt b/doc/advopt.txt
index 344b3475b..e2d4f37b2 100755
--- a/data/advopt.txt
+++ b/doc/advopt.txt
@@ -1,10 +1,12 @@
-Advanced commands::
-  pretty                    pretty print the inputfile
-  genDepend                 generate a DOT file containing the
+Advanced commands:
+  //run                     run the project (with Tiny C backend; Linux only!)
+  //pretty                  pretty print the inputfile
+  //genDepend               generate a DOT file containing the
                             module dependency graph
-  listDef                   list all defined conditionals and exit
-  check                     checks the project for syntax and semantic
-  parse                     parses a single file (for debugging Nimrod)
+  //listDef                 list all defined conditionals and exit
+  //check                   checks the project for syntax and semantic
+  //parse                   parses a single file (for debugging Nimrod)
+
 Advanced options:
   -w, --warnings:on|off     turn all warnings on|off
   --warning[X]:on|off       turn specific warning X on|off
diff --git a/data/basicopt.txt b/doc/basicopt.txt
index 0201b84d7..7d2a9b26d 100755
--- a/data/basicopt.txt
+++ b/doc/basicopt.txt
@@ -1,11 +1,13 @@
 Usage::
   nimrod command [options] inputfile [arguments]
-Command::
-  compile, c                compile project with default code generator (C)
-  compileToC, cc            compile project with C code generator
-  doc                       generate the documentation for inputfile
-  rst2html                  converts a reStructuredText file to HTML
-  rst2tex                   converts a reStructuredText file to TeX
+
+Command:
+  //compile, c              compile project with default code generator (C)
+  //compileToC, cc          compile project with C code generator
+  //doc                     generate the documentation for inputfile
+  //rst2html                converts a reStructuredText file to HTML
+  //rst2tex                 converts a reStructuredText file to TeX
+
 Arguments:
   arguments are passed to the program being run (if --run option is selected)
 Options:
diff --git a/data/keywords.txt b/doc/keywords.txt
index a6d96834a..a6d96834a 100755
--- a/data/keywords.txt
+++ b/doc/keywords.txt
diff --git a/doc/manual.txt b/doc/manual.txt
index 36be32538..9a6060264 100755
--- a/doc/manual.txt
+++ b/doc/manual.txt
@@ -160,7 +160,7 @@ underscores ``__`` are not allowed::
 The following `keywords`:idx: are reserved and cannot be used as identifiers:

 

 .. code-block:: nimrod

-   :file: ../data/keywords.txt

+   :file: keywords.txt

 

 Some keywords are unused; they are reserved for future developments of the

 language.

diff --git a/doc/nimrodc.txt b/doc/nimrodc.txt
index 733c83f0c..bd185ca4c 100755
--- a/doc/nimrodc.txt
+++ b/doc/nimrodc.txt
@@ -30,11 +30,11 @@ Command line switches
 ---------------------

 Basis command line switches are:

 

-.. include:: ../data/basicopt.txt

+.. include:: basicopt.txt

 

 Advanced command line switches are:

 

-.. include:: ../data/advopt.txt

+.. include:: advopt.txt

 

 

 Configuration file

diff --git a/koch.nim b/koch.nim
index bf07f3ba9..a926de479 100755
--- a/koch.nim
+++ b/koch.nim
@@ -30,6 +30,9 @@ Possible Commands:
   csource [options]        builds the C sources for installation
   zip                      builds the installation ZIP package
   inno                     builds the Inno Setup installer
+Boot options:
+  -d:release               produce a release version of the compiler
+  -d:tinyc                 include the Tiny C backend (not supported on Windows)
 """
 
 proc exec(cmd: string) =
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 59ddda5e7..cd803d70a 100755
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -487,14 +487,14 @@ when not defined(useNimRtl):
         stackBottom = cast[pointer](max(a, b))
 
 proc stackSize(): int {.noinline.} =
-  var stackTop: array[0..1, pointer]
-  result = abs(cast[int](addr(stackTop[0])) - cast[int](stackBottom))
+  var stackTop {.volatile.}: pointer
+  result = abs(cast[int](addr(stackTop)) - cast[int](stackBottom))
 
 when defined(sparc): # For SPARC architecture.
   proc isOnStack(p: pointer): bool =
-    var stackTop: array [0..1, pointer]
+    var stackTop {.volatile.}: pointer
     var b = cast[TAddress](stackBottom)
-    var a = cast[TAddress](addr(stackTop[0]))
+    var a = cast[TAddress](addr(stackTop))
     var x = cast[TAddress](p)
     result = x >=% a and x <=% b
 
@@ -522,9 +522,9 @@ elif stackIncreases:
   # Generic code for architectures where addresses increase as the stack grows.
   # ---------------------------------------------------------------------------
   proc isOnStack(p: pointer): bool =
-    var stackTop: array [0..1, pointer]
+    var stackTop {.volatile.}: pointer
     var a = cast[TAddress](stackBottom)
-    var b = cast[TAddress](addr(stackTop[0]))
+    var b = cast[TAddress](addr(stackTop))
     var x = cast[TAddress](p)
     result = x >=% a and x <=% b
 
@@ -549,9 +549,9 @@ else:
   # Generic code for architectures where addresses decrease as the stack grows.
   # ---------------------------------------------------------------------------
   proc isOnStack(p: pointer): bool =
-    var stackTop: array [0..1, pointer]
+    var stackTop {.volatile.}: pointer
     var b = cast[TAddress](stackBottom)
-    var a = cast[TAddress](addr(stackTop[0]))
+    var a = cast[TAddress](addr(stackTop))
     var x = cast[TAddress](p)
     result = x >=% a and x <=% b
 
diff --git a/lib/system/systhread.nim b/lib/system/systhread.nim
index 68121661f..58482ac65 100755
--- a/lib/system/systhread.nim
+++ b/lib/system/systhread.nim
@@ -40,7 +40,7 @@ proc atomicDec(memLoc: var int, x: int): int =
 type
   TThread* {.final, pure.} = object
     next: ptr TThread
-  TThreadFunc* = proc (closure: pointer) {.cdecl.}
+  TThreadFunc* = proc (closure: pointer)
   
 proc createThread*(t: var TThread, fn: TThreadFunc) = 
   nil
diff --git a/rod/ccgexprs.nim b/rod/ccgexprs.nim
index 7ea90eec8..6169c970c 100755
--- a/rod/ccgexprs.nim
+++ b/rod/ccgexprs.nim
@@ -243,7 +243,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     # passed to an open array?
     if needsComplexAssignment(dest.t):
       appcg(p, cpsStmts,     # XXX: is this correct for arrays?
-           "genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
+           "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len0, $3);$n",
            [addrLoc(dest), addrLoc(src), genTypeInfo(p.module, dest.t)])
     else:
       appcg(p, cpsStmts,
diff --git a/rod/commands.nim b/rod/commands.nim
index f67a8e765..706332447 100755
--- a/rod/commands.nim
+++ b/rod/commands.nim
@@ -31,12 +31,11 @@ const
 
 const 
   Usage = """
-Usage::
+Usage:
   nimrod command [options] inputfile [arguments]
-Command::
+Command:
   compile, c                compile project with default code generator (C)
   compileToC, cc            compile project with C code generator
-  run                       compile the project in memory and run it
   doc                       generate the documentation for inputfile
   rst2html                  converts a reStructuredText file to HTML
   rst2tex                   converts a reStructuredText file to TeX
@@ -70,7 +69,8 @@ Options:
 """
         
   AdvancedUsage = """
-Advanced commands::
+Advanced commands:
+  run                       run the project (with Tiny C backend; buggy!)
   pretty                    pretty print the inputfile
   genDepend                 generate a DOT file containing the
                             module dependency graph
diff --git a/rod/crc.nim b/rod/crc.nim
index b397d5382..be1aee16b 100755
--- a/rod/crc.nim
+++ b/rod/crc.nim
@@ -17,8 +17,8 @@ const
   InitCrc32* = TCrc32(- 1)
   InitAdler32* = int32(1)
 
-proc updateCrc32*(val: int8, crc: TCrc32): TCrc32
-proc updateCrc32*(val: Char, crc: TCrc32): TCrc32
+proc updateCrc32*(val: int8, crc: TCrc32): TCrc32 {.inline.}
+proc updateCrc32*(val: Char, crc: TCrc32): TCrc32 {.inline.}
 proc crcFromBuf*(buf: Pointer, length: int): TCrc32
 proc strCrc32*(s: string): TCrc32
 proc crcFromFile*(filename: string): TCrc32
@@ -85,6 +85,10 @@ proc strCrc32(s: string): TCrc32 =
   result = InitCrc32
   for i in countup(0, len(s) + 0 - 1): result = updateCrc32(s[i], result)
   
+proc `><`*(c: TCrc32, s: string): TCrc32 = 
+  result = c
+  for i in 0..len(s)-1: result = updateCrc32(s[i], result)  
+  
 type 
   TByteArray = array[0..10000000, int8]
   PByteArray = ref TByteArray
diff --git a/rod/extccomp.nim b/rod/extccomp.nim
index d7b429339..ce8e71547 100755
--- a/rod/extccomp.nim
+++ b/rod/extccomp.nim
@@ -299,9 +299,15 @@ proc toObjFile(filenameWithoutExt: string): string =
 proc addFileToCompile(filename: string) = 
   appendStr(toCompile, filename)
 
+proc footprint(filename: string): TCrc32 =
+  result = crcFromFile(filename) >< 
+      platform.OS[targetOS].name ><
+      platform.CPU[targetCPU].name ><
+      extccomp.CC[extccomp.ccompiler].name
+
 proc externalFileChanged(filename: string): bool = 
   var crcFile = toGeneratedFile(filename, "crc")
-  var currentCrc = int(crcFromFile(filename))
+  var currentCrc = int(footprint(filename))
   var f: TFile
   if open(f, crcFile, fmRead): 
     var line = f.readLine()
diff --git a/rod/options.nim b/rod/options.nim
index 28b58f40a..3742cad9d 100755
--- a/rod/options.nim
+++ b/rod/options.nim
@@ -11,7 +11,7 @@ import
   os, lists, strutils, nstrtabs
   
 const
-  hasTinyCBackend* = false
+  hasTinyCBackend* = defined(tinyc)
 
 type                          # please make sure we have under 32 options
                               # (improves code efficiency a lot!)
diff --git a/rod/rst.nim b/rod/rst.nim
index 5c675f563..207640b2c 100755
--- a/rod/rst.nim
+++ b/rod/rst.nim
@@ -948,6 +948,10 @@ proc isDefList(p: TRstParser): bool =
       (p.tok[j].kind in {tkWord, tkOther, tkPunct}) and
       (p.tok[j - 2].symbol != "::")
 
+proc isOptionList(p: TRstParser): bool = 
+  result = match(p, p.idx, "-w") or match(p, p.idx, "--w") or
+           match(p, p.idx, "/w") or match(p, p.idx, "//w")
+
 proc whichSection(p: TRstParser): TRstNodeKind = 
   case p.tok[p.idx].kind
   of tkAdornment: 
@@ -977,8 +981,7 @@ proc whichSection(p: TRstParser): TRstNodeKind =
       rstMessage(p, errGridTableNotImplemented)
     elif isDefList(p): 
       result = rnDefList
-    elif match(p, p.idx, "-w") or match(p, p.idx, "--w") or
-        match(p, p.idx, "/w"): 
+    elif isOptionList(p): 
       result = rnOptionList
     else: 
       result = rnParagraph
@@ -1176,11 +1179,11 @@ proc parseBulletList(p: var TRstParser): PRstNode =
 proc parseOptionList(p: var TRstParser): PRstNode = 
   result = newRstNode(rnOptionList)
   while true: 
-    if match(p, p.idx, "-w") or match(p, p.idx, "--w") or
-        match(p, p.idx, "/w"): 
+    if isOptionList(p):
       var a = newRstNode(rnOptionGroup)
       var b = newRstNode(rnDescription)
       var c = newRstNode(rnOptionListItem)
+      if match(p, p.idx, "//w"): inc(p.idx)
       while not (p.tok[p.idx].kind in {tkIndent, tkEof}): 
         if (p.tok[p.idx].kind == tkWhite) and (len(p.tok[p.idx].symbol) > 1): 
           inc(p.idx)
diff --git a/rod/semstmts.nim b/rod/semstmts.nim
index cadecad40..b449c995a 100755
--- a/rod/semstmts.nim
+++ b/rod/semstmts.nim
@@ -671,6 +671,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
       if n.sons[genericParamsPos] == nil:
         # we have a list of implicit type parameters:
         n.sons[genericParamsPos] = gp
+        # check for semantics again:
+        semParamList(c, n.sons[ParamsPos], nil, s)
     addParams(c, s.typ.n)
   else: 
     s.typ = newTypeS(tyProc, c)
diff --git a/rod/semtypes.nim b/rod/semtypes.nim
index f5fae4811..8083227fd 100755
--- a/rod/semtypes.nim
+++ b/rod/semtypes.nim
@@ -454,6 +454,8 @@ proc addTypeVarsOfGenericBody(c: PContext, t: PType, genericParams: PNode,
       #if not IntSetContainsOrIncl(cl, t.sons[i].sym.ident.id):
       var s = copySym(t.sons[i].sym)
       s.position = sonsLen(genericParams)
+      if s.typ == nil or s.typ.kind != tyGenericParam: 
+        InternalError("addTypeVarsOfGenericBody 2")
       addDecl(c, s)
       addSon(genericParams, newSymNode(s))
       addSon(result, t.sons[i])
diff --git a/rod/tccgen.nim b/rod/tccgen.nim
index 3e3c311a4..0a588fda0 100755
--- a/rod/tccgen.nim
+++ b/rod/tccgen.nim
@@ -28,9 +28,11 @@ proc addFile(filename: string) =
     rawMessage(errCannotOpenFile, filename)
 
 proc setupEnvironment = 
-  #defineSymbol(gTinyC, "__x86_64__", nil)
-  #defineSymbol(gTinyC, "__linux__", nil)
-  #defineSymbol(gTinyC, "__linux", nil)
+  when defined(amd64):
+    defineSymbol(gTinyC, "__x86_64__", nil)
+  when defined(linux):
+    defineSymbol(gTinyC, "__linux__", nil)
+    defineSymbol(gTinyC, "__linux", nil)
   var nimrodDir = getPrefixDir()
 
   addIncludePath(gTinyC, libpath)
diff --git a/tinyc/arm-gen.c b/tinyc/arm-gen.c
new file mode 100755
index 000000000..42feecf73
--- /dev/null
+++ b/tinyc/arm-gen.c
@@ -0,0 +1,1734 @@
+/*
+ *  ARMv4 code generator for TCC
+ * 
+ *  Copyright (c) 2003 Daniel Glöckner
+ *
+ *  Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TCC_ARM_EABI
+#define TCC_ARM_VFP
+#endif
+
+
+/* number of available registers */
+#ifdef TCC_ARM_VFP
+#define NB_REGS            13
+#else
+#define NB_REGS             9
+#endif
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_R0      0x0004
+#define RC_R1      0x0008 
+#define RC_R2      0x0010
+#define RC_R3      0x0020
+#define RC_R12     0x0040
+#define RC_F0      0x0080
+#define RC_F1      0x0100
+#define RC_F2      0x0200
+#define RC_F3      0x0400
+#ifdef TCC_ARM_VFP
+#define RC_F4      0x0800
+#define RC_F5      0x1000
+#define RC_F6      0x2000
+#define RC_F7      0x4000
+#endif
+#define RC_IRET    RC_R0  /* function return: integer register */
+#define RC_LRET    RC_R1  /* function return: second integer register */
+#define RC_FRET    RC_F0  /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_R0 = 0,
+    TREG_R1,
+    TREG_R2,
+    TREG_R3,
+    TREG_R12,
+    TREG_F0,
+    TREG_F1,
+    TREG_F2,
+    TREG_F3,
+#ifdef TCC_ARM_VFP
+    TREG_F4,
+    TREG_F5,
+    TREG_F6,
+    TREG_F7,
+#endif
+};
+
+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
+
+/* return registers for function */
+#define REG_IRET TREG_R0 /* single word int return register */
+#define REG_LRET TREG_R1 /* second word return register (for long long) */
+#define REG_FRET TREG_F0 /* float return register */
+
+#ifdef TCC_ARM_EABI
+#define TOK___divdi3 TOK___aeabi_ldivmod
+#define TOK___moddi3 TOK___aeabi_ldivmod
+#define TOK___udivdi3 TOK___aeabi_uldivmod
+#define TOK___umoddi3 TOK___aeabi_uldivmod
+#endif
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+//#define FUNC_STRUCT_PARAM_AS_PTR
+
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+static CType float_type, double_type, func_float_type, func_double_type;
+#define func_ldouble_type func_double_type
+#else
+#define func_float_type func_old_type
+#define func_double_type func_old_type
+#define func_ldouble_type func_old_type
+#endif
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#ifdef TCC_ARM_VFP
+#define LDOUBLE_SIZE  8
+#endif
+
+#ifndef LDOUBLE_SIZE
+#define LDOUBLE_SIZE  8
+#endif
+
+#ifdef TCC_ARM_EABI
+#define LDOUBLE_ALIGN 8
+#else
+#define LDOUBLE_ALIGN 4
+#endif
+
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+/* ELF defines */
+
+#define EM_TCC_TARGET EM_ARM
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_ARM_ABS32
+#define R_JMP_SLOT  R_ARM_JUMP_SLOT
+#define R_COPY      R_ARM_COPY
+
+#define ELF_START_ADDR 0x00008000
+#define ELF_PAGE_SIZE  0x1000
+
+/******************************************************/
+static unsigned long func_sub_sp_offset,last_itod_magic;
+static int leaffunc;
+
+void o(unsigned long i)
+{
+  /* this is a good place to start adding big-endian support*/
+  int ind1;
+
+  ind1 = ind + 4;
+  if (!cur_text_section)
+    error("compiler error! This happens f.ex. if the compiler\n"
+         "can't evaluate constant expressions outside of a function.");
+  if (ind1 > cur_text_section->data_allocated)
+    section_realloc(cur_text_section, ind1);
+  cur_text_section->data[ind++] = i&255;
+  i>>=8;
+  cur_text_section->data[ind++] = i&255;
+  i>>=8; 
+  cur_text_section->data[ind++] = i&255;
+  i>>=8;
+  cur_text_section->data[ind++] = i;
+}
+
+static unsigned long stuff_const(unsigned long op,unsigned long c)
+{
+  int try_neg=0;
+  unsigned long nc = 0,negop = 0;
+
+  switch(op&0x1F00000)
+  {
+    case 0x800000: //add
+    case 0x400000: //sub
+      try_neg=1;
+      negop=op^0xC00000;
+      nc=-c;
+      break;
+    case 0x1A00000: //mov
+    case 0x1E00000: //mvn
+      try_neg=1;
+      negop=op^0x400000;
+      nc=~c;
+      break;
+    case 0x200000: //xor
+      if(c==~0)
+	return (op&0xF010F000)|((op>>16)&0xF)|0x1E00000;
+      break;
+    case 0x0: //and
+      if(c==~0)
+	return (op&0xF010F000)|((op>>16)&0xF)|0x1A00000;
+    case 0x1C00000: //bic
+      try_neg=1;
+      negop=op^0x1C00000;
+      nc=~c;
+      break;
+    case 0x1800000: //orr
+      if(c==~0)
+	return (op&0xFFF0FFFF)|0x1E00000;
+      break;
+  }
+  do {
+    unsigned long m;
+    int i;
+    if(c<256) /* catch undefined <<32 */
+      return op|c;
+    for(i=2;i<32;i+=2) {
+      m=(0xff>>i)|(0xff<<(32-i));
+      if(!(c&~m))
+	return op|(i<<7)|(c<<i)|(c>>(32-i));
+    }
+    op=negop;
+    c=nc;
+  } while(try_neg--);
+  return 0;
+}
+
+
+//only add,sub
+void stuff_const_harder(unsigned long op,unsigned long v) {
+  unsigned long x;
+  x=stuff_const(op,v);
+  if(x)
+    o(x);
+  else {
+    unsigned long a[16],nv,no,o2,n2;
+    int i,j,k;
+    a[0]=0xff;
+    o2=(op&0xfff0ffff)|((op&0xf000)<<4);;
+    for(i=1;i<16;i++)
+      a[i]=(a[i-1]>>2)|(a[i-1]<<30);
+    for(i=0;i<12;i++)
+      for(j=i<4?i+12:15;j>=i+4;j--)
+	if((v&(a[i]|a[j]))==v) {
+	  o(stuff_const(op,v&a[i]));
+	  o(stuff_const(o2,v&a[j]));
+	  return;
+	}
+    no=op^0xC00000;
+    n2=o2^0xC00000;
+    nv=-v;
+    for(i=0;i<12;i++)
+      for(j=i<4?i+12:15;j>=i+4;j--)
+	if((nv&(a[i]|a[j]))==nv) {
+	  o(stuff_const(no,nv&a[i]));
+	  o(stuff_const(n2,nv&a[j]));
+	  return;
+	}
+    for(i=0;i<8;i++)
+      for(j=i+4;j<12;j++)
+	for(k=i<4?i+12:15;k>=j+4;k--)
+	  if((v&(a[i]|a[j]|a[k]))==v) {
+	    o(stuff_const(op,v&a[i]));
+	    o(stuff_const(o2,v&a[j]));
+	    o(stuff_const(o2,v&a[k]));
+	    return;
+	  }
+    no=op^0xC00000;
+    nv=-v;
+    for(i=0;i<8;i++)
+      for(j=i+4;j<12;j++)
+	for(k=i<4?i+12:15;k>=j+4;k--)
+	  if((nv&(a[i]|a[j]|a[k]))==nv) {
+	    o(stuff_const(no,nv&a[i]));
+	    o(stuff_const(n2,nv&a[j]));
+	    o(stuff_const(n2,nv&a[k]));
+	    return;
+	  }
+    o(stuff_const(op,v&a[0]));
+    o(stuff_const(o2,v&a[4]));
+    o(stuff_const(o2,v&a[8]));
+    o(stuff_const(o2,v&a[12]));
+  }
+}
+
+unsigned long encbranch(int pos,int addr,int fail)
+{
+  addr-=pos+8;
+  addr/=4;
+  if(addr>=0x1000000 || addr<-0x1000000) {
+    if(fail)
+      error("FIXME: function bigger than 32MB");
+    return 0;
+  }
+  return 0x0A000000|(addr&0xffffff);
+}
+
+int decbranch(int pos)
+{
+  int x;
+  x=*(int *)(cur_text_section->data + pos);
+  x&=0x00ffffff;
+  if(x&0x800000)
+    x-=0x1000000;
+  return x*4+pos+8;
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+  unsigned long *x;
+  int lt;
+  while(t) {
+    x=(unsigned long *)(cur_text_section->data + t);
+    t=decbranch(lt=t);
+    if(a==lt+4)
+      *x=0xE1A00000; // nop
+    else {
+      *x &= 0xff000000;
+      *x |= encbranch(lt,a,1);
+    }
+  }
+}
+
+void gsym(int t)
+{
+  gsym_addr(t, ind);
+}
+
+#ifdef TCC_ARM_VFP
+static unsigned long vfpr(int r)
+{
+  if(r<TREG_F0 || r>TREG_F7)
+    error("compiler error! register %i is no vfp register",r);
+  return r-5;
+}
+#else
+static unsigned long fpr(int r)
+{
+  if(r<TREG_F0 || r>TREG_F3)
+    error("compiler error! register %i is no fpa register",r);
+  return r-5;
+}
+#endif
+
+static unsigned long intr(int r)
+{
+  if(r==4)
+    return 12;
+  if((r<0 || r>4) && r!=14)
+    error("compiler error! register %i is no int register",r);
+  return r;
+}
+
+static void calcaddr(unsigned long *base,int *off,int *sgn,int maxoff,unsigned shift)
+{
+  if(*off>maxoff || *off&((1<<shift)-1)) {
+    unsigned long x,y;
+    x=0xE280E000;
+    if(*sgn)
+      x=0xE240E000;
+    x|=(*base)<<16;
+    *base=14; // lr
+    y=stuff_const(x,*off&~maxoff);
+    if(y) {
+      o(y);
+      *off&=maxoff;
+      return;
+    }
+    y=stuff_const(x,(*off+maxoff)&~maxoff);
+    if(y) {
+      o(y);
+      *sgn=!*sgn;
+      *off=((*off+maxoff)&~maxoff)-*off;
+      return;
+    }
+    stuff_const_harder(x,*off&~maxoff);
+    *off&=maxoff;
+  }
+}
+
+static unsigned long mapcc(int cc)
+{
+  switch(cc)
+  {
+    case TOK_ULT:
+      return 0x30000000; /* CC/LO */
+    case TOK_UGE:
+      return 0x20000000; /* CS/HS */
+    case TOK_EQ:
+      return 0x00000000; /* EQ */
+    case TOK_NE:
+      return 0x10000000; /* NE */
+    case TOK_ULE:
+      return 0x90000000; /* LS */
+    case TOK_UGT:
+      return 0x80000000; /* HI */
+    case TOK_Nset:
+      return 0x40000000; /* MI */
+    case TOK_Nclear:
+      return 0x50000000; /* PL */
+    case TOK_LT:
+      return 0xB0000000; /* LT */
+    case TOK_GE:
+      return 0xA0000000; /* GE */
+    case TOK_LE:
+      return 0xD0000000; /* LE */
+    case TOK_GT:
+      return 0xC0000000; /* GT */
+  }
+  error("unexpected condition code");
+  return 0xE0000000; /* AL */
+}
+
+static int negcc(int cc)
+{
+  switch(cc)
+  {
+    case TOK_ULT:
+      return TOK_UGE;
+    case TOK_UGE:
+      return TOK_ULT;
+    case TOK_EQ:
+      return TOK_NE;
+    case TOK_NE:
+      return TOK_EQ;
+    case TOK_ULE:
+      return TOK_UGT;
+    case TOK_UGT:
+      return TOK_ULE;
+    case TOK_Nset:
+      return TOK_Nclear;
+    case TOK_Nclear:
+      return TOK_Nset;
+    case TOK_LT:
+      return TOK_GE;
+    case TOK_GE:
+      return TOK_LT;
+    case TOK_LE:
+      return TOK_GT;
+    case TOK_GT:
+      return TOK_LE;
+  }
+  error("unexpected condition code");
+  return TOK_NE;
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+  int v, ft, fc, fr, sign;
+  unsigned long op;
+  SValue v1;
+
+  fr = sv->r;
+  ft = sv->type.t;
+  fc = sv->c.ul;
+
+  if(fc>=0)
+    sign=0;
+  else {
+    sign=1;
+    fc=-fc;
+  }
+  
+  v = fr & VT_VALMASK;
+  if (fr & VT_LVAL) {
+    unsigned long base=0xB; // fp
+    if(v == VT_LLOCAL) {
+      v1.type.t = VT_PTR;
+      v1.r = VT_LOCAL | VT_LVAL;
+      v1.c.ul = sv->c.ul;
+      load(base=14 /* lr */, &v1);
+      fc=sign=0;
+      v=VT_LOCAL;
+    } else if(v == VT_CONST) {
+      v1.type.t = VT_PTR;
+      v1.r = fr&~VT_LVAL;
+      v1.c.ul = sv->c.ul;
+      v1.sym=sv->sym;
+      load(base=14, &v1);
+      fc=sign=0;
+      v=VT_LOCAL;
+    } else if(v < VT_CONST) {
+      base=intr(v);
+      fc=sign=0;
+      v=VT_LOCAL;
+    }
+    if(v == VT_LOCAL) {
+      if(is_float(ft)) {
+	calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+        op=0xED100A00; /* flds */
+        if(!sign)
+          op|=0x800000;
+        if ((ft & VT_BTYPE) != VT_FLOAT)
+          op|=0x100;   /* flds -> fldd */
+        o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+	op=0xED100100;
+	if(!sign)
+	  op|=0x800000;
+#if LDOUBLE_SIZE == 8
+	if ((ft & VT_BTYPE) != VT_FLOAT)
+	  op|=0x8000;
+#else
+	if ((ft & VT_BTYPE) == VT_DOUBLE)
+	  op|=0x8000;
+	else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	  op|=0x400000;
+#endif
+	o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+      } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
+                || (ft & VT_BTYPE) == VT_SHORT) {
+	calcaddr(&base,&fc,&sign,255,0);
+	op=0xE1500090;
+	if ((ft & VT_BTYPE) == VT_SHORT)
+	  op|=0x20;
+	if ((ft & VT_UNSIGNED) == 0)
+	  op|=0x40;
+	if(!sign)
+	  op|=0x800000;
+	o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+      } else {
+	calcaddr(&base,&fc,&sign,4095,0);
+	op=0xE5100000;
+	if(!sign)
+	  op|=0x800000;
+        if ((ft & VT_BTYPE) == VT_BYTE)
+          op|=0x400000;
+        o(op|(intr(r)<<12)|fc|(base<<16));
+      }
+      return;
+    }
+  } else {
+    if (v == VT_CONST) {
+      op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul);
+      if (fr & VT_SYM || !op) {
+        o(0xE59F0000|(intr(r)<<12));
+        o(0xEA000000);
+        if(fr & VT_SYM)
+	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+        o(sv->c.ul);
+      } else
+        o(op);
+      return;
+    } else if (v == VT_LOCAL) {
+      op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul);
+      if (fr & VT_SYM || !op) {
+	o(0xE59F0000|(intr(r)<<12));
+	o(0xEA000000);
+	if(fr & VT_SYM) // needed ?
+	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+	o(sv->c.ul);
+	o(0xE08B0000|(intr(r)<<12)|intr(r));
+      } else
+	o(op);
+      return;
+    } else if(v == VT_CMP) {
+      o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12));
+      o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12));
+      return;
+    } else if (v == VT_JMP || v == VT_JMPI) {
+      int t;
+      t = v & 1;
+      o(0xE3A00000|(intr(r)<<12)|t);
+      o(0xEA000000);
+      gsym(sv->c.ul);
+      o(0xE3A00000|(intr(r)<<12)|(t^1));
+      return;
+    } else if (v < VT_CONST) {
+      if(is_float(ft))
+#ifdef TCC_ARM_VFP
+        o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
+#else
+	o(0xEE008180|(fpr(r)<<12)|fpr(v));
+#endif
+      else
+	o(0xE1A00000|(intr(r)<<12)|intr(v));
+      return;
+    }
+  }
+  error("load unimplemented!");
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+  SValue v1;
+  int v, ft, fc, fr, sign;
+  unsigned long op;
+
+  fr = sv->r;
+  ft = sv->type.t;
+  fc = sv->c.ul;
+
+  if(fc>=0)
+    sign=0;
+  else {
+    sign=1;
+    fc=-fc;
+  }
+  
+  v = fr & VT_VALMASK; 
+  if (fr & VT_LVAL || fr == VT_LOCAL) {
+    unsigned long base=0xb;
+    if(v < VT_CONST) {
+      base=intr(v);
+      v=VT_LOCAL;
+      fc=sign=0;
+    } else if(v == VT_CONST) {
+      v1.type.t = ft;
+      v1.r = fr&~VT_LVAL;
+      v1.c.ul = sv->c.ul;
+      v1.sym=sv->sym;
+      load(base=14, &v1);
+      fc=sign=0;
+      v=VT_LOCAL;   
+    }
+    if(v == VT_LOCAL) {
+       if(is_float(ft)) {
+	calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+        op=0xED000A00; /* fsts */
+        if(!sign) 
+          op|=0x800000; 
+        if ((ft & VT_BTYPE) != VT_FLOAT) 
+          op|=0x100;   /* fsts -> fstd */
+        o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+	op=0xED000100;
+	if(!sign)
+	  op|=0x800000;
+#if LDOUBLE_SIZE == 8
+	if ((ft & VT_BTYPE) != VT_FLOAT)
+	  op|=0x8000;
+#else
+	if ((ft & VT_BTYPE) == VT_DOUBLE)
+	  op|=0x8000;
+	if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	  op|=0x400000;
+#endif
+	o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+	return;
+      } else if((ft & VT_BTYPE) == VT_SHORT) {
+	calcaddr(&base,&fc,&sign,255,0);
+	op=0xE14000B0;
+	if(!sign)
+	  op|=0x800000;
+	o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+      } else {
+	calcaddr(&base,&fc,&sign,4095,0);
+	op=0xE5000000;
+	if(!sign)
+	  op|=0x800000;
+        if ((ft & VT_BTYPE) == VT_BYTE)
+          op|=0x400000;
+        o(op|(intr(r)<<12)|fc|(base<<16));
+      }
+      return;
+    }
+  }
+  error("store unimplemented");
+}
+
+static void gadd_sp(int val)
+{
+  stuff_const_harder(0xE28DD000,val);
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+  int r;
+  if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+    unsigned long x;
+    /* constant case */
+    x=encbranch(ind,ind+vtop->c.ul,0);
+    if(x) {
+      if (vtop->r & VT_SYM) {
+	/* relocation case */
+	greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
+      } else
+	put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
+      o(x|(is_jmp?0xE0000000:0xE1000000));
+    } else {
+      if(!is_jmp)
+	o(0xE28FE004); // add lr,pc,#4
+      o(0xE51FF004);   // ldr pc,[pc,#-4]
+      if (vtop->r & VT_SYM)
+	greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
+      o(vtop->c.ul);
+    }
+  } else {
+    /* otherwise, indirect call */
+    r = gv(RC_INT);
+    if(!is_jmp)
+      o(0xE1A0E00F);       // mov lr,pc
+    o(0xE1A0F000|intr(r)); // mov pc,r
+  }
+}
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+  int size, align, r, args_size, i;
+  Sym *func_sym;
+  signed char plan[4][2]={{-1,-1},{-1,-1},{-1,-1},{-1,-1}};
+  int todo=0xf, keep, plan2[4]={0,0,0,0};
+
+  r = vtop->r & VT_VALMASK;
+  if (r == VT_CMP || (r & ~1) == VT_JMP)
+    gv(RC_INT);
+#ifdef TCC_ARM_EABI
+  if((vtop[-nb_args].type.ref->type.t & VT_BTYPE) == VT_STRUCT
+     && type_size(&vtop[-nb_args].type, &align) <= 4) {
+    SValue tmp;
+    tmp=vtop[-nb_args];
+    vtop[-nb_args]=vtop[-nb_args+1];
+    vtop[-nb_args+1]=tmp;
+    --nb_args;
+  }
+  
+  vpushi(0);
+  vtop->type.t = VT_LLONG;
+  args_size = 0;
+  for(i = nb_args + 1 ; i-- ;) {
+    size = type_size(&vtop[-i].type, &align);
+    if(args_size & (align-1)) {
+      vpushi(0);
+      vtop->type.t = VT_VOID; /* padding */
+      vrott(i+2);
+      args_size += 4;
+      ++nb_args;
+    }
+    args_size += (size + 3) & -4;
+  }
+  vtop--;
+#endif
+  args_size = 0;
+  for(i = nb_args ; i-- && args_size < 16 ;) {
+    switch(vtop[-i].type.t & VT_BTYPE) {
+      case VT_STRUCT:
+      case VT_FLOAT:
+      case VT_DOUBLE:
+      case VT_LDOUBLE:
+      size = type_size(&vtop[-i].type, &align);
+        size = (size + 3) & -4;
+      args_size += size;
+        break;
+      default:
+      plan[nb_args-1-i][0]=args_size/4;
+      args_size += 4;
+      if ((vtop[-i].type.t & VT_BTYPE) == VT_LLONG && args_size < 16) {
+	plan[nb_args-1-i][1]=args_size/4;
+	args_size += 4;
+      }
+    }
+  }
+  args_size = keep = 0;
+  for(i = 0;i < nb_args; i++) {
+    vnrott(keep+1);
+    if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+      size = type_size(&vtop->type, &align);
+      /* align to stack align size */
+      size = (size + 3) & -4;
+      /* allocate the necessary size on stack */
+      gadd_sp(-size);
+      /* generate structure store */
+      r = get_reg(RC_INT);
+      o(0xE1A0000D|(intr(r)<<12));
+      vset(&vtop->type, r | VT_LVAL, 0);
+      vswap();
+      vstore();
+      vtop--;
+      args_size += size;
+    } else if (is_float(vtop->type.t)) {
+#ifdef TCC_ARM_VFP
+      r=vfpr(gv(RC_FLOAT))<<12;
+      size=4;
+      if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
+      {
+        size=8;
+        r|=0x101; /* fstms -> fstmd */
+      }
+      o(0xED2D0A01+r);
+#else
+      r=fpr(gv(RC_FLOAT))<<12;
+      if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
+        size = 4;
+      else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+        size = 8;
+      else
+        size = LDOUBLE_SIZE;
+      
+      if (size == 12)
+	r|=0x400000;
+      else if(size == 8)
+	r|=0x8000;
+
+      o(0xED2D0100|r|(size>>2));
+#endif
+      vtop--;
+      args_size += size;
+    } else {
+      int s;
+      /* simple type (currently always same size) */
+      /* XXX: implicit cast ? */
+      size=4;
+      if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+	lexpand_nr();
+	s=RC_INT;
+	if(nb_args-i<5 && plan[nb_args-i-1][1]!=-1) {
+	  s=regmask(plan[nb_args-i-1][1]);
+	  todo&=~(1<<plan[nb_args-i-1][1]);
+	}
+	if(s==RC_INT) {
+	  r = gv(s);
+	  o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
+	  vtop--;
+	} else {
+	  plan2[keep]=s;
+	  keep++;
+          vswap();
+	}
+	size = 8;
+      }
+      s=RC_INT;
+      if(nb_args-i<5 && plan[nb_args-i-1][0]!=-1) {
+        s=regmask(plan[nb_args-i-1][0]);
+	todo&=~(1<<plan[nb_args-i-1][0]);
+      }
+#ifdef TCC_ARM_EABI
+      if(vtop->type.t == VT_VOID) {
+        if(s == RC_INT)
+          o(0xE24DD004); /* sub sp,sp,#4 */
+        vtop--;
+      } else
+#endif      
+      if(s == RC_INT) {
+	r = gv(s);
+	o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */
+	vtop--;
+      } else {
+	plan2[keep]=s;
+	keep++;
+      }
+      args_size += size;
+    }
+  }
+  for(i=keep;i--;) {
+    gv(plan2[i]);
+    vrott(keep);
+  }
+save_regs(keep); /* save used temporary registers */
+  keep++;
+  if(args_size) {
+    int n;
+    n=args_size/4;
+    if(n>4)
+      n=4;
+    todo&=((1<<n)-1);
+    if(todo) {
+      int i;
+      o(0xE8BD0000|todo);
+      for(i=0;i<4;i++)
+	if(todo&(1<<i)) {
+	  vpushi(0);
+	  vtop->r=i;
+	  keep++;
+	}
+    }
+    args_size-=n*4;
+  }
+  vnrott(keep);
+  func_sym = vtop->type.ref;
+  gcall_or_jmp(0);
+  if (args_size)
+      gadd_sp(args_size);
+#ifdef TCC_ARM_EABI
+  if((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT
+     && type_size(&vtop->type.ref->type, &align) <= 4)
+  {
+    store(REG_IRET,vtop-keep);
+    ++keep;
+  }
+#ifdef TCC_ARM_VFP
+  else if(is_float(vtop->type.ref->type.t)) {
+    if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
+      o(0xEE000A10); /* fmsr s0,r0 */
+    } else {
+      o(0xEE000B10); /* fmdlr d0,r0 */
+      o(0xEE201B10); /* fmdhr d0,r1 */
+    }
+  }
+#endif
+#endif
+  vtop-=keep;
+  leaffunc = 0;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+  Sym *sym,*sym2;
+  int n,addr,size,align;
+
+  sym = func_type->ref;
+  func_vt = sym->type;
+  
+  n = 0;
+  addr = 0;
+  if((func_vt.t & VT_BTYPE) == VT_STRUCT
+     && type_size(&func_vt,&align) > 4)
+  {
+    func_vc = addr;
+    addr += 4;
+    n++;
+  }
+  for(sym2=sym->next;sym2 && n<4;sym2=sym2->next) {
+    size = type_size(&sym2->type, &align);
+    n += (size + 3) / 4;
+  }
+  o(0xE1A0C00D); /* mov ip,sp */
+  if(func_type->ref->c == FUNC_ELLIPSIS)
+    n=4;
+  if(n) {
+    if(n>4)
+      n=4;
+#ifdef TCC_ARM_EABI
+    n=(n+1)&-2;
+#endif
+    o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
+  }
+  o(0xE92D5800); /* save fp, ip, lr */
+  o(0xE28DB00C); /* add fp, sp, #12 */
+  func_sub_sp_offset = ind;
+  o(0xE1A00000); /* nop, leave space for stack adjustment */
+  while ((sym = sym->next)) {
+    CType *type;
+    type = &sym->type;
+    size = type_size(type, &align);
+    size = (size + 3) & -4;
+#ifdef TCC_ARM_EABI
+    addr = (addr + align - 1) & -align;
+#endif
+    sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr);
+    addr += size;
+  }
+  last_itod_magic=0;
+  leaffunc = 1;
+  loc = -12;
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+  unsigned long x;
+  int diff;
+#ifdef TCC_ARM_EABI
+  if(is_float(func_vt.t)) {
+    if((func_vt.t & VT_BTYPE) == VT_FLOAT)
+      o(0xEE100A10); /* fmrs r0, s0 */
+    else {
+      o(0xEE100B10); /* fmrdl r0, d0 */
+      o(0xEE301B10); /* fmrdh r1, d0 */
+    }
+  }
+#endif
+  o(0xE91BA800); /* restore fp, sp, pc */
+  diff = (-loc + 3) & -4;
+#ifdef TCC_ARM_EABI
+  if(!leaffunc)
+    diff = (diff + 7) & -8;
+#endif
+  if(diff > 12) {
+    x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
+    if(x)
+      *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = x;
+    else {
+      unsigned long addr;
+      addr=ind;
+      o(0xE59FC004); /* ldr ip,[pc+4] */
+      o(0xE04BD00C); /* sub sp,fp,ip  */
+      o(0xE1A0F00E); /* mov pc,lr */
+      o(diff);
+      *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
+    }
+  }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+  int r;
+  r=ind;
+  o(0xE0000000|encbranch(r,t,1));
+  return r;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+  gjmp(a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+  int v, r;
+  unsigned long op;
+  v = vtop->r & VT_VALMASK;
+  r=ind;
+  if (v == VT_CMP) {
+    op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
+    op|=encbranch(r,t,1);
+    o(op);
+    t=r;
+  } else if (v == VT_JMP || v == VT_JMPI) {
+    if ((v & 1) == inv) {
+      if(!vtop->c.i)
+	vtop->c.i=t;
+      else {
+	unsigned long *x;
+	int p,lp;
+	if(t) {
+          p = vtop->c.i;
+          do {
+	    p = decbranch(lp=p);
+          } while(p);
+	  x = (unsigned long *)(cur_text_section->data + lp);
+	  *x &= 0xff000000;
+	  *x |= encbranch(lp,t,1);
+	}
+	t = vtop->c.i;
+      }
+    } else {
+      t = gjmp(t);
+      gsym(vtop->c.i);
+    }
+  } else {
+    if (is_float(vtop->type.t)) {
+      r=gv(RC_FLOAT);
+#ifdef TCC_ARM_VFP
+      o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */
+      o(0xEEF1FA10); /* fmstat */
+#else
+      o(0xEE90F118|(fpr(r)<<16));
+#endif
+      vtop->r = VT_CMP;
+      vtop->c.i = TOK_NE;
+      return gtst(inv, t);
+    } else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+      /* constant jmp optimization */
+      if ((vtop->c.i != 0) != inv) 
+	t = gjmp(t);
+    } else {
+      v = gv(RC_INT);
+      o(0xE3300000|(intr(v)<<16));
+      vtop->r = VT_CMP;
+      vtop->c.i = TOK_NE;
+      return gtst(inv, t);
+    }   
+  }
+  vtop--;
+  return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+  int c, func = 0;
+  unsigned long opc = 0,r,fr;
+  unsigned short retreg = REG_IRET;
+
+  c=0;
+  switch(op) {
+    case '+':
+      opc = 0x8;
+      c=1;
+      break;
+    case TOK_ADDC1: /* add with carry generation */
+      opc = 0x9;
+      c=1;
+      break;
+    case '-':
+      opc = 0x4;
+      c=1;
+      break;
+    case TOK_SUBC1: /* sub with carry generation */
+      opc = 0x5;
+      c=1;
+      break;
+    case TOK_ADDC2: /* add with carry use */
+      opc = 0xA;
+      c=1;
+      break;
+    case TOK_SUBC2: /* sub with carry use */
+      opc = 0xC;
+      c=1;
+      break;
+    case '&':
+      opc = 0x0;
+      c=1;
+      break;
+    case '^':
+      opc = 0x2;
+      c=1;
+      break;
+    case '|':
+      opc = 0x18;
+      c=1;
+      break;
+    case '*':
+      gv2(RC_INT, RC_INT);
+      r = vtop[-1].r;
+      fr = vtop[0].r;
+      vtop--;
+      o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
+      return;
+    case TOK_SHL:
+      opc = 0;
+      c=2;
+      break;
+    case TOK_SHR:
+      opc = 1;
+      c=2;
+      break;
+    case TOK_SAR:
+      opc = 2;
+      c=2;
+      break;
+    case '/':
+    case TOK_PDIV:
+      func=TOK___divsi3;
+      c=3;
+      break;
+    case TOK_UDIV:
+      func=TOK___udivsi3;
+      c=3;
+      break;
+    case '%':
+#ifdef TCC_ARM_EABI
+      func=TOK___aeabi_idivmod;
+      retreg=REG_LRET;
+#else
+      func=TOK___modsi3;
+#endif
+      c=3;
+      break;
+    case TOK_UMOD:
+#ifdef TCC_ARM_EABI
+      func=TOK___aeabi_uidivmod;
+      retreg=REG_LRET;
+#else
+      func=TOK___umodsi3;
+#endif
+      c=3;
+      break;
+    case TOK_UMULL:
+      gv2(RC_INT, RC_INT);
+      r=intr(vtop[-1].r2=get_reg(RC_INT));
+      c=vtop[-1].r;
+      vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
+      vtop--;
+      o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
+      return;
+    default:
+      opc = 0x15;
+      c=1;
+      break;
+  }
+  switch(c) {
+    case 1:
+      if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	if(opc == 4 || opc == 5 || opc == 0xc) {
+	  vswap();
+	  opc|=2; // sub -> rsb
+	}
+      }
+      if ((vtop->r & VT_VALMASK) == VT_CMP ||
+          (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+        gv(RC_INT);
+      vswap();
+      c=intr(gv(RC_INT));
+      vswap();
+      opc=0xE0000000|(opc<<20)|(c<<16);
+      if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	unsigned long x;
+	x=stuff_const(opc|0x2000000,vtop->c.i);
+	if(x) {
+	  r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+	  o(x|(r<<12));
+	  goto done;
+	}
+      }
+      fr=intr(gv(RC_INT));
+      r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+      o(opc|(r<<12)|fr);
+done:
+      vtop--;
+      if (op >= TOK_ULT && op <= TOK_GT) {
+        vtop->r = VT_CMP;
+        vtop->c.i = op;
+      }
+      break;
+    case 2:
+      opc=0xE1A00000|(opc<<5);
+      if ((vtop->r & VT_VALMASK) == VT_CMP ||
+          (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+        gv(RC_INT);
+      vswap();
+      r=intr(gv(RC_INT));
+      vswap();
+      opc|=r;
+      if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+	c = vtop->c.i & 0x1f;
+	o(opc|(c<<7)|(fr<<12));
+      } else {
+        fr=intr(gv(RC_INT));
+	c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+	o(opc|(c<<12)|(fr<<8)|0x10);
+      }
+      vtop--;
+      break;
+    case 3:
+      vpush_global_sym(&func_old_type, func);
+      vrott(3);
+      gfunc_call(2);
+      vpushi(0);
+      vtop->r = retreg;
+      break;
+    default:
+      error("gen_opi %i unimplemented!",op);
+  }
+}
+
+#ifdef TCC_ARM_VFP
+static int is_zero(int i)
+{
+  if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+    return 0;
+  if (vtop[i].type.t == VT_FLOAT)
+    return (vtop[i].c.f == 0.f);
+  else if (vtop[i].type.t == VT_DOUBLE)
+    return (vtop[i].c.d == 0.0);
+  return (vtop[i].c.ld == 0.l);
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ *    two operands are guaranted to have the same floating point type */
+void gen_opf(int op)
+{
+  unsigned long x;
+  int fneg=0,r;
+  x=0xEE000A00|T2CPR(vtop->type.t);
+  switch(op) {
+    case '+':
+      if(is_zero(-1))
+        vswap();
+      if(is_zero(0)) {
+        vtop--;
+        return;
+      }
+      x|=0x300000;
+      break;
+    case '-':
+      x|=0x300040;
+      if(is_zero(0)) {
+        vtop--;
+        return;
+      }
+      if(is_zero(-1)) {
+        x|=0x810000; /* fsubX -> fnegX */
+        vswap();
+        vtop--;
+        fneg=1;
+      }
+      break;
+    case '*':
+      x|=0x200000;
+      break;
+    case '/':
+      x|=0x800000;
+      break;
+    default:
+      if(op < TOK_ULT && op > TOK_GT) {
+        error("unknown fp op %x!",op);
+        return;
+      }
+      if(is_zero(-1)) {
+        vswap();
+        switch(op) {
+          case TOK_LT: op=TOK_GT; break;
+          case TOK_GE: op=TOK_ULE; break;
+          case TOK_LE: op=TOK_GE; break;
+          case TOK_GT: op=TOK_ULT; break;
+        }
+      }
+      x|=0xB40040; /* fcmpX */
+      if(op!=TOK_EQ && op!=TOK_NE)
+        x|=0x80; /* fcmpX -> fcmpeX */
+      if(is_zero(0)) {
+        vtop--;
+        o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
+      } else {
+        x|=vfpr(gv(RC_FLOAT));
+        vswap();
+        o(x|(vfpr(gv(RC_FLOAT))<<12));
+        vtop--;
+      }
+      o(0xEEF1FA10); /* fmstat */
+
+      switch(op) {
+        case TOK_LE: op=TOK_ULE; break;
+        case TOK_LT: op=TOK_ULT; break;
+        case TOK_UGE: op=TOK_GE; break;
+        case TOK_UGT: op=TOK_GT; break;
+      }
+      
+      vtop->r = VT_CMP;
+      vtop->c.i = op;
+      return;
+  }
+  r=gv(RC_FLOAT);
+  x|=vfpr(r);
+  r=regmask(r);
+  if(!fneg) {
+    int r2;
+    vswap();
+    r2=gv(RC_FLOAT);
+    x|=vfpr(r2)<<16;
+    r|=regmask(r2);
+  }
+  vtop->r=get_reg_ex(RC_FLOAT,r);
+  if(!fneg)
+    vtop--;
+  o(x|(vfpr(vtop->r)<<12));
+}
+
+#else
+static int is_fconst()
+{
+  long double f;
+  int r;
+  if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+    return 0;
+  if (vtop->type.t == VT_FLOAT)
+    f = vtop->c.f;
+  else if (vtop->type.t == VT_DOUBLE)
+    f = vtop->c.d;
+  else
+    f = vtop->c.ld;
+  if(!ieee_finite(f))
+    return 0;
+  r=0x8;
+  if(f<0.0) {
+    r=0x18;
+    f=-f;
+  }
+  if(f==0.0)
+    return r;
+  if(f==1.0)
+    return r|1;
+  if(f==2.0)
+    return r|2;
+  if(f==3.0)
+    return r|3;
+  if(f==4.0)
+    return r|4;
+  if(f==5.0)
+    return r|5;
+  if(f==0.5)
+    return r|6;
+  if(f==10.0)
+    return r|7;
+  return 0;
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranted to have the same floating point type */
+void gen_opf(int op)
+{
+  unsigned long x;
+  int r,r2,c1,c2;
+  //fputs("gen_opf\n",stderr);
+  vswap();
+  c1 = is_fconst();
+  vswap();
+  c2 = is_fconst();
+  x=0xEE000100;
+#if LDOUBLE_SIZE == 8
+  if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
+    x|=0x80;
+#else
+  if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+    x|=0x80;
+  else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
+    x|=0x80000;
+#endif
+  switch(op)
+  {
+    case '+':
+      if(!c2) {
+	vswap();
+	c2=c1;
+      }
+      vswap();
+      r=fpr(gv(RC_FLOAT));
+      vswap();
+      if(c2) {
+	if(c2>0xf)
+	  x|=0x200000; // suf
+	r2=c2&0xf;
+      } else {
+	r2=fpr(gv(RC_FLOAT));
+      }
+      break;
+    case '-':
+      if(c2) {
+	if(c2<=0xf)
+	  x|=0x200000; // suf
+	r2=c2&0xf;
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else if(c1 && c1<=0xf) {
+	x|=0x300000; // rsf
+	r2=c1;
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else {
+	x|=0x200000; // suf
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	r2=fpr(gv(RC_FLOAT));
+      }
+      break;
+    case '*':
+      if(!c2 || c2>0xf) {
+	vswap();
+	c2=c1;
+      }
+      vswap();
+      r=fpr(gv(RC_FLOAT));
+      vswap();
+      if(c2 && c2<=0xf)
+	r2=c2;
+      else
+	r2=fpr(gv(RC_FLOAT));
+      x|=0x100000; // muf
+      break;
+    case '/':
+      if(c2 && c2<=0xf) {
+	x|=0x400000; // dvf
+	r2=c2;
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else if(c1 && c1<=0xf) {
+	x|=0x500000; // rdf
+	r2=c1;
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else {
+	x|=0x400000; // dvf
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	r2=fpr(gv(RC_FLOAT));
+      }     
+      break;
+    default:
+      if(op >= TOK_ULT && op <= TOK_GT) {
+	x|=0xd0f110; // cmfe
+/* bug (intention?) in Linux FPU emulator
+   doesn't set carry if equal */
+	switch(op) {
+	  case TOK_ULT:
+	  case TOK_UGE:
+	  case TOK_ULE:
+	  case TOK_UGT:
+            error("unsigned comparision on floats?");
+	    break;
+	  case TOK_LT:
+            op=TOK_Nset;
+	    break;
+	  case TOK_LE:
+            op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
+	    break;
+	  case TOK_EQ:
+	  case TOK_NE:
+	    x&=~0x400000; // cmfe -> cmf
+	    break;
+	}
+	if(c1 && !c2) {
+	  c2=c1;
+	  vswap();
+	  switch(op) {
+            case TOK_Nset:
+              op=TOK_GT;
+	      break;
+            case TOK_GE:
+	      op=TOK_ULE;
+	      break;
+	    case TOK_ULE:
+              op=TOK_GE;
+	      break;
+            case TOK_GT:
+              op=TOK_Nset;
+	      break;
+	  }
+	}
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	if(c2) {
+	  if(c2>0xf)
+	    x|=0x200000;
+	  r2=c2&0xf;
+	} else {
+	  r2=fpr(gv(RC_FLOAT));
+	}
+	vtop[-1].r = VT_CMP;
+	vtop[-1].c.i = op;
+      } else {
+        error("unknown fp op %x!",op);
+	return;
+      }
+  }
+  if(vtop[-1].r == VT_CMP)
+    c1=15;
+  else {
+    c1=vtop->r;
+    if(r2&0x8)
+      c1=vtop[-1].r;
+    vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
+    c1=fpr(vtop[-1].r);
+  }
+  vtop--;
+  o(x|(r<<16)|(c1<<12)|r2);
+}
+#endif
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof1(int t)
+{
+  int r,r2,bt;
+  bt=vtop->type.t & VT_BTYPE;
+  if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
+#ifndef TCC_ARM_VFP
+    unsigned int dsize=0;
+#endif
+    r=intr(gv(RC_INT));
+#ifdef TCC_ARM_VFP
+    r2=vfpr(vtop->r=get_reg(RC_FLOAT));
+    o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
+    r2<<=12;
+    if(!(vtop->type.t & VT_UNSIGNED))
+      r2|=0x80;                /* fuitoX -> fsituX */
+    o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
+#else
+    r2=fpr(vtop->r=get_reg(RC_FLOAT));
+    if((t & VT_BTYPE) != VT_FLOAT)
+      dsize=0x80;    /* flts -> fltd */
+    o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
+    if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
+      unsigned int off=0;
+      o(0xE3500000|(r<<12));        /* cmp */
+      r=fpr(get_reg(RC_FLOAT));
+      if(last_itod_magic) {
+	off=ind+8-last_itod_magic;
+	off/=4;
+	if(off>255)
+	  off=0;
+      }
+      o(0xBD1F0100|(r<<12)|off);    /* ldflts */
+      if(!off) {
+        o(0xEA000000);              /* b */
+        last_itod_magic=ind;
+        o(0x4F800000);              /* 4294967296.0f */
+      }
+      o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
+    }
+#endif
+    return;
+  } else if(bt == VT_LLONG) {
+    int func;
+    CType *func_type = 0;
+    if((t & VT_BTYPE) == VT_FLOAT) {
+      func_type = &func_float_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundisf;
+      else
+        func=TOK___floatdisf;
+#if LDOUBLE_SIZE != 8
+    } else if((t & VT_BTYPE) == VT_LDOUBLE) {
+      func_type = &func_ldouble_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundixf;
+      else
+        func=TOK___floatdixf;
+    } else if((t & VT_BTYPE) == VT_DOUBLE) {
+#else
+    } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
+#endif
+      func_type = &func_double_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundidf;
+      else
+        func=TOK___floatdidf;
+    }
+    if(func_type) {
+      vpush_global_sym(func_type, func);
+      vswap();
+      gfunc_call(1);
+      vpushi(0);
+      vtop->r=TREG_F0;
+      return;
+    }
+  }
+  error("unimplemented gen_cvt_itof %x!",vtop->type.t);
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+  int r,r2,u,func=0;
+  u=t&VT_UNSIGNED;
+  t&=VT_BTYPE;
+  r2=vtop->type.t & VT_BTYPE;
+  if(t==VT_INT) {
+#ifdef TCC_ARM_VFP
+    r=vfpr(gv(RC_FLOAT));
+    u=u?0:0x10000;
+    o(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */
+    r2=intr(vtop->r=get_reg(RC_INT));
+    o(0xEE100A10|(r<<16)|(r2<<12));
+    return;
+#else
+    if(u) {
+      if(r2 == VT_FLOAT)
+        func=TOK___fixunssfsi;
+#if LDOUBLE_SIZE != 8
+      else if(r2 == VT_LDOUBLE)
+	func=TOK___fixunsxfsi;
+      else if(r2 == VT_DOUBLE)
+#else
+      else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+	func=TOK___fixunsdfsi;
+    } else {
+      r=fpr(gv(RC_FLOAT));
+      r2=intr(vtop->r=get_reg(RC_INT));
+      o(0xEE100170|(r2<<12)|r);
+      return;
+    }
+#endif
+  } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
+    if(r2 == VT_FLOAT)
+      func=TOK___fixsfdi;
+#if LDOUBLE_SIZE != 8
+    else if(r2 == VT_LDOUBLE)
+      func=TOK___fixxfdi;
+    else if(r2 == VT_DOUBLE)
+#else
+    else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+      func=TOK___fixdfdi;
+  }
+  if(func) {
+    vpush_global_sym(&func_old_type, func);
+    vswap();
+    gfunc_call(1);
+    vpushi(0);
+    if(t == VT_LLONG)
+      vtop->r2 = REG_LRET;
+    vtop->r = REG_IRET;
+    return;
+  }
+  error("unimplemented gen_cvt_ftoi!");
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+#ifdef TCC_ARM_VFP
+  if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
+    int r=vfpr(gv(RC_FLOAT));
+    o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
+  }
+#else
+  /* all we have to do on i386 and FPA ARM is to put the float in a register */
+  gv(RC_FLOAT);
+#endif
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+  gcall_or_jmp(1);
+  vtop--;
+}
+
+/* end of ARM code generator */
+/*************************************************************/
+
diff --git a/tinyc/c67-gen.c b/tinyc/c67-gen.c
new file mode 100755
index 000000000..04f8a12b7
--- /dev/null
+++ b/tinyc/c67-gen.c
@@ -0,0 +1,2548 @@
+/*
+ *  TMS320C67xx code generator for TCC
+ * 
+ *  Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+//#define ASSEMBLY_LISTING_C67
+
+/* number of available registers */
+#define NB_REGS            24
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001	/* generic integer register */
+#define RC_FLOAT   0x0002	/* generic float register */
+#define RC_EAX     0x0004
+#define RC_ST0     0x0008
+#define RC_ECX     0x0010
+#define RC_EDX     0x0020
+#define RC_INT_BSIDE  0x00000040	/* generic integer register  on b side */
+#define RC_C67_A4     0x00000100
+#define RC_C67_A5     0x00000200
+#define RC_C67_B4     0x00000400
+#define RC_C67_B5     0x00000800
+#define RC_C67_A6     0x00001000
+#define RC_C67_A7     0x00002000
+#define RC_C67_B6     0x00004000
+#define RC_C67_B7     0x00008000
+#define RC_C67_A8     0x00010000
+#define RC_C67_A9     0x00020000
+#define RC_C67_B8     0x00040000
+#define RC_C67_B9     0x00080000
+#define RC_C67_A10    0x00100000
+#define RC_C67_A11    0x00200000
+#define RC_C67_B10    0x00400000
+#define RC_C67_B11    0x00800000
+#define RC_C67_A12    0x01000000
+#define RC_C67_A13    0x02000000
+#define RC_C67_B12    0x04000000
+#define RC_C67_B13    0x08000000
+#define RC_IRET    RC_C67_A4	/* function return: integer register */
+#define RC_LRET    RC_C67_A5	/* function return: second integer register */
+#define RC_FRET    RC_C67_A4	/* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_EAX = 0,		// really A2
+    TREG_ECX,			// really A3
+    TREG_EDX,			// really B0
+    TREG_ST0,			// really B1
+    TREG_C67_A4,
+    TREG_C67_A5,
+    TREG_C67_B4,
+    TREG_C67_B5,
+    TREG_C67_A6,
+    TREG_C67_A7,
+    TREG_C67_B6,
+    TREG_C67_B7,
+    TREG_C67_A8,
+    TREG_C67_A9,
+    TREG_C67_B8,
+    TREG_C67_B9,
+    TREG_C67_A10,
+    TREG_C67_A11,
+    TREG_C67_B10,
+    TREG_C67_B11,
+    TREG_C67_A12,
+    TREG_C67_A13,
+    TREG_C67_B12,
+    TREG_C67_B13,
+};
+
+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
+   are directly pushed on stack. */
+//#define FUNC_STRUCT_PARAM_AS_PTR
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+/******************************************************/
+/* ELF defines */
+
+#define EM_TCC_TARGET EM_C60
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_C60_32
+#define R_JMP_SLOT  R_C60_JMP_SLOT
+#define R_COPY      R_C60_COPY
+
+#define ELF_START_ADDR 0x00000400
+#define ELF_PAGE_SIZE  0x1000
+
+/******************************************************/
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+
+static BOOL C67_invert_test;
+static int C67_compare_reg;
+
+#ifdef ASSEMBLY_LISTING_C67
+FILE *f = NULL;
+#endif
+
+
+void C67_g(int c)
+{
+    int ind1;
+
+#ifdef ASSEMBLY_LISTING_C67
+    fprintf(f, " %08X", c);
+#endif
+    ind1 = ind + 4;
+    if (ind1 > (int) cur_text_section->data_allocated)
+	section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c & 0xff;
+    cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
+    cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
+    cur_text_section->data[ind + 3] = (c >> 24) & 0xff;
+    ind = ind1;
+}
+
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+    int n, *ptr;
+    while (t) {
+	ptr = (int *) (cur_text_section->data + t);
+	{
+	    Sym *sym;
+
+	    // extract 32 bit address from MVKH/MVKL
+	    n = ((*ptr >> 7) & 0xffff);
+	    n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
+
+	    // define a label that will be relocated
+
+	    sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+	    greloc(cur_text_section, sym, t, R_C60LO16);
+	    greloc(cur_text_section, sym, t + 4, R_C60HI16);
+
+	    // clear out where the pointer was
+
+	    *ptr &= ~(0xffff << 7);
+	    *(ptr + 1) &= ~(0xffff << 7);
+	}
+	t = n;
+    }
+}
+
+void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+// these are regs that tcc doesn't really know about, 
+// but asign them unique values so the mapping routines
+// can distinquish them
+
+#define C67_A0 105
+#define C67_SP 106
+#define C67_B3 107
+#define C67_FP 108
+#define C67_B2 109
+#define C67_CREG_ZERO -1	// Special code for no condition reg test
+
+
+int ConvertRegToRegClass(int r)
+{
+    // only works for A4-B13
+
+    return RC_C67_A4 << (r - TREG_C67_A4);
+}
+
+
+// map TCC reg to C67 reg number
+
+int C67_map_regn(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x2;		// A2
+    else if (r == 1)		// normal tcc regs
+	return 3;		// A3
+    else if (r == 2)		// normal tcc regs
+	return 0;		// B0
+    else if (r == 3)		// normal tcc regs
+	return 1;		// B1
+    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs
+	return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2;
+    else if (r == C67_A0)
+	return 0;		// set to A0 (offset reg)
+    else if (r == C67_B2)
+	return 2;		// set to B2 (offset reg)
+    else if (r == C67_B3)
+	return 3;		// set to B3 (return address reg)
+    else if (r == C67_SP)
+	return 15;		// set to SP (B15) (offset reg)
+    else if (r == C67_FP)
+	return 15;		// set to FP (A15) (offset reg)
+    else if (r == C67_CREG_ZERO)
+	return 0;		// Special code for no condition reg test
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+// mapping from tcc reg number to 
+// C67 register to condition code field
+//
+// valid condition code regs are:
+//
+// tcc reg 2 ->B0 -> 1
+// tcc reg 3 ->B1 -> 2
+// tcc reg 0 -> A2 -> 5
+// tcc reg 1 -> A3 -> X
+// tcc reg      B2 -> 3
+
+int C67_map_regc(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x5;
+    else if (r == 2)		// normal tcc regs
+	return 0x1;
+    else if (r == 3)		// normal tcc regs
+	return 0x2;
+    else if (r == C67_B2)	// normal tcc regs
+	return 0x3;
+    else if (r == C67_CREG_ZERO)
+	return 0;		// Special code for no condition reg test
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+
+// map TCC reg to C67 reg side A or B
+
+int C67_map_regs(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x0;
+    else if (r == 1)		// normal tcc regs
+	return 0x0;
+    else if (r == 2)		// normal tcc regs
+	return 0x1;
+    else if (r == 3)		// normal tcc regs
+	return 0x1;
+    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs
+	return (r & 2) >> 1;
+    else if (r == C67_A0)
+	return 0;		// set to A side 
+    else if (r == C67_B2)
+	return 1;		// set to B side 
+    else if (r == C67_B3)
+	return 1;		// set to B side
+    else if (r == C67_SP)
+	return 0x1;		// set to SP (B15) B side 
+    else if (r == C67_FP)
+	return 0x0;		// set to FP (A15) A side 
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+int C67_map_S12(char *s)
+{
+    if (strstr(s, ".S1") != NULL)
+	return 0;
+    else if (strcmp(s, ".S2"))
+	return 1;
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+int C67_map_D12(char *s)
+{
+    if (strstr(s, ".D1") != NULL)
+	return 0;
+    else if (strcmp(s, ".D2"))
+	return 1;
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+
+
+void C67_asm(char *s, int a, int b, int c)
+{
+    BOOL xpath;
+
+#ifdef ASSEMBLY_LISTING_C67
+    if (!f) {
+	f = fopen("TCC67_out.txt", "wt");
+    }
+    fprintf(f, "%04X ", ind);
+#endif
+
+    if (strstr(s, "MVKL") == s) {
+	C67_g((C67_map_regn(b) << 23) |
+	      ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));
+    } else if (strstr(s, "MVKH") == s) {
+	C67_g((C67_map_regn(b) << 23) |
+	      (((a >> 16) & 0xffff) << 7) |
+	      (0x1a << 2) | (C67_map_regs(b) << 1));
+    } else if (strstr(s, "STW.D SP POST DEC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//SP B15
+	      (2 << 13) |	//ucst5 (must keep 8 byte boundary !!)
+	      (0xa << 9) |	//mode a = post dec ucst
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (1 << 7) |	//y D1/D2 use B side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D +*") == s) {
+	ALWAYS_ASSERT(c < 32);
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (c << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D SP PRE INC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg B15
+	      (2 << 13) |	//ucst5 (must keep 8 byte boundary)
+	      (9 << 9) |	//mode 9 = pre inc ucst5
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (1 << 7) |	//y D1/D2  B side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D SP PRE INC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg B15
+	      (1 << 13) |	//ucst5 (must keep 8 byte boundary)
+	      (9 << 9) |	//mode 9 = pre inc ucst5
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (1 << 7) |	//y D1/D2  B side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (0 << 7) |	//y D1/D2  A side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (4 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (2 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (0 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (1 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDH.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (4 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDB.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (2 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDHU.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (0 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDBU.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (1 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D +*") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (1 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLTSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x3a << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x39 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x38 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    }
+
+    else if (strstr(s, "CMPLTDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x2a << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x29 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x28 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLT") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x57 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGT") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x47 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQ") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x53 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLTU") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x5f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTU") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x4f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "B DISP") == s) {
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//z
+	      (a << 7) |	//cnst
+	      (0x4 << 2) |	//opcode fixed
+	      (0 << 1) |	//S0/S1
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "B.") == s) {
+	xpath = C67_map_regs(c) ^ 1;
+
+	C67_g((C67_map_regc(b) << 29) |	//creg
+	      (a << 28) |	//inv
+	      (0 << 23) |	//dst
+	      (C67_map_regn(c) << 18) |	//src2
+	      (0 << 13) |	//
+	      (xpath << 12) |	//x cross path if !B side
+	      (0xd << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (1 << 1) |	//must be S2
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MV.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 (cst5)
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x2 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SPTRUNC.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0xb << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "DPTRUNC.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2   WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x1 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2   
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x4a << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTSPU.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2  
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x49 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2  
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x39 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTDPU.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2   WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x3b << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SPDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x2 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "DPSP.L") == s) {
+	ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2 WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (0 << 12) |	//x cross path if opposite sides
+	      (0x9 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADD.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x3 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUB.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "OR.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "AND.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7b << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "XOR.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x6f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADDSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x10 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADDDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x18 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUBSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x11 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUBDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x19 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYSP.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x1c << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYDP.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x0e << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYI.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 (cst5)
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x4 << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHR.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x37 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHRU.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x27 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHL.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x33 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "||ADDK") == s) {
+	xpath = 0;		// no xpath required just use the side of the src/dst
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(b) << 23) |	//dst
+	      (a << 07) |	//scst16
+	      (0x14 << 2) |	//opcode fixed
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (1 << 0));	//parallel
+    } else if (strstr(s, "ADDK") == s) {
+	xpath = 0;		// no xpath required just use the side of the src/dst
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(b) << 23) |	//dst
+	      (a << 07) |	//scst16
+	      (0x14 << 2) |	//opcode fixed
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "NOP") == s) {
+	C67_g(((a - 1) << 13) |	//no of cycles
+	      (0 << 0));	//parallel
+    } else
+	ALWAYS_ASSERT(FALSE);
+
+#ifdef ASSEMBLY_LISTING_C67
+    fprintf(f, " %s %d %d %d\n", s, a, b, c);
+#endif
+
+}
+
+//r=reg to load, fr=from reg, symbol for relocation, constant
+
+void C67_MVKL(int r, int fc)
+{
+    C67_asm("MVKL.", fc, r, 0);
+}
+
+void C67_MVKH(int r, int fc)
+{
+    C67_asm("MVKH.", fc, r, 0);
+}
+
+void C67_STB_SP_A0(int r)
+{
+    C67_asm("STB.D *+SP[A0]", r, 0, 0);	// STB  r,*+SP[A0]
+}
+
+void C67_STH_SP_A0(int r)
+{
+    C67_asm("STH.D *+SP[A0]", r, 0, 0);	// STH  r,*+SP[A0]
+}
+
+void C67_STW_SP_A0(int r)
+{
+    C67_asm("STW.D *+SP[A0]", r, 0, 0);	// STW  r,*+SP[A0]
+}
+
+void C67_STB_PTR(int r, int r2)
+{
+    C67_asm("STB.D *", r, r2, 0);	// STB  r, *r2
+}
+
+void C67_STH_PTR(int r, int r2)
+{
+    C67_asm("STH.D *", r, r2, 0);	// STH  r, *r2
+}
+
+void C67_STW_PTR(int r, int r2)
+{
+    C67_asm("STW.D *", r, r2, 0);	// STW  r, *r2
+}
+
+void C67_STW_PTR_PRE_INC(int r, int r2, int n)
+{
+    C67_asm("STW.D +*", r, r2, n);	// STW  r, *+r2
+}
+
+void C67_PUSH(int r)
+{
+    C67_asm("STW.D SP POST DEC", r, 0, 0);	// STW  r,*SP--
+}
+
+void C67_LDW_SP_A0(int r)
+{
+    C67_asm("LDW.D *+SP[A0]", r, 0, 0);	// LDW  *+SP[A0],r
+}
+
+void C67_LDDW_SP_A0(int r)
+{
+    C67_asm("LDDW.D *+SP[A0]", r, 0, 0);	// LDDW  *+SP[A0],r
+}
+
+void C67_LDH_SP_A0(int r)
+{
+    C67_asm("LDH.D *+SP[A0]", r, 0, 0);	// LDH  *+SP[A0],r
+}
+
+void C67_LDB_SP_A0(int r)
+{
+    C67_asm("LDB.D *+SP[A0]", r, 0, 0);	// LDB  *+SP[A0],r
+}
+
+void C67_LDHU_SP_A0(int r)
+{
+    C67_asm("LDHU.D *+SP[A0]", r, 0, 0);	// LDHU  *+SP[A0],r
+}
+
+void C67_LDBU_SP_A0(int r)
+{
+    C67_asm("LDBU.D *+SP[A0]", r, 0, 0);	// LDBU  *+SP[A0],r
+}
+
+void C67_LDW_PTR(int r, int r2)
+{
+    C67_asm("LDW.D *", r, r2, 0);	// LDW  *r,r2
+}
+
+void C67_LDDW_PTR(int r, int r2)
+{
+    C67_asm("LDDW.D *", r, r2, 0);	// LDDW  *r,r2
+}
+
+void C67_LDH_PTR(int r, int r2)
+{
+    C67_asm("LDH.D *", r, r2, 0);	// LDH  *r,r2
+}
+
+void C67_LDB_PTR(int r, int r2)
+{
+    C67_asm("LDB.D *", r, r2, 0);	// LDB  *r,r2
+}
+
+void C67_LDHU_PTR(int r, int r2)
+{
+    C67_asm("LDHU.D *", r, r2, 0);	// LDHU  *r,r2
+}
+
+void C67_LDBU_PTR(int r, int r2)
+{
+    C67_asm("LDBU.D *", r, r2, 0);	// LDBU  *r,r2
+}
+
+void C67_LDW_PTR_PRE_INC(int r, int r2)
+{
+    C67_asm("LDW.D +*", r, r2, 0);	// LDW  *+r,r2
+}
+
+void C67_POP(int r)
+{
+    C67_asm("LDW.D SP PRE INC", r, 0, 0);	// LDW  *++SP,r
+}
+
+void C67_POP_DW(int r)
+{
+    C67_asm("LDDW.D SP PRE INC", r, 0, 0);	// LDDW  *++SP,r
+}
+
+void C67_CMPLT(int s1, int s2, int dst)
+{
+    C67_asm("CMPLT.L1", s1, s2, dst);
+}
+
+void C67_CMPGT(int s1, int s2, int dst)
+{
+    C67_asm("CMPGT.L1", s1, s2, dst);
+}
+
+void C67_CMPEQ(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQ.L1", s1, s2, dst);
+}
+
+void C67_CMPLTU(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTU.L1", s1, s2, dst);
+}
+
+void C67_CMPGTU(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTU.L1", s1, s2, dst);
+}
+
+
+void C67_CMPLTSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQSP.S1", s1, s2, dst);
+}
+
+void C67_CMPLTDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQDP.S1", s1, s2, dst);
+}
+
+
+void C67_IREG_B_REG(int inv, int r1, int r2)	// [!R] B  r2
+{
+    C67_asm("B.S2", inv, r1, r2);
+}
+
+
+// call with how many 32 bit words to skip
+// (0 would branch to the branch instruction)
+
+void C67_B_DISP(int disp)	//  B  +2  Branch with constant displacement
+{
+    // Branch point is relative to the 8 word fetch packet
+    //
+    // we will assume the text section always starts on an 8 word (32 byte boundary)
+    //
+    // so add in how many words into the fetch packet the branch is
+
+
+    C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);
+}
+
+void C67_NOP(int n)
+{
+    C67_asm("NOP", n, 0, 0);
+}
+
+void C67_ADDK(int n, int r)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    C67_asm("ADDK", n, r, 0);
+}
+
+void C67_ADDK_PARALLEL(int n, int r)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    C67_asm("||ADDK", n, r, 0);
+}
+
+void C67_Adjust_ADDK(int *inst, int n)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);
+}
+
+void C67_MV(int r, int v)
+{
+    C67_asm("MV.L", 0, r, v);
+}
+
+
+void C67_DPTRUNC(int r, int v)
+{
+    C67_asm("DPTRUNC.L", 0, r, v);
+}
+
+void C67_SPTRUNC(int r, int v)
+{
+    C67_asm("SPTRUNC.L", 0, r, v);
+}
+
+void C67_INTSP(int r, int v)
+{
+    C67_asm("INTSP.L", 0, r, v);
+}
+
+void C67_INTDP(int r, int v)
+{
+    C67_asm("INTDP.L", 0, r, v);
+}
+
+void C67_INTSPU(int r, int v)
+{
+    C67_asm("INTSPU.L", 0, r, v);
+}
+
+void C67_INTDPU(int r, int v)
+{
+    C67_asm("INTDPU.L", 0, r, v);
+}
+
+void C67_SPDP(int r, int v)
+{
+    C67_asm("SPDP.L", 0, r, v);
+}
+
+void C67_DPSP(int r, int v)	// note regs must be on the same side
+{
+    C67_asm("DPSP.L", 0, r, v);
+}
+
+void C67_ADD(int r, int v)
+{
+    C67_asm("ADD.L", v, r, v);
+}
+
+void C67_SUB(int r, int v)
+{
+    C67_asm("SUB.L", v, r, v);
+}
+
+void C67_AND(int r, int v)
+{
+    C67_asm("AND.L", v, r, v);
+}
+
+void C67_OR(int r, int v)
+{
+    C67_asm("OR.L", v, r, v);
+}
+
+void C67_XOR(int r, int v)
+{
+    C67_asm("XOR.L", v, r, v);
+}
+
+void C67_ADDSP(int r, int v)
+{
+    C67_asm("ADDSP.L", v, r, v);
+}
+
+void C67_SUBSP(int r, int v)
+{
+    C67_asm("SUBSP.L", v, r, v);
+}
+
+void C67_MPYSP(int r, int v)
+{
+    C67_asm("MPYSP.M", v, r, v);
+}
+
+void C67_ADDDP(int r, int v)
+{
+    C67_asm("ADDDP.L", v, r, v);
+}
+
+void C67_SUBDP(int r, int v)
+{
+    C67_asm("SUBDP.L", v, r, v);
+}
+
+void C67_MPYDP(int r, int v)
+{
+    C67_asm("MPYDP.M", v, r, v);
+}
+
+void C67_MPYI(int r, int v)
+{
+    C67_asm("MPYI.M", v, r, v);
+}
+
+void C67_SHL(int r, int v)
+{
+    C67_asm("SHL.S", r, v, v);
+}
+
+void C67_SHRU(int r, int v)
+{
+    C67_asm("SHRU.S", r, v, v);
+}
+
+void C67_SHR(int r, int v)
+{
+    C67_asm("SHR.S", r, v, v);
+}
+
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue * sv)
+{
+    int v, t, ft, fc, fr, size = 0, element;
+    BOOL Unsigned = false;
+    SValue v1;
+
+    fr = sv->r;
+    ft = sv->type.t;
+    fc = sv->c.ul;
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+	if (v == VT_LLOCAL) {
+	    v1.type.t = VT_INT;
+	    v1.r = VT_LOCAL | VT_LVAL;
+	    v1.c.ul = fc;
+	    load(r, &v1);
+	    fr = r;
+	} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+	    error("long double not supported");
+	} else if ((ft & VT_TYPE) == VT_BYTE) {
+	    size = 1;
+	} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+	    size = 1;
+	    Unsigned = TRUE;
+	} else if ((ft & VT_TYPE) == VT_SHORT) {
+	    size = 2;
+	} else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+	    size = 2;
+	    Unsigned = TRUE;
+	} else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+	    size = 8;
+	} else {
+	    size = 4;
+	}
+
+	// check if fc is a positive reference on the stack, 
+	// if it is tcc is referencing what it thinks is a parameter
+	// on the stack, so check if it is really in a register.
+
+
+	if (v == VT_LOCAL && fc > 0) {
+	    int stack_pos = 8;
+
+	    for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+		if (fc == stack_pos)
+		    break;
+
+		stack_pos += TranslateStackToReg[t];
+	    }
+
+	    // param has been pushed on stack, get it like a local var
+
+	    fc = ParamLocOnStack[t] - 8;
+	}
+
+	if ((fr & VT_VALMASK) < VT_CONST)	// check for pure indirect
+	{
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_PTR(v, r);	// LDBU  *v,r
+		else
+		    C67_LDB_PTR(v, r);	// LDB  *v,r
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_PTR(v, r);	// LDHU  *v,r
+		else
+		    C67_LDH_PTR(v, r);	// LDH  *v,r
+	    } else if (size == 4) {
+		C67_LDW_PTR(v, r);	// LDW  *v,r
+	    } else if (size == 8) {
+		C67_LDDW_PTR(v, r);	// LDDW  *v,r
+	    }
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	} else if (fr & VT_SYM) {
+	    greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+
+
+	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant
+
+
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_PTR(C67_A0, r);	// LDBU  *A0,r
+		else
+		    C67_LDB_PTR(C67_A0, r);	// LDB  *A0,r
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_PTR(C67_A0, r);	// LDHU  *A0,r
+		else
+		    C67_LDH_PTR(C67_A0, r);	// LDH  *A0,r
+	    } else if (size == 4) {
+		C67_LDW_PTR(C67_A0, r);	// LDW  *A0,r
+	    } else if (size == 8) {
+		C67_LDDW_PTR(C67_A0, r);	// LDDW  *A0,r
+	    }
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	} else {
+	    element = size;
+
+	    // divide offset in bytes to create element index
+	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_SP_A0(r);	// LDBU  r, SP[A0]
+		else
+		    C67_LDB_SP_A0(r);	// LDB  r, SP[A0]
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_SP_A0(r);	// LDHU  r, SP[A0]
+		else
+		    C67_LDH_SP_A0(r);	// LDH  r, SP[A0]
+	    } else if (size == 4) {
+		C67_LDW_SP_A0(r);	// LDW  r, SP[A0]
+	    } else if (size == 8) {
+		C67_LDDW_SP_A0(r);	// LDDW  r, SP[A0]
+	    }
+
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	}
+    } else {
+	if (v == VT_CONST) {
+	    if (fr & VT_SYM) {
+		greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+	    }
+	    C67_MVKL(r, fc);	//r=reg to load, constant
+	    C67_MVKH(r, fc);	//r=reg to load, constant
+	} else if (v == VT_LOCAL) {
+	    C67_MVKL(r, fc + 8);	//r=reg to load, constant C67 stack points to next free
+	    C67_MVKH(r, fc + 8);	//r=reg to load, constant
+	    C67_ADD(C67_FP, r);	// MV v,r   v -> r
+	} else if (v == VT_CMP) {
+	    C67_MV(C67_compare_reg, r);	// MV v,r   v -> r
+	} else if (v == VT_JMP || v == VT_JMPI) {
+	    t = v & 1;
+	    C67_B_DISP(4);	//  Branch with constant displacement, skip over this branch, load, nop, load
+	    C67_MVKL(r, t);	//  r=reg to load, 0 or 1 (do this while branching)
+	    C67_NOP(4);		//  NOP 4
+	    gsym(fc);		//  modifies other branches to branch here
+	    C67_MVKL(r, t ^ 1);	//  r=reg to load, 0 or 1
+	} else if (v != r) {
+	    C67_MV(v, r);	// MV v,r   v -> r
+
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_MV(v + 1, r + 1);	// MV v,r   v -> r
+	}
+    }
+}
+
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue * v)
+{
+    int fr, bt, ft, fc, size, t, element;
+
+    ft = v->type.t;
+    fc = v->c.ul;
+    fr = v->r & VT_VALMASK;
+    bt = ft & VT_BTYPE;
+    /* XXX: incorrect if float reg to reg */
+
+    if (bt == VT_LDOUBLE) {
+	error("long double not supported");
+    } else {
+	if (bt == VT_SHORT)
+	    size = 2;
+	else if (bt == VT_BYTE)
+	    size = 1;
+	else if (bt == VT_DOUBLE)
+	    size = 8;
+	else
+	    size = 4;
+
+	if ((v->r & VT_VALMASK) == VT_CONST) {
+	    /* constant memory reference */
+
+	    if (v->r & VT_SYM) {
+		greloc(cur_text_section, v->sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);
+	    }
+	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant
+
+	    if (size == 1)
+		C67_STB_PTR(r, C67_A0);	// STB  r, *A0
+	    else if (size == 2)
+		C67_STH_PTR(r, C67_A0);	// STH  r, *A0
+	    else if (size == 4 || size == 8)
+		C67_STW_PTR(r, C67_A0);	// STW  r, *A0
+
+	    if (size == 8)
+		C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1);	// STW  r, *+A0[1]
+	} else if ((v->r & VT_VALMASK) == VT_LOCAL) {
+	    // check case of storing to passed argument that
+	    // tcc thinks is on the stack but for C67 is
+	    // passed as a reg.  However it may have been
+	    // saved to the stack, if that reg was required
+	    // for a call to a child function
+
+	    if (fc > 0)		// argument ??
+	    {
+		// walk through sizes and figure which param
+
+		int stack_pos = 8;
+
+		for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+		    if (fc == stack_pos)
+			break;
+
+		    stack_pos += TranslateStackToReg[t];
+		}
+
+		// param has been pushed on stack, get it like a local var
+		fc = ParamLocOnStack[t] - 8;
+	    }
+
+	    if (size == 8)
+		element = 4;
+	    else
+		element = size;
+
+	    // divide offset in bytes to create word index
+	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+
+
+
+	    if (size == 1)
+		C67_STB_SP_A0(r);	// STB  r, SP[A0]
+	    else if (size == 2)
+		C67_STH_SP_A0(r);	// STH  r, SP[A0]
+	    else if (size == 4 || size == 8)
+		C67_STW_SP_A0(r);	// STW  r, SP[A0]
+
+	    if (size == 8) {
+		C67_ADDK(1, C67_A0);	//  ADDK 1,A0
+		C67_STW_SP_A0(r + 1);	//  STW  r, SP[A0]
+	    }
+	} else {
+	    if (size == 1)
+		C67_STB_PTR(r, fr);	// STB  r, *fr
+	    else if (size == 2)
+		C67_STH_PTR(r, fr);	// STH  r, *fr
+	    else if (size == 4 || size == 8)
+		C67_STW_PTR(r, fr);	// STW  r, *fr
+
+	    if (size == 8) {
+		C67_STW_PTR_PRE_INC(r + 1, fr, 1);	// STW  r, *+fr[1]
+	    }
+	}
+    }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    Sym *sym;
+
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+	/* constant case */
+	if (vtop->r & VT_SYM) {
+	    /* relocation case */
+
+	    // get add into A0, then start the jump B3
+
+	    greloc(cur_text_section, vtop->sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);
+
+	    C67_MVKL(C67_A0, 0);	//r=reg to load, constant
+	    C67_MVKH(C67_A0, 0);	//r=reg to load, constant
+	    C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0);	//  B.S2x  A0
+
+	    if (is_jmp) {
+		C67_NOP(5);	// simple jump, just put NOP
+	    } else {
+		// Call, must load return address into B3 during delay slots
+
+		sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0);	// symbol for return address
+		greloc(cur_text_section, sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+		C67_MVKL(C67_B3, 0);	//r=reg to load, constant
+		C67_MVKH(C67_B3, 0);	//r=reg to load, constant
+		C67_NOP(3);	// put remaining NOPs
+	    }
+	} else {
+	    /* put an empty PC32 relocation */
+	    ALWAYS_ASSERT(FALSE);
+	}
+    } else {
+	/* otherwise, indirect call */
+	r = gv(RC_INT);
+	C67_IREG_B_REG(0, C67_CREG_ZERO, r);	//  B.S2x  r
+
+	if (is_jmp) {
+	    C67_NOP(5);		// simple jump, just put NOP
+	} else {
+	    // Call, must load return address into B3 during delay slots
+
+	    sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0);	// symbol for return address
+	    greloc(cur_text_section, sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+	    C67_MVKL(C67_B3, 0);	//r=reg to load, constant
+	    C67_MVKH(C67_B3, 0);	//r=reg to load, constant
+	    C67_NOP(3);		// put remaining NOPs
+	}
+    }
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+   context. Stack entry is popped */
+void gfunc_call(int nb_args)
+{
+    int i, r, size = 0;
+    int args_sizes[NoCallArgsPassedOnStack];
+
+    if (nb_args > NoCallArgsPassedOnStack) {
+	error("more than 10 function params not currently supported");
+	// handle more than 10, put some on the stack
+    }
+
+    for (i = 0; i < nb_args; i++) {
+	if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+	    ALWAYS_ASSERT(FALSE);
+	} else if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+	    ALWAYS_ASSERT(FALSE);
+	} else {
+	    /* simple type (currently always same size) */
+	    /* XXX: implicit cast ? */
+
+
+	    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+		error("long long not supported");
+	    } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+		error("long double not supported");
+	    } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+		size = 8;
+	    } else {
+		size = 4;
+	    }
+
+	    // put the parameter into the corresponding reg (pair)
+
+	    r = gv(RC_C67_A4 << (2 * i));
+
+	    // must put on stack because with 1 pass compiler , no way to tell
+	    // if an up coming nested call might overwrite these regs
+
+	    C67_PUSH(r);
+
+	    if (size == 8) {
+		C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3);	// STW  r, *+SP[3] (go back and put the other)
+	    }
+	    args_sizes[i] = size;
+	}
+	vtop--;
+    }
+    // POP all the params on the stack into registers for the
+    // immediate call (in reverse order)
+
+    for (i = nb_args - 1; i >= 0; i--) {
+
+	if (args_sizes[i] == 8)
+	    C67_POP_DW(TREG_C67_A4 + i * 2);
+	else
+	    C67_POP(TREG_C67_A4 + i * 2);
+    }
+    gcall_or_jmp(0);
+    vtop--;
+}
+
+
+// to be compatible with Code Composer for the C67
+// the first 10 parameters must be passed in registers
+// (pairs for 64 bits) starting wit; A4:A5, then B4:B5 and
+// ending with B12:B13.
+//
+// When a call is made, if the caller has its parameters
+// in regs A4-B13 these must be saved before/as the call 
+// parameters are loaded and restored upon return (or if/when needed).
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType * func_type)
+{
+    int addr, align, size, func_call, i;
+    Sym *sym;
+    CType *type;
+
+    sym = func_type->ref;
+    func_call = sym->r;
+    addr = 8;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+	func_vc = addr;
+	addr += 4;
+    }
+
+    NoOfCurFuncArgs = 0;
+
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+	type = &sym->type;
+	sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr);
+	size = type_size(type, &align);
+	size = (size + 3) & ~3;
+
+	// keep track of size of arguments so
+	// we can translate where tcc thinks they
+	// are on the stack into the appropriate reg
+
+	TranslateStackToReg[NoOfCurFuncArgs] = size;
+	NoOfCurFuncArgs++;
+
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+	/* structs are passed as pointer */
+	if ((type->t & VT_BTYPE) == VT_STRUCT) {
+	    size = 4;
+	}
+#endif
+	addr += size;
+    }
+    func_ret_sub = 0;
+    /* pascal type call ? */
+    if (func_call == FUNC_STDCALL)
+	func_ret_sub = addr - 8;
+
+    C67_MV(C67_FP, C67_A0);	//  move FP -> A0
+    C67_MV(C67_SP, C67_FP);	//  move SP -> FP
+
+    // place all the args passed in regs onto the stack
+
+    loc = 0;
+    for (i = 0; i < NoOfCurFuncArgs; i++) {
+
+	ParamLocOnStack[i] = loc;	// remember where the param is
+	loc += -8;
+
+	C67_PUSH(TREG_C67_A4 + i * 2);
+
+	if (TranslateStackToReg[i] == 8) {
+	    C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3);	// STW  r, *+SP[1] (go back and put the other)
+	}
+    }
+
+    TotalBytesPushedOnStack = -loc;
+
+    func_sub_sp_offset = ind;	// remember where we put the stack instruction 
+    C67_ADDK(0, C67_SP);	//  ADDK.L2 loc,SP  (just put zero temporarily)
+
+    C67_PUSH(C67_A0);
+    C67_PUSH(C67_B3);
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    {
+	int local = (-loc + 7) & -8;	// stack must stay aligned to 8 bytes for LDDW instr
+	C67_POP(C67_B3);
+	C67_NOP(4);		// NOP wait for load
+	C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3);	//  B.S2  B3
+	C67_POP(C67_FP);
+	C67_ADDK(local, C67_SP);	//  ADDK.L2 loc,SP  
+	C67_Adjust_ADDK((int *) (cur_text_section->data +
+				 func_sub_sp_offset),
+			-local + TotalBytesPushedOnStack);
+	C67_NOP(3);		// NOP 
+    }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    int ind1 = ind;
+
+    C67_MVKL(C67_A0, t);	//r=reg to load,  constant
+    C67_MVKH(C67_A0, t);	//r=reg to load,  constant
+    C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0);	// [!R] B.S2x  A0
+    C67_NOP(5);
+    return ind1;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    Sym *sym;
+    // I guess this routine is used for relative short
+    // local jumps, for now just handle it as the general
+    // case
+
+    // define a label that will be relocated
+
+    sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+    greloc(cur_text_section, sym, ind, R_C60LO16);
+    greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+
+    gjmp(0);			// place a zero there later the symbol will be added to it
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int ind1, n;
+    int v, *p;
+
+    v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+	/* fast case : can jump directly since flags are set */
+	// C67 uses B2 sort of as flags register
+	ind1 = ind;
+	C67_MVKL(C67_A0, t);	//r=reg to load, constant
+	C67_MVKH(C67_A0, t);	//r=reg to load, constant
+
+	if (C67_compare_reg != TREG_EAX &&	// check if not already in a conditional test reg
+	    C67_compare_reg != TREG_EDX &&
+	    C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
+	    C67_MV(C67_compare_reg, C67_B2);
+	    C67_compare_reg = C67_B2;
+	}
+
+	C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0);	// [!R] B.S2x  A0
+	C67_NOP(5);
+	t = ind1;		//return where we need to patch
+
+    } else if (v == VT_JMP || v == VT_JMPI) {
+	/* && or || optimization */
+	if ((v & 1) == inv) {
+	    /* insert vtop->c jump list in t */
+	    p = &vtop->c.i;
+
+	    // I guess the idea is to traverse to the
+	    // null at the end of the list and store t
+	    // there
+
+	    n = *p;
+	    while (n != 0) {
+		p = (int *) (cur_text_section->data + n);
+
+		// extract 32 bit address from MVKH/MVKL
+		n = ((*p >> 7) & 0xffff);
+		n |= ((*(p + 1) >> 7) & 0xffff) << 16;
+	    }
+	    *p |= (t & 0xffff) << 7;
+	    *(p + 1) |= ((t >> 16) & 0xffff) << 7;
+	    t = vtop->c.i;
+
+	} else {
+	    t = gjmp(t);
+	    gsym(vtop->c.i);
+	}
+    } else {
+	if (is_float(vtop->type.t)) {
+	    vpushi(0);
+	    gen_op(TOK_NE);
+	}
+	if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	    /* constant jmp optimization */
+	    if ((vtop->c.i != 0) != inv)
+		t = gjmp(t);
+	} else {
+	    // I think we need to get the value on the stack
+	    // into a register, test it, and generate a branch
+	    // return the address of the branch, so it can be
+	    // later patched
+
+	    v = gv(RC_INT);	// get value into a reg 
+	    ind1 = ind;
+	    C67_MVKL(C67_A0, t);	//r=reg to load, constant
+	    C67_MVKH(C67_A0, t);	//r=reg to load, constant
+
+	    if (v != TREG_EAX &&	// check if not already in a conditional test reg
+		v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
+		C67_MV(v, C67_B2);
+		v = C67_B2;
+	    }
+
+	    C67_IREG_B_REG(inv, v, C67_A0);	// [!R] B.S2x  A0
+	    C67_NOP(5);
+	    t = ind1;		//return where we need to patch
+	    ind1 = ind;
+	}
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    int r, fr, opc, t;
+
+    switch (op) {
+    case '+':
+    case TOK_ADDC1:		/* add with carry generation */
+	opc = 0;
+      gen_op8:
+
+
+// C67 can't do const compares, must load into a reg
+// so just go to gv2 directly - tktk
+
+
+
+	if (op >= TOK_ULT && op <= TOK_GT)
+	    gv2(RC_INT_BSIDE, RC_INT);	// make sure r (src1) is on the B Side of CPU
+	else
+	    gv2(RC_INT, RC_INT);
+
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+
+	C67_compare_reg = C67_B2;
+
+
+	if (op == TOK_LT) {
+	    C67_CMPLT(r, fr, C67_B2);
+	    C67_invert_test = false;
+	} else if (op == TOK_GE) {
+	    C67_CMPLT(r, fr, C67_B2);
+	    C67_invert_test = true;
+	} else if (op == TOK_GT) {
+	    C67_CMPGT(r, fr, C67_B2);
+	    C67_invert_test = false;
+	} else if (op == TOK_LE) {
+	    C67_CMPGT(r, fr, C67_B2);
+	    C67_invert_test = true;
+	} else if (op == TOK_EQ) {
+	    C67_CMPEQ(r, fr, C67_B2);
+	    C67_invert_test = false;
+	} else if (op == TOK_NE) {
+	    C67_CMPEQ(r, fr, C67_B2);
+	    C67_invert_test = true;
+	} else if (op == TOK_ULT) {
+	    C67_CMPLTU(r, fr, C67_B2);
+	    C67_invert_test = false;
+	} else if (op == TOK_UGE) {
+	    C67_CMPLTU(r, fr, C67_B2);
+	    C67_invert_test = true;
+	} else if (op == TOK_UGT) {
+	    C67_CMPGTU(r, fr, C67_B2);
+	    C67_invert_test = false;
+	} else if (op == TOK_ULE) {
+	    C67_CMPGTU(r, fr, C67_B2);
+	    C67_invert_test = true;
+	} else if (op == '+')
+	    C67_ADD(fr, r);	// ADD  r,fr,r
+	else if (op == '-')
+	    C67_SUB(fr, r);	// SUB  r,fr,r
+	else if (op == '&')
+	    C67_AND(fr, r);	// AND  r,fr,r
+	else if (op == '|')
+	    C67_OR(fr, r);	// OR  r,fr,r
+	else if (op == '^')
+	    C67_XOR(fr, r);	// XOR  r,fr,r
+	else
+	    ALWAYS_ASSERT(FALSE);
+
+	vtop--;
+	if (op >= TOK_ULT && op <= TOK_GT) {
+	    vtop->r = VT_CMP;
+	    vtop->c.i = op;
+	}
+	break;
+    case '-':
+    case TOK_SUBC1:		/* sub with carry generation */
+	opc = 5;
+	goto gen_op8;
+    case TOK_ADDC2:		/* add with carry use */
+	opc = 2;
+	goto gen_op8;
+    case TOK_SUBC2:		/* sub with carry use */
+	opc = 3;
+	goto gen_op8;
+    case '&':
+	opc = 4;
+	goto gen_op8;
+    case '^':
+	opc = 6;
+	goto gen_op8;
+    case '|':
+	opc = 1;
+	goto gen_op8;
+    case '*':
+    case TOK_UMULL:
+	gv2(RC_INT, RC_INT);
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_MPYI(fr, r);	// 32 bit bultiply  fr,r,fr
+	C67_NOP(8);		// NOP 8 for worst case
+	break;
+    case TOK_SHL:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHL(fr, r);		// arithmetic/logical shift
+	break;
+
+    case TOK_SHR:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHRU(fr, r);	// logical shift
+	break;
+
+    case TOK_SAR:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHR(fr, r);		// arithmetic shift
+	break;
+
+    case '/':
+	t = TOK__divi;
+      call_func:
+	vswap();
+	/* call generic idiv function */
+	vpush_global_sym(&func_old_type, t);
+	vrott(3);
+	gfunc_call(2);
+	vpushi(0);
+	vtop->r = REG_IRET;
+	vtop->r2 = VT_CONST;
+	break;
+    case TOK_UDIV:
+    case TOK_PDIV:
+	t = TOK__divu;
+	goto call_func;
+    case '%':
+	t = TOK__remi;
+	goto call_func;
+    case TOK_UMOD:
+	t = TOK__remu;
+	goto call_func;
+
+    default:
+	opc = 7;
+	goto gen_op8;
+    }
+}
+
+/* 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)
+{
+    int ft, fc, fr, r;
+
+    if (op >= TOK_ULT && op <= TOK_GT)
+	gv2(RC_EDX, RC_EAX);	// make sure src2 is on b side
+    else
+	gv2(RC_FLOAT, RC_FLOAT);	// make sure src2 is on b side
+
+    ft = vtop->type.t;
+    fc = vtop->c.ul;
+    r = vtop->r;
+    fr = vtop[-1].r;
+
+
+    if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	error("long doubles not supported");
+
+    if (op >= TOK_ULT && op <= TOK_GT) {
+
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+
+	C67_compare_reg = C67_B2;
+
+	if (op == TOK_LT) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPLTDP(r, fr, C67_B2);
+	    else
+		C67_CMPLTSP(r, fr, C67_B2);
+
+	    C67_invert_test = false;
+	} else if (op == TOK_GE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPLTDP(r, fr, C67_B2);
+	    else
+		C67_CMPLTSP(r, fr, C67_B2);
+
+	    C67_invert_test = true;
+	} else if (op == TOK_GT) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPGTDP(r, fr, C67_B2);
+	    else
+		C67_CMPGTSP(r, fr, C67_B2);
+
+	    C67_invert_test = false;
+	} else if (op == TOK_LE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPGTDP(r, fr, C67_B2);
+	    else
+		C67_CMPGTSP(r, fr, C67_B2);
+
+	    C67_invert_test = true;
+	} else if (op == TOK_EQ) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPEQDP(r, fr, C67_B2);
+	    else
+		C67_CMPEQSP(r, fr, C67_B2);
+
+	    C67_invert_test = false;
+	} else if (op == TOK_NE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPEQDP(r, fr, C67_B2);
+	    else
+		C67_CMPEQSP(r, fr, C67_B2);
+
+	    C67_invert_test = true;
+	} else {
+	    ALWAYS_ASSERT(FALSE);
+	}
+	vtop->r = VT_CMP;	// tell TCC that result is in "flags" actually B2
+    } else {
+	if (op == '+') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_ADDDP(r, fr);	// ADD  fr,r,fr
+		C67_NOP(6);
+	    } else {
+		C67_ADDSP(r, fr);	// ADD  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '-') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_SUBDP(r, fr);	// SUB  fr,r,fr
+		C67_NOP(6);
+	    } else {
+		C67_SUBSP(r, fr);	// SUB  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '*') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_MPYDP(r, fr);	// MPY  fr,r,fr
+		C67_NOP(9);
+	    } else {
+		C67_MPYSP(r, fr);	// MPY  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '/') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		// must call intrinsic DP floating point divide
+		vswap();
+		/* call generic idiv function */
+		vpush_global_sym(&func_old_type, TOK__divd);
+		vrott(3);
+		gfunc_call(2);
+		vpushi(0);
+		vtop->r = REG_FRET;
+		vtop->r2 = REG_LRET;
+
+	    } else {
+		// must call intrinsic SP floating point divide
+		vswap();
+		/* call generic idiv function */
+		vpush_global_sym(&func_old_type, TOK__divf);
+		vrott(3);
+		gfunc_call(2);
+		vpushi(0);
+		vtop->r = REG_FRET;
+		vtop->r2 = VT_CONST;
+	    }
+	} else
+	    ALWAYS_ASSERT(FALSE);
+
+
+    }
+}
+
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    int r;
+
+    gv(RC_INT);
+    r = vtop->r;
+
+    if ((t & VT_BTYPE) == VT_DOUBLE) {
+	if (t & VT_UNSIGNED)
+	    C67_INTDPU(r, r);
+	else
+	    C67_INTDP(r, r);
+
+	C67_NOP(4);
+	vtop->type.t = VT_DOUBLE;
+    } else {
+	if (t & VT_UNSIGNED)
+	    C67_INTSPU(r, r);
+	else
+	    C67_INTSP(r, r);
+	C67_NOP(3);
+	vtop->type.t = VT_FLOAT;
+    }
+
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+    int r;
+
+    gv(RC_FLOAT);
+    r = vtop->r;
+
+    if (t != VT_INT)
+	error("long long not supported");
+    else {
+	if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+	    C67_DPTRUNC(r, r);
+	    C67_NOP(3);
+	} else {
+	    C67_SPTRUNC(r, r);
+	    C67_NOP(3);
+	}
+
+	vtop->type.t = VT_INT;
+
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    int r, r2;
+
+    if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
+	(t & VT_BTYPE) == VT_FLOAT) {
+	// convert double to float
+
+	gv(RC_FLOAT);		// get it in a register pair
+
+	r = vtop->r;
+
+	C67_DPSP(r, r);		// convert it to SP same register
+	C67_NOP(3);
+
+	vtop->type.t = VT_FLOAT;
+	vtop->r2 = VT_CONST;	// set this as unused
+    } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT &&
+	       (t & VT_BTYPE) == VT_DOUBLE) {
+	// convert float to double
+
+	gv(RC_FLOAT);		// get it in a register
+
+	r = vtop->r;
+
+	if (r == TREG_EAX) {	// make sure the paired reg is avail
+	    r2 = get_reg(RC_ECX);
+	} else if (r == TREG_EDX) {
+	    r2 = get_reg(RC_ST0);
+	} else {
+	    ALWAYS_ASSERT(FALSE);
+            r2 = 0; /* avoid warning */
+        }
+
+	C67_SPDP(r, r);		// convert it to DP same register
+	C67_NOP(1);
+
+	vtop->type.t = VT_DOUBLE;
+	vtop->r2 = r2;		// set this as unused
+    } else {
+	ALWAYS_ASSERT(FALSE);
+    }
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* end of X86 code generator */
+/*************************************************************/
diff --git a/tinyc/coff.h b/tinyc/coff.h
new file mode 100755
index 000000000..38960b40f
--- /dev/null
+++ b/tinyc/coff.h
@@ -0,0 +1,446 @@
+/**************************************************************************/
+/*  COFF.H                                                                */
+/*     COFF data structures and related definitions used by the linker    */
+/**************************************************************************/
+
+/*------------------------------------------------------------------------*/
+/*  COFF FILE HEADER                                                      */
+/*------------------------------------------------------------------------*/
+struct filehdr {
+        unsigned short  f_magic;        /* magic number */
+        unsigned short  f_nscns;        /* number of sections */
+        long            f_timdat;       /* time & date stamp */
+        long            f_symptr;       /* file pointer to symtab */
+        long            f_nsyms;        /* number of symtab entries */
+        unsigned short  f_opthdr;       /* sizeof(optional hdr) */
+        unsigned short  f_flags;        /* flags */
+        unsigned short  f_TargetID;     /* for C6x = 0x0099 */
+        };
+
+/*------------------------------------------------------------------------*/
+/*  File header flags                                                     */
+/*------------------------------------------------------------------------*/
+#define  F_RELFLG   0x01       /* relocation info stripped from file       */
+#define  F_EXEC     0x02       /* file is executable (no unresolved refs)  */
+#define  F_LNNO     0x04       /* line nunbers stripped from file          */
+#define  F_LSYMS    0x08       /* local symbols stripped from file         */
+#define  F_GSP10    0x10       /* 34010 version                            */
+#define  F_GSP20    0x20       /* 34020 version                            */
+#define  F_SWABD    0x40       /* bytes swabbed (in names)                 */
+#define  F_AR16WR   0x80       /* byte ordering of an AR16WR (PDP-11)      */
+#define  F_LITTLE   0x100      /* byte ordering of an AR32WR (vax)         */
+#define  F_BIG      0x200      /* byte ordering of an AR32W (3B, maxi)     */
+#define  F_PATCH    0x400      /* contains "patch" list in optional header */
+#define  F_NODF     0x400   
+
+#define F_VERSION    (F_GSP10  | F_GSP20)   
+#define F_BYTE_ORDER (F_LITTLE | F_BIG)
+#define FILHDR  struct filehdr
+
+//#define FILHSZ  sizeof(FILHDR) 
+#define FILHSZ  22                // above rounds to align on 4 bytes which causes problems 
+
+#define COFF_C67_MAGIC 0x00c2
+
+/*------------------------------------------------------------------------*/
+/*  Macros to recognize magic numbers                                     */
+/*------------------------------------------------------------------------*/
+#define ISMAGIC(x)      (((unsigned short)(x))==(unsigned short)magic)
+#define ISARCHIVE(x)    ((((unsigned short)(x))==(unsigned short)ARTYPE))
+#define BADMAGIC(x)     (((unsigned short)(x) & 0x8080) && !ISMAGIC(x))
+
+
+/*------------------------------------------------------------------------*/
+/*  OPTIONAL FILE HEADER                                                  */
+/*------------------------------------------------------------------------*/
+typedef struct aouthdr {
+        short   magic;          /* see magic.h                          */
+        short   vstamp;         /* version stamp                        */
+        long    tsize;          /* text size in bytes, padded to FW bdry*/
+        long    dsize;          /* initialized data "  "                */
+        long    bsize;          /* uninitialized data "   "             */
+        long    entrypt;        /* entry pt.                            */
+        long    text_start;     /* base of text used for this file      */
+        long    data_start;     /* base of data used for this file      */
+} AOUTHDR;
+
+#define AOUTSZ  sizeof(AOUTHDR)
+
+/*----------------------------------------------------------------------*/
+/*      When a UNIX aout header is to be built in the optional header,  */
+/*      the following magic numbers can appear in that header:          */ 
+/*                                                                      */
+/*              AOUT1MAGIC : default : readonly sharable text segment   */
+/*              AOUT2MAGIC:          : writable text segment            */
+/*              PAGEMAGIC  :         : configured for paging            */
+/*----------------------------------------------------------------------*/
+#define AOUT1MAGIC 0410
+#define AOUT2MAGIC 0407
+#define PAGEMAGIC  0413
+
+
+/*------------------------------------------------------------------------*/
+/*  COMMON ARCHIVE FILE STRUCTURES                                        */
+/*                                                                        */
+/*       ARCHIVE File Organization:                                       */
+/*       _______________________________________________                  */
+/*       |__________ARCHIVE_MAGIC_STRING_______________|                  */
+/*       |__________ARCHIVE_FILE_MEMBER_1______________|                  */
+/*       |                                             |                  */
+/*       |       Archive File Header "ar_hdr"          |                  */
+/*       |.............................................|                  */
+/*       |       Member Contents                       |                  */
+/*       |               1. External symbol directory  |                  */
+/*       |               2. Text file                  |                  */
+/*       |_____________________________________________|                  */
+/*       |________ARCHIVE_FILE_MEMBER_2________________|                  */
+/*       |               "ar_hdr"                      |                  */
+/*       |.............................................|                  */
+/*       |       Member Contents (.o or text file)     |                  */
+/*       |_____________________________________________|                  */
+/*       |       .               .               .     |                  */
+/*       |       .               .               .     |                  */
+/*       |       .               .               .     |                  */
+/*       |_____________________________________________|                  */
+/*       |________ARCHIVE_FILE_MEMBER_n________________|                  */
+/*       |               "ar_hdr"                      |                  */
+/*       |.............................................|                  */
+/*       |               Member Contents               |                  */
+/*       |_____________________________________________|                  */
+/*                                                                        */
+/*------------------------------------------------------------------------*/
+
+#define COFF_ARMAG   "!<arch>\n"
+#define SARMAG  8
+#define ARFMAG  "`\n"
+
+struct ar_hdr           /* archive file member header - printable ascii */
+{
+        char    ar_name[16];    /* file member name - `/' terminated */
+        char    ar_date[12];    /* file member date - decimal */
+        char    ar_uid[6];      /* file member user id - decimal */
+        char    ar_gid[6];      /* file member group id - decimal */
+        char    ar_mode[8];     /* file member mode - octal */
+        char    ar_size[10];    /* file member size - decimal */
+        char    ar_fmag[2];     /* ARFMAG - string to end header */
+};
+
+
+/*------------------------------------------------------------------------*/
+/*  SECTION HEADER                                                        */
+/*------------------------------------------------------------------------*/
+struct scnhdr {
+        char            s_name[8];      /* section name */
+        long            s_paddr;        /* physical address */
+        long            s_vaddr;        /* virtual address */
+        long            s_size;         /* section size */
+        long            s_scnptr;       /* file ptr to raw data for section */
+        long            s_relptr;       /* file ptr to relocation */
+        long            s_lnnoptr;      /* file ptr to line numbers */
+        unsigned int	s_nreloc;       /* number of relocation entries */
+        unsigned int	s_nlnno;        /* number of line number entries */
+        unsigned int	s_flags;        /* flags */
+		unsigned short	s_reserved;     /* reserved byte */
+		unsigned short  s_page;         /* memory page id */
+        };
+
+#define SCNHDR  struct scnhdr
+#define SCNHSZ  sizeof(SCNHDR)
+
+/*------------------------------------------------------------------------*/
+/* Define constants for names of "special" sections                       */
+/*------------------------------------------------------------------------*/
+//#define _TEXT    ".text"
+#define _DATA    ".data"
+#define _BSS     ".bss"
+#define _CINIT   ".cinit"
+#define _TV      ".tv"
+
+/*------------------------------------------------------------------------*/
+/* The low 4 bits of s_flags is used as a section "type"                  */
+/*------------------------------------------------------------------------*/
+#define STYP_REG    0x00  /* "regular" : allocated, relocated, loaded */
+#define STYP_DSECT  0x01  /* "dummy"   : not allocated, relocated, not loaded */
+#define STYP_NOLOAD 0x02  /* "noload"  : allocated, relocated, not loaded */
+#define STYP_GROUP  0x04  /* "grouped" : formed of input sections */
+#define STYP_PAD    0x08  /* "padding" : not allocated, not relocated, loaded */
+#define STYP_COPY   0x10  /* "copy"    : used for C init tables - 
+                                                not allocated, relocated,
+                                                loaded;  reloc & lineno
+                                                entries processed normally */
+#define STYP_TEXT   0x20   /* section contains text only */
+#define STYP_DATA   0x40   /* section contains data only */
+#define STYP_BSS    0x80   /* section contains bss only */
+
+#define STYP_ALIGN  0x100  /* align flag passed by old version assemblers */
+#define ALIGN_MASK  0x0F00 /* part of s_flags that is used for align vals */
+#define ALIGNSIZE(x) (1 << ((x & ALIGN_MASK) >> 8))
+
+
+/*------------------------------------------------------------------------*/
+/*  RELOCATION ENTRIES                                                    */
+/*------------------------------------------------------------------------*/
+struct reloc
+{
+   long            r_vaddr;        /* (virtual) address of reference */
+   short           r_symndx;       /* index into symbol table */
+   unsigned short  r_disp;         /* additional bits for address calculation */
+   unsigned short  r_type;         /* relocation type */
+};
+
+#define RELOC   struct reloc
+#define RELSZ   10                 /* sizeof(RELOC) */
+
+/*--------------------------------------------------------------------------*/
+/*   define all relocation types                                            */
+/*--------------------------------------------------------------------------*/
+
+#define R_ABS           0         /* absolute address - no relocation       */
+#define R_DIR16         01        /* UNUSED                                 */
+#define R_REL16         02        /* UNUSED                                 */
+#define R_DIR24         04        /* UNUSED                                 */
+#define R_REL24         05        /* 24 bits, direct                        */
+#define R_DIR32         06        /* UNUSED                                 */
+#define R_RELBYTE      017        /* 8 bits, direct                         */
+#define R_RELWORD      020        /* 16 bits, direct                        */
+#define R_RELLONG      021        /* 32 bits, direct                        */
+#define R_PCRBYTE      022        /* 8 bits, PC-relative                    */
+#define R_PCRWORD      023        /* 16 bits, PC-relative                   */
+#define R_PCRLONG      024        /* 32 bits, PC-relative                   */
+#define R_OCRLONG      030        /* GSP: 32 bits, one's complement direct  */
+#define R_GSPPCR16     031        /* GSP: 16 bits, PC relative (in words)   */
+#define R_GSPOPR32     032        /* GSP: 32 bits, direct big-endian        */
+#define R_PARTLS16     040        /* Brahma: 16 bit offset of 24 bit address*/
+#define R_PARTMS8      041        /* Brahma: 8 bit page of 24 bit address   */
+#define R_PARTLS7      050        /* DSP: 7 bit offset of 16 bit address    */
+#define R_PARTMS9      051        /* DSP: 9 bit page of 16 bit address      */
+#define R_REL13        052        /* DSP: 13 bits, direct                   */
+
+
+/*------------------------------------------------------------------------*/
+/*  LINE NUMBER ENTRIES                                                   */
+/*------------------------------------------------------------------------*/
+struct lineno
+{
+        union
+        {
+                long    l_symndx ;      /* sym. table index of function name
+                                                iff l_lnno == 0      */
+                long    l_paddr ;       /* (physical) address of line number */
+        }               l_addr ;
+        unsigned short  l_lnno ;        /* line number */
+};
+
+#define LINENO  struct lineno
+#define LINESZ  6       /* sizeof(LINENO) */
+
+
+/*------------------------------------------------------------------------*/
+/*   STORAGE CLASSES                                                      */
+/*------------------------------------------------------------------------*/
+#define  C_EFCN          -1    /* physical end of function */
+#define  C_NULL          0
+#define  C_AUTO          1     /* automatic variable */
+#define  C_EXT           2     /* external symbol */
+#define  C_STAT          3     /* static */
+#define  C_REG           4     /* register variable */
+#define  C_EXTDEF        5     /* external definition */
+#define  C_LABEL         6     /* label */
+#define  C_ULABEL        7     /* undefined label */
+#define  C_MOS           8     /* member of structure */
+#define  C_ARG           9     /* function argument */
+#define  C_STRTAG        10    /* structure tag */
+#define  C_MOU           11    /* member of union */
+#define  C_UNTAG         12    /* union tag */
+#define  C_TPDEF         13    /* type definition */
+#define C_USTATIC        14    /* undefined static */
+#define  C_ENTAG         15    /* enumeration tag */
+#define  C_MOE           16    /* member of enumeration */
+#define  C_REGPARM       17    /* register parameter */
+#define  C_FIELD         18    /* bit field */
+
+#define  C_BLOCK         100   /* ".bb" or ".eb" */
+#define  C_FCN           101   /* ".bf" or ".ef" */
+#define  C_EOS           102   /* end of structure */
+#define  C_FILE          103   /* file name */
+#define  C_LINE          104   /* dummy sclass for line number entry */
+#define  C_ALIAS         105   /* duplicate tag */
+#define  C_HIDDEN        106   /* special storage class for external */
+                               /* symbols in dmert public libraries  */
+
+/*------------------------------------------------------------------------*/
+/*  SYMBOL TABLE ENTRIES                                                  */
+/*------------------------------------------------------------------------*/
+
+#define  SYMNMLEN   8      /*  Number of characters in a symbol name */
+#define  FILNMLEN   14     /*  Number of characters in a file name */
+#define  DIMNUM     4      /*  Number of array dimensions in auxiliary entry */
+
+
+struct syment
+{
+        union
+        {
+                char            _n_name[SYMNMLEN];      /* old COFF version */
+                struct
+                {
+                        long    _n_zeroes;      /* new == 0 */
+                        long    _n_offset;      /* offset into string table */
+                } _n_n;
+                char            *_n_nptr[2];    /* allows for overlaying */
+        } _n;
+        long                    n_value;        /* value of symbol */
+        short                   n_scnum;        /* section number */
+        unsigned short          n_type;         /* type and derived type */
+        char                    n_sclass;       /* storage class */
+        char                    n_numaux;       /* number of aux. entries */
+};
+
+#define n_name          _n._n_name
+#define n_nptr          _n._n_nptr[1]
+#define n_zeroes        _n._n_n._n_zeroes
+#define n_offset        _n._n_n._n_offset
+
+/*------------------------------------------------------------------------*/
+/* Relocatable symbols have a section number of the                       */
+/* section in which they are defined.  Otherwise, section                 */
+/* numbers have the following meanings:                                   */
+/*------------------------------------------------------------------------*/
+#define  N_UNDEF  0                     /* undefined symbol */
+#define  N_ABS    -1                    /* value of symbol is absolute */
+#define  N_DEBUG  -2                    /* special debugging symbol  */
+#define  N_TV     (unsigned short)-3    /* needs transfer vector (preload) */
+#define  P_TV     (unsigned short)-4    /* needs transfer vector (postload) */
+
+
+/*------------------------------------------------------------------------*/
+/* The fundamental type of a symbol packed into the low                   */
+/* 4 bits of the word.                                                    */
+/*------------------------------------------------------------------------*/
+#define  _EF    ".ef"
+
+#define  T_NULL     0          /* no type info */
+#define  T_ARG      1          /* function argument (only used by compiler) */
+#define  T_CHAR     2          /* character */
+#define  T_SHORT    3          /* short integer */
+#define  T_INT      4          /* integer */
+#define  T_LONG     5          /* long integer */
+#define  T_FLOAT    6          /* floating point */
+#define  T_DOUBLE   7          /* double word */
+#define  T_STRUCT   8          /* structure  */
+#define  T_UNION    9          /* union  */
+#define  T_ENUM     10         /* enumeration  */
+#define  T_MOE      11         /* member of enumeration */
+#define  T_UCHAR    12         /* unsigned character */
+#define  T_USHORT   13         /* unsigned short */
+#define  T_UINT     14         /* unsigned integer */
+#define  T_ULONG    15         /* unsigned long */
+
+/*------------------------------------------------------------------------*/
+/* derived types are:                                                     */
+/*------------------------------------------------------------------------*/
+#define  DT_NON      0          /* no derived type */
+#define  DT_PTR      1          /* pointer */
+#define  DT_FCN      2          /* function */
+#define  DT_ARY      3          /* array */
+
+#define MKTYPE(basic, d1,d2,d3,d4,d5,d6) \
+       ((basic) | ((d1) <<  4) | ((d2) <<  6) | ((d3) <<  8) |\
+                  ((d4) << 10) | ((d5) << 12) | ((d6) << 14))
+
+/*------------------------------------------------------------------------*/
+/* type packing constants and macros                                      */
+/*------------------------------------------------------------------------*/
+#define  N_BTMASK_COFF     017
+#define  N_TMASK_COFF      060
+#define  N_TMASK1_COFF     0300
+#define  N_TMASK2_COFF     0360
+#define  N_BTSHFT_COFF     4
+#define  N_TSHIFT_COFF     2
+
+#define  BTYPE_COFF(x)  ((x) & N_BTMASK_COFF)  
+#define  ISINT(x)  (((x) >= T_CHAR && (x) <= T_LONG) ||   \
+		    ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
+#define  ISFLT_COFF(x)  ((x) == T_DOUBLE || (x) == T_FLOAT)
+#define  ISPTR_COFF(x)  (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF)) 
+#define  ISFCN_COFF(x)  (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
+#define  ISARY_COFF(x)  (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
+#define  ISTAG_COFF(x)  ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
+
+#define  INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
+#define  DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
+
+
+/*------------------------------------------------------------------------*/
+/*  AUXILIARY SYMBOL ENTRY                                                */
+/*------------------------------------------------------------------------*/
+union auxent
+{
+	struct
+	{
+		long            x_tagndx;       /* str, un, or enum tag indx */
+		union
+		{
+			struct
+			{
+				unsigned short  x_lnno; /* declaration line number */
+				unsigned short  x_size; /* str, union, array size */
+			} x_lnsz;
+			long    x_fsize;        /* size of function */
+		} x_misc;
+		union
+		{
+			struct                  /* if ISFCN, tag, or .bb */
+			{
+				long    x_lnnoptr;      /* ptr to fcn line # */
+				long    x_endndx;       /* entry ndx past block end */
+			}       x_fcn;
+			struct                  /* if ISARY, up to 4 dimen. */
+			{
+				unsigned short  x_dimen[DIMNUM];
+			}       x_ary;
+		}               x_fcnary;
+		unsigned short  x_regcount;   /* number of registers used by func */
+	}       x_sym;
+	struct
+	{
+		char    x_fname[FILNMLEN];
+	}       x_file;
+	struct
+	{
+		long    x_scnlen;          /* section length */
+		unsigned short  x_nreloc;  /* number of relocation entries */
+		unsigned short  x_nlinno;  /* number of line numbers */
+	}       x_scn;
+};
+
+#define SYMENT  struct syment
+#define SYMESZ  18      /* sizeof(SYMENT) */
+
+#define AUXENT  union auxent
+#define AUXESZ  18      /* sizeof(AUXENT) */
+
+/*------------------------------------------------------------------------*/
+/*  NAMES OF "SPECIAL" SYMBOLS                                            */
+/*------------------------------------------------------------------------*/
+#define _STEXT          ".text"
+#define _ETEXT          "etext"
+#define _SDATA          ".data"
+#define _EDATA          "edata"
+#define _SBSS           ".bss"
+#define _END            "end"
+#define _CINITPTR       "cinit"
+
+/*--------------------------------------------------------------------------*/
+/*  ENTRY POINT SYMBOLS                                                     */
+/*--------------------------------------------------------------------------*/
+#define _START          "_start"
+#define _MAIN           "_main"
+    /*  _CSTART         "_c_int00"          (defined in params.h)  */
+
+
+#define _TVORIG         "_tvorig"
+#define _TORIGIN        "_torigin"
+#define _DORIGIN        "_dorigin"
+
+#define _SORIGIN        "_sorigin"
diff --git a/tinyc/config.h b/tinyc/config.h
new file mode 100755
index 000000000..ceb34f784
--- /dev/null
+++ b/tinyc/config.h
@@ -0,0 +1,15 @@
+/* Modified to not rely on a configure script: */
+#define CONFIG_SYSROOT ""
+#define TCC_VERSION "0.9.25"
+
+#if defined(WIN32) || defined(_WIN32)
+#  define TCC_TARGET_PE   1
+#  define TCC_TARGET_I386

+#  define CONFIG_TCCDIR "."

+#else
+#  define TCC_TARGET_X86_64
+#  define CONFIG_TCCDIR "/usr/local/lib/tcc"
+#  define GCC_MAJOR 4
+#  define HOST_X86_64 1
+#endif
+
diff --git a/tinyc/config.mak b/tinyc/config.mak
new file mode 100755
index 000000000..1722d20b3
--- /dev/null
+++ b/tinyc/config.mak
@@ -0,0 +1,20 @@
+# Automatically generated by configure - do not modify
+prefix=/usr/local
+bindir=/usr/local/bin
+tccdir=/usr/local/lib/tcc
+libdir=/usr/local/lib
+includedir=/usr/local/include
+mandir=/usr/local/man
+docdir=/usr/local/share/doc/tcc
+CC=gcc
+GCC_MAJOR=4
+HOST_CC=gcc
+AR=ar
+STRIP=strip -s -R .comment -R .note
+CFLAGS=-O2
+LDFLAGS=
+LIBSUF=.a
+EXESUF=
+ARCH=x86-64
+VERSION=0.9.25
+SRC_PATH=/home/andreas/nimrod/tinyc
diff --git a/tinyc/config.texi b/tinyc/config.texi
new file mode 100755
index 000000000..2d90df0ee
--- /dev/null
+++ b/tinyc/config.texi
@@ -0,0 +1 @@
+@set VERSION 0.9.25
diff --git a/tinyc/config_edited.h b/tinyc/config_edited.h
new file mode 100755
index 000000000..ceb34f784
--- /dev/null
+++ b/tinyc/config_edited.h
@@ -0,0 +1,15 @@
+/* Modified to not rely on a configure script: */
+#define CONFIG_SYSROOT ""
+#define TCC_VERSION "0.9.25"
+
+#if defined(WIN32) || defined(_WIN32)
+#  define TCC_TARGET_PE   1
+#  define TCC_TARGET_I386

+#  define CONFIG_TCCDIR "."

+#else
+#  define TCC_TARGET_X86_64
+#  define CONFIG_TCCDIR "/usr/local/lib/tcc"
+#  define GCC_MAJOR 4
+#  define HOST_X86_64 1
+#endif
+
diff --git a/tinyc/elf.h b/tinyc/elf.h
new file mode 100755
index 000000000..82fd7ed91
--- /dev/null
+++ b/tinyc/elf.h
@@ -0,0 +1,1714 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ian Lance Taylor <ian@cygnus.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _ELF_H
+#define _ELF_H 1
+
+#ifndef _WIN32
+#include <inttypes.h>
+#else
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+#endif
+
+typedef unsigned char           uint8_t;
+typedef unsigned short int      uint16_t;
+typedef unsigned int            uint32_t;
+typedef unsigned long long int  uint64_t;
+#endif
+
+/* Standard ELF types.  */
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type of symbol indices.  */
+typedef uint32_t Elf32_Symndx;
+typedef uint64_t Elf64_Symndx;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
+  Elf32_Half    e_type;                 /* Object file type */
+  Elf32_Half    e_machine;              /* Architecture */
+  Elf32_Word    e_version;              /* Object file version */
+  Elf32_Addr    e_entry;                /* Entry point virtual address */
+  Elf32_Off     e_phoff;                /* Program header table file offset */
+  Elf32_Off     e_shoff;                /* Section header table file offset */
+  Elf32_Word    e_flags;                /* Processor-specific flags */
+  Elf32_Half    e_ehsize;               /* ELF header size in bytes */
+  Elf32_Half    e_phentsize;            /* Program header table entry size */
+  Elf32_Half    e_phnum;                /* Program header table entry count */
+  Elf32_Half    e_shentsize;            /* Section header table entry size */
+  Elf32_Half    e_shnum;                /* Section header table entry count */
+  Elf32_Half    e_shstrndx;             /* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char e_ident[EI_NIDENT];     /* Magic number and other info */
+  Elf64_Half    e_type;                 /* Object file type */
+  Elf64_Half    e_machine;              /* Architecture */
+  Elf64_Word    e_version;              /* Object file version */
+  Elf64_Addr    e_entry;                /* Entry point virtual address */
+  Elf64_Off     e_phoff;                /* Program header table file offset */
+  Elf64_Off     e_shoff;                /* Section header table file offset */
+  Elf64_Word    e_flags;                /* Processor-specific flags */
+  Elf64_Half    e_ehsize;               /* ELF header size in bytes */
+  Elf64_Half    e_phentsize;            /* Program header table entry size */
+  Elf64_Half    e_phnum;                /* Program header table entry count */
+  Elf64_Half    e_shentsize;            /* Section header table entry size */
+  Elf64_Half    e_shnum;                /* Section header table entry count */
+  Elf64_Half    e_shstrndx;             /* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0         0               /* File identification byte 0 index */
+#define ELFMAG0         0x7f            /* Magic number byte 0 */
+
+#define EI_MAG1         1               /* File identification byte 1 index */
+#define ELFMAG1         'E'             /* Magic number byte 1 */
+
+#define EI_MAG2         2               /* File identification byte 2 index */
+#define ELFMAG2         'L'             /* Magic number byte 2 */
+
+#define EI_MAG3         3               /* File identification byte 3 index */
+#define ELFMAG3         'F'             /* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define ELFMAG          "\177ELF"
+#define SELFMAG         4
+
+#define EI_CLASS        4               /* File class byte index */
+#define ELFCLASSNONE    0               /* Invalid class */
+#define ELFCLASS32      1               /* 32-bit objects */
+#define ELFCLASS64      2               /* 64-bit objects */
+#define ELFCLASSNUM     3
+
+#define EI_DATA         5               /* Data encoding byte index */
+#define ELFDATANONE     0               /* Invalid data encoding */
+#define ELFDATA2LSB     1               /* 2's complement, little endian */
+#define ELFDATA2MSB     2               /* 2's complement, big endian */
+#define ELFDATANUM      3
+
+#define EI_VERSION      6               /* File version byte index */
+                                        /* Value must be EV_CURRENT */
+
+#define EI_OSABI        7               /* OS ABI identification */
+#define ELFOSABI_SYSV           0       /* UNIX System V ABI */
+#define ELFOSABI_HPUX           1       /* HP-UX */
+#define ELFOSABI_FREEBSD        9       /* Free BSD */
+#define ELFOSABI_ARM            97      /* ARM */
+#define ELFOSABI_STANDALONE     255     /* Standalone (embedded) application */
+
+#define EI_ABIVERSION   8               /* ABI version */
+
+#define EI_PAD          9               /* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE         0               /* No file type */
+#define ET_REL          1               /* Relocatable file */
+#define ET_EXEC         2               /* Executable file */
+#define ET_DYN          3               /* Shared object file */
+#define ET_CORE         4               /* Core file */
+#define ET_NUM          5               /* Number of defined types */
+#define ET_LOPROC       0xff00          /* Processor-specific */
+#define ET_HIPROC       0xffff          /* Processor-specific */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE          0              /* No machine */
+#define EM_M32           1              /* AT&T WE 32100 */
+#define EM_SPARC         2              /* SUN SPARC */
+#define EM_386           3              /* Intel 80386 */
+#define EM_68K           4              /* Motorola m68k family */
+#define EM_88K           5              /* Motorola m88k family */
+#define EM_486           6              /* Intel 80486 */
+#define EM_860           7              /* Intel 80860 */
+#define EM_MIPS          8              /* MIPS R3000 big-endian */
+#define EM_S370          9              /* Amdahl */
+#define EM_MIPS_RS4_BE  10              /* MIPS R4000 big-endian */
+#define EM_RS6000       11              /* RS6000 */
+
+#define EM_PARISC       15              /* HPPA */
+#define EM_nCUBE        16              /* nCUBE */
+#define EM_VPP500       17              /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS  18              /* Sun's "v8plus" */
+#define EM_960          19              /* Intel 80960 */
+#define EM_PPC          20              /* PowerPC */
+
+#define EM_V800         36              /* NEC V800 series */
+#define EM_FR20         37              /* Fujitsu FR20 */
+#define EM_RH32         38              /* TRW RH32 */
+#define EM_RCE          39              /* Motorola RCE */
+#define EM_ARM          40              /* ARM */
+#define EM_FAKE_ALPHA   41              /* Digital Alpha */
+#define EM_SH           42              /* Hitachi SH */
+#define EM_SPARCV9      43              /* SPARC v9 64-bit */
+#define EM_TRICORE      44              /* Siemens Tricore */
+#define EM_ARC          45              /* Argonaut RISC Core */
+#define EM_H8_300       46              /* Hitachi H8/300 */
+#define EM_H8_300H      47              /* Hitachi H8/300H */
+#define EM_H8S          48              /* Hitachi H8S */
+#define EM_H8_500       49              /* Hitachi H8/500 */
+#define EM_IA_64        50              /* Intel Merced */
+#define EM_MIPS_X       51              /* Stanford MIPS-X */
+#define EM_COLDFIRE     52              /* Motorola Coldfire */
+#define EM_68HC12       53              /* Motorola M68HC12 */
+#define EM_MMA          54              /* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP          55              /* Siemens PCP */
+#define EM_NCPU         56              /* Sony nCPU embeeded RISC */
+#define EM_NDR1         57              /* Denso NDR1 microprocessor */
+#define EM_STARCORE     58              /* Motorola Start*Core processor */
+#define EM_ME16         59              /* Toyota ME16 processor */
+#define EM_ST100        60              /* STMicroelectronic ST100 processor */
+#define EM_TINYJ        61              /* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64       62              /* AMD x86-64 architecture */
+#define EM_PDSP         63              /* Sony DSP Processor */
+#define EM_FX66         66              /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS      67              /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7          68              /* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16       69              /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11       70              /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08       71              /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05       72              /* Motorola MC68HC05 microcontroller */
+#define EM_SVX          73              /* Silicon Graphics SVx */
+#define EM_ST19         74              /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX          75              /* Digital VAX */
+#define EM_CRIS         76              /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN      77              /* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH     78              /* Element 14 64-bit DSP Processor */
+#define EM_ZSP          79              /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX         80              /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY        81              /* Harvard University machine-independent object files */
+#define EM_PRISM        82              /* SiTera Prism */
+#define EM_AVR          83              /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30         84              /* Fujitsu FR30 */
+#define EM_D10V         85              /* Mitsubishi D10V */
+#define EM_D30V         86              /* Mitsubishi D30V */
+#define EM_V850         87              /* NEC v850 */
+#define EM_M32R         88              /* Mitsubishi M32R */
+#define EM_MN10300      89              /* Matsushita MN10300 */
+#define EM_MN10200      90              /* Matsushita MN10200 */
+#define EM_PJ           91              /* picoJava */
+#define EM_OPENRISC     92              /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5       93              /* ARC Cores Tangent-A5 */
+#define EM_XTENSA       94              /* Tensilica Xtensa Architecture */
+#define EM_NUM          95
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA        0x9026
+#define EM_C60          0x9c60
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE         0               /* Invalid ELF version */
+#define EV_CURRENT      1               /* Current version */
+#define EV_NUM          2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word    sh_name;                /* Section name (string tbl index) */
+  Elf32_Word    sh_type;                /* Section type */
+  Elf32_Word    sh_flags;               /* Section flags */
+  Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
+  Elf32_Off     sh_offset;              /* Section file offset */
+  Elf32_Word    sh_size;                /* Section size in bytes */
+  Elf32_Word    sh_link;                /* Link to another section */
+  Elf32_Word    sh_info;                /* Additional section information */
+  Elf32_Word    sh_addralign;           /* Section alignment */
+  Elf32_Word    sh_entsize;             /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word    sh_name;                /* Section name (string tbl index) */
+  Elf64_Word    sh_type;                /* Section type */
+  Elf64_Xword   sh_flags;               /* Section flags */
+  Elf64_Addr    sh_addr;                /* Section virtual addr at execution */
+  Elf64_Off     sh_offset;              /* Section file offset */
+  Elf64_Xword   sh_size;                /* Section size in bytes */
+  Elf64_Word    sh_link;                /* Link to another section */
+  Elf64_Word    sh_info;                /* Additional section information */
+  Elf64_Xword   sh_addralign;           /* Section alignment */
+  Elf64_Xword   sh_entsize;             /* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF       0               /* Undefined section */
+#define SHN_LORESERVE   0xff00          /* Start of reserved indices */
+#define SHN_LOPROC      0xff00          /* Start of processor-specific */
+#define SHN_HIPROC      0xff1f          /* End of processor-specific */
+#define SHN_ABS         0xfff1          /* Associated symbol is absolute */
+#define SHN_COMMON      0xfff2          /* Associated symbol is common */
+#define SHN_HIRESERVE   0xffff          /* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL         0              /* Section header table entry unused */
+#define SHT_PROGBITS     1              /* Program data */
+#define SHT_SYMTAB       2              /* Symbol table */
+#define SHT_STRTAB       3              /* String table */
+#define SHT_RELA         4              /* Relocation entries with addends */
+#define SHT_HASH         5              /* Symbol hash table */
+#define SHT_DYNAMIC      6              /* Dynamic linking information */
+#define SHT_NOTE         7              /* Notes */
+#define SHT_NOBITS       8              /* Program space with no data (bss) */
+#define SHT_REL          9              /* Relocation entries, no addends */
+#define SHT_SHLIB        10             /* Reserved */
+#define SHT_DYNSYM       11             /* Dynamic linker symbol table */
+#define SHT_NUM          12             /* Number of defined types.  */
+#define SHT_LOOS         0x60000000     /* Start OS-specific */
+#define SHT_LOSUNW       0x6ffffffb     /* Sun-specific low bound.  */
+#define SHT_SUNW_COMDAT  0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef   0x6ffffffd     /* Version definition section.  */
+#define SHT_GNU_verneed  0x6ffffffe     /* Version needs section.  */
+#define SHT_GNU_versym   0x6fffffff     /* Version symbol table.  */
+#define SHT_HISUNW       0x6fffffff     /* Sun-specific high bound.  */
+#define SHT_HIOS         0x6fffffff     /* End OS-specific type */
+#define SHT_LOPROC       0x70000000     /* Start of processor-specific */
+#define SHT_ARM_EXIDX    0x70000001     /* Exception Index table */
+#define SHT_ARM_PREEMPTMAP 0x70000002   /* dynamic linking pre-emption map */
+#define SHT_ARM_ATTRIBUTES 0x70000003   /* Object file compatibility attrs */
+#define SHT_HIPROC       0x7fffffff     /* End of processor-specific */
+#define SHT_LOUSER       0x80000000     /* Start of application-specific */
+#define SHT_HIUSER       0x8fffffff     /* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE       (1 << 0)        /* Writable */
+#define SHF_ALLOC       (1 << 1)        /* Occupies memory during execution */
+#define SHF_EXECINSTR   (1 << 2)        /* Executable */
+#define SHF_MASKPROC    0xf0000000      /* Processor-specific */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
+  Elf32_Addr    st_value;               /* Symbol value */
+  Elf32_Word    st_size;                /* Symbol size */
+  unsigned char st_info;                /* Symbol type and binding */
+  unsigned char st_other;               /* No defined meaning, 0 */
+  Elf32_Section st_shndx;               /* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word    st_name;                /* Symbol name (string tbl index) */
+  unsigned char st_info;                /* Symbol type and binding */
+  unsigned char st_other;               /* No defined meaning, 0 */
+  Elf64_Section st_shndx;               /* Section index */
+  Elf64_Addr    st_value;               /* Symbol value */
+  Elf64_Xword   st_size;                /* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;                /* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;                  /* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;                /* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;                  /* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF         0xffff  /* Symbol bound to self */
+#define SYMINFO_BT_PARENT       0xfffe  /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE   0xff00  /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT      0x0001  /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU    0x0002  /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY        0x0004  /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD    0x0008  /* Symbol bound to object to be lazy
+                                           loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE            0
+#define SYMINFO_CURRENT         1
+#define SYMINFO_NUM             2
+
+
+/* Special section index.  */
+
+#define SHN_UNDEF       0               /* No section, undefined symbol.  */
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)              (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)              ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)              ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)              ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)       ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL       0               /* Local symbol */
+#define STB_GLOBAL      1               /* Global symbol */
+#define STB_WEAK        2               /* Weak symbol */
+#define STB_NUM         3               /* Number of defined types.  */
+#define STB_LOOS        10              /* Start of OS-specific */
+#define STB_HIOS        12              /* End of OS-specific */
+#define STB_LOPROC      13              /* Start of processor-specific */
+#define STB_HIPROC      15              /* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE      0               /* Symbol type is unspecified */
+#define STT_OBJECT      1               /* Symbol is a data object */
+#define STT_FUNC        2               /* Symbol is a code object */
+#define STT_SECTION     3               /* Symbol associated with a section */
+#define STT_FILE        4               /* Symbol's name is file name */
+#define STT_NUM         5               /* Number of defined types.  */
+#define STT_LOOS        11              /* Start of OS-specific */
+#define STT_HIOS        12              /* End of OS-specific */
+#define STT_LOPROC      13              /* Start of processor-specific */
+#define STT_HIPROC      15              /* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF       0               /* End of a chain.  */
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)  ((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)  ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT     0               /* Default symbol visibility rules */
+#define STV_INTERNAL    1               /* Processor specific hidden class */
+#define STV_HIDDEN      2               /* Sym unavailable in other modules */
+#define STV_PROTECTED   3               /* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr    r_offset;               /* Address */
+  Elf32_Word    r_info;                 /* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr    r_offset;               /* Address */
+  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr    r_offset;               /* Address */
+  Elf32_Word    r_info;                 /* Relocation type and symbol index */
+  Elf32_Sword   r_addend;               /* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr    r_offset;               /* Address */
+  Elf64_Xword   r_info;                 /* Relocation type and symbol index */
+  Elf64_Sxword  r_addend;               /* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)                ((val) >> 8)
+#define ELF32_R_TYPE(val)               ((val) & 0xff)
+#define ELF32_R_INFO(sym, type)         (((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)                  ((i) >> 32)
+#define ELF64_R_TYPE(i)                 ((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)          ((((Elf64_Xword)(sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word    p_type;                 /* Segment type */
+  Elf32_Off     p_offset;               /* Segment file offset */
+  Elf32_Addr    p_vaddr;                /* Segment virtual address */
+  Elf32_Addr    p_paddr;                /* Segment physical address */
+  Elf32_Word    p_filesz;               /* Segment size in file */
+  Elf32_Word    p_memsz;                /* Segment size in memory */
+  Elf32_Word    p_flags;                /* Segment flags */
+  Elf32_Word    p_align;                /* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word    p_type;                 /* Segment type */
+  Elf64_Word    p_flags;                /* Segment flags */
+  Elf64_Off     p_offset;               /* Segment file offset */
+  Elf64_Addr    p_vaddr;                /* Segment virtual address */
+  Elf64_Addr    p_paddr;                /* Segment physical address */
+  Elf64_Xword   p_filesz;               /* Segment size in file */
+  Elf64_Xword   p_memsz;                /* Segment size in memory */
+  Elf64_Xword   p_align;                /* Segment alignment */
+} Elf64_Phdr;
+
+/* Legal values for p_type (segment type).  */
+
+#define PT_NULL         0               /* Program header table entry unused */
+#define PT_LOAD         1               /* Loadable program segment */
+#define PT_DYNAMIC      2               /* Dynamic linking information */
+#define PT_INTERP       3               /* Program interpreter */
+#define PT_NOTE         4               /* Auxiliary information */
+#define PT_SHLIB        5               /* Reserved */
+#define PT_PHDR         6               /* Entry for header table itself */
+#define PT_NUM          7               /* Number of defined types.  */
+#define PT_LOOS         0x60000000      /* Start of OS-specific */
+#define PT_HIOS         0x6fffffff      /* End of OS-specific */
+#define PT_LOPROC       0x70000000      /* Start of processor-specific */
+#define PT_HIPROC       0x7fffffff      /* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X            (1 << 0)        /* Segment is executable */
+#define PF_W            (1 << 1)        /* Segment is writable */
+#define PF_R            (1 << 2)        /* Segment is readable */
+#define PF_MASKPROC     0xf0000000      /* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS     1               /* Contains copy of prstatus struct */
+#define NT_FPREGSET     2               /* Contains copy of fpregset struct */
+#define NT_PRPSINFO     3               /* Contains copy of prpsinfo struct */
+#define NT_PRXREG       4               /* Contains copy of prxregset struct */
+#define NT_PLATFORM     5               /* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV         6               /* Contains copy of auxv array */
+#define NT_GWINDOWS     7               /* Contains copy of gwindows struct */
+#define NT_PSTATUS      10              /* Contains copy of pstatus struct */
+#define NT_PSINFO       13              /* Contains copy of psinfo struct */
+#define NT_PRCRED       14              /* Contains copy of prcred struct */
+#define NT_UTSNAME      15              /* Contains copy of utsname struct */
+#define NT_LWPSTATUS    16              /* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO     17              /* Contains copy of lwpinfo struct */
+
+/* Legal values for the  note segment descriptor types for object files.  */
+
+#define NT_VERSION      1               /* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword   d_tag;                  /* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;                 /* Integer value */
+      Elf32_Addr d_ptr;                 /* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword  d_tag;                  /* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;                /* Integer value */
+      Elf64_Addr d_ptr;                 /* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL         0               /* Marks end of dynamic section */
+#define DT_NEEDED       1               /* Name of needed library */
+#define DT_PLTRELSZ     2               /* Size in bytes of PLT relocs */
+#define DT_PLTGOT       3               /* Processor defined value */
+#define DT_HASH         4               /* Address of symbol hash table */
+#define DT_STRTAB       5               /* Address of string table */
+#define DT_SYMTAB       6               /* Address of symbol table */
+#define DT_RELA         7               /* Address of Rela relocs */
+#define DT_RELASZ       8               /* Total size of Rela relocs */
+#define DT_RELAENT      9               /* Size of one Rela reloc */
+#define DT_STRSZ        10              /* Size of string table */
+#define DT_SYMENT       11              /* Size of one symbol table entry */
+#define DT_INIT         12              /* Address of init function */
+#define DT_FINI         13              /* Address of termination function */
+#define DT_SONAME       14              /* Name of shared object */
+#define DT_RPATH        15              /* Library search path */
+#define DT_SYMBOLIC     16              /* Start symbol search here */
+#define DT_REL          17              /* Address of Rel relocs */
+#define DT_RELSZ        18              /* Total size of Rel relocs */
+#define DT_RELENT       19              /* Size of one Rel reloc */
+#define DT_PLTREL       20              /* Type of reloc in PLT */
+#define DT_DEBUG        21              /* For debugging; unspecified */
+#define DT_TEXTREL      22              /* Reloc might modify .text */
+#define DT_JMPREL       23              /* Address of PLT relocs */
+#define DT_BIND_NOW     24              /* Process relocations of object */
+#define DT_INIT_ARRAY   25              /* Array with addresses of init fct */
+#define DT_FINI_ARRAY   26              /* Array with addresses of fini fct */
+#define DT_INIT_ARRAYSZ 27              /* Size in bytes of DT_INIT_ARRAY */
+#define DT_FINI_ARRAYSZ 28              /* Size in bytes of DT_FINI_ARRAY */
+#define DT_NUM          29              /* Number used */
+#define DT_LOOS         0x60000000      /* Start of OS-specific */
+#define DT_HIOS         0x6fffffff      /* End of OS-specific */
+#define DT_LOPROC       0x70000000      /* Start of processor-specific */
+#define DT_HIPROC       0x7fffffff      /* End of processor-specific */
+#define DT_PROCNUM      DT_MIPS_NUM     /* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO     0x6ffffd00
+#define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting
+                                           the following DT_* entry.  */
+#define DT_SYMINSZ      0x6ffffdfe      /* Size of syminfo table (in bytes) */
+#define DT_SYMINENT     0x6ffffdff      /* Entry size of syminfo */
+#define DT_VALRNGHI     0x6ffffdff
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO    0x6ffffe00
+#define DT_SYMINFO      0x6ffffeff      /* syminfo table */
+#define DT_ADDRRNGHI    0x6ffffeff
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM       0x6ffffff0
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1      0x6ffffffb      /* State flags, see DF_1_* below.  */
+#define DT_VERDEF       0x6ffffffc      /* Address of version definition
+                                           table */
+#define DT_VERDEFNUM    0x6ffffffd      /* Number of version definitions */
+#define DT_VERNEED      0x6ffffffe      /* Address of table with needed
+                                           versions */
+#define DT_VERNEEDNUM   0x6fffffff      /* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)     ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM     3
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW        0x00000001      /* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL     0x00000002      /* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP      0x00000004      /* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE   0x00000008      /* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR   0x00000010      /* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST  0x00000020      /* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN     0x00000040      /* Set RTLD_NOOPEN for this object.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half    vd_version;             /* Version revision */
+  Elf32_Half    vd_flags;               /* Version information */
+  Elf32_Half    vd_ndx;                 /* Version Index */
+  Elf32_Half    vd_cnt;                 /* Number of associated aux entries */
+  Elf32_Word    vd_hash;                /* Version name hash value */
+  Elf32_Word    vd_aux;                 /* Offset in bytes to verdaux array */
+  Elf32_Word    vd_next;                /* Offset in bytes to next verdef
+                                           entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half    vd_version;             /* Version revision */
+  Elf64_Half    vd_flags;               /* Version information */
+  Elf64_Half    vd_ndx;                 /* Version Index */
+  Elf64_Half    vd_cnt;                 /* Number of associated aux entries */
+  Elf64_Word    vd_hash;                /* Version name hash value */
+  Elf64_Word    vd_aux;                 /* Offset in bytes to verdaux array */
+  Elf64_Word    vd_next;                /* Offset in bytes to next verdef
+                                           entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE    0               /* No version */
+#define VER_DEF_CURRENT 1               /* Current version */
+#define VER_DEF_NUM     2               /* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE    0x1             /* Version definition of file itself */
+#define VER_FLG_WEAK    0x2             /* Weak version identifier */
+
+/* Auxialiary version information.  */
+
+typedef struct
+{
+  Elf32_Word    vda_name;               /* Version or dependency names */
+  Elf32_Word    vda_next;               /* Offset in bytes to next verdaux
+                                           entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word    vda_name;               /* Version or dependency names */
+  Elf64_Word    vda_next;               /* Offset in bytes to next verdaux
+                                           entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half    vn_version;             /* Version of structure */
+  Elf32_Half    vn_cnt;                 /* Number of associated aux entries */
+  Elf32_Word    vn_file;                /* Offset of filename for this
+                                           dependency */
+  Elf32_Word    vn_aux;                 /* Offset in bytes to vernaux array */
+  Elf32_Word    vn_next;                /* Offset in bytes to next verneed
+                                           entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half    vn_version;             /* Version of structure */
+  Elf64_Half    vn_cnt;                 /* Number of associated aux entries */
+  Elf64_Word    vn_file;                /* Offset of filename for this
+                                           dependency */
+  Elf64_Word    vn_aux;                 /* Offset in bytes to vernaux array */
+  Elf64_Word    vn_next;                /* Offset in bytes to next verneed
+                                           entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE    0              /* No version */
+#define VER_NEED_CURRENT 1              /* Current version */
+#define VER_NEED_NUM     2              /* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word    vna_hash;               /* Hash value of dependency name */
+  Elf32_Half    vna_flags;              /* Dependency specific information */
+  Elf32_Half    vna_other;              /* Unused */
+  Elf32_Word    vna_name;               /* Dependency name string offset */
+  Elf32_Word    vna_next;               /* Offset in bytes to next vernaux
+                                           entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word    vna_hash;               /* Hash value of dependency name */
+  Elf64_Half    vna_flags;              /* Dependency specific information */
+  Elf64_Half    vna_other;              /* Unused */
+  Elf64_Word    vna_name;               /* Dependency name string offset */
+  Elf64_Word    vna_next;               /* Offset in bytes to next vernaux
+                                           entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK    0x2             /* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  int a_type;                   /* Entry type */
+  union
+    {
+      long int a_val;           /* Integer value */
+      void *a_ptr;              /* Pointer value */
+      void (*a_fcn) (void);     /* Function pointer value */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  long int a_type;              /* Entry type */
+  union
+    {
+      long int a_val;           /* Integer value */
+      void *a_ptr;              /* Pointer value */
+      void (*a_fcn) (void);     /* Function pointer value */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL         0               /* End of vector */
+#define AT_IGNORE       1               /* Entry should be ignored */
+#define AT_EXECFD       2               /* File descriptor of program */
+#define AT_PHDR         3               /* Program headers for program */
+#define AT_PHENT        4               /* Size of program header entry */
+#define AT_PHNUM        5               /* Number of program headers */
+#define AT_PAGESZ       6               /* System page size */
+#define AT_BASE         7               /* Base address of interpreter */
+#define AT_FLAGS        8               /* Flags */
+#define AT_ENTRY        9               /* Entry point of program */
+#define AT_NOTELF       10              /* Program is not ELF */
+#define AT_UID          11              /* Real uid */
+#define AT_EUID         12              /* Effective uid */
+#define AT_GID          13              /* Real gid */
+#define AT_EGID         14              /* Effective gid */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM     15              /* String identifying platform.  */
+#define AT_HWCAP        16              /* Machine dependent hints about
+                                           processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW        17              /* Used FPU control word.  */
+
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;                  /* Length of the note's name.  */
+  Elf32_Word n_descsz;                  /* Length of the note's descriptor.  */
+  Elf32_Word n_type;                    /* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;                  /* Length of the note's name.  */
+  Elf64_Word n_descsz;                  /* Length of the note's descriptor.  */
+  Elf64_Word n_type;                    /* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS        "SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU            "GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT  1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define ELF_NOTE_ABI            1
+
+/* Known OSes.  These value can appear in word 0 of an ELF_NOTE_ABI
+   note section entry.  */
+#define ELF_NOTE_OS_LINUX       0
+#define ELF_NOTE_OS_GNU         1
+#define ELF_NOTE_OS_SOLARIS2    2
+
+
+/* Motorola 68k specific definitions.  */
+
+/* m68k relocs.  */
+
+#define R_68K_NONE      0               /* No reloc */
+#define R_68K_32        1               /* Direct 32 bit  */
+#define R_68K_16        2               /* Direct 16 bit  */
+#define R_68K_8         3               /* Direct 8 bit  */
+#define R_68K_PC32      4               /* PC relative 32 bit */
+#define R_68K_PC16      5               /* PC relative 16 bit */
+#define R_68K_PC8       6               /* PC relative 8 bit */
+#define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
+#define R_68K_GOT16     8               /* 16 bit PC relative GOT entry */
+#define R_68K_GOT8      9               /* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O    10              /* 32 bit GOT offset */
+#define R_68K_GOT16O    11              /* 16 bit GOT offset */
+#define R_68K_GOT8O     12              /* 8 bit GOT offset */
+#define R_68K_PLT32     13              /* 32 bit PC relative PLT address */
+#define R_68K_PLT16     14              /* 16 bit PC relative PLT address */
+#define R_68K_PLT8      15              /* 8 bit PC relative PLT address */
+#define R_68K_PLT32O    16              /* 32 bit PLT offset */
+#define R_68K_PLT16O    17              /* 16 bit PLT offset */
+#define R_68K_PLT8O     18              /* 8 bit PLT offset */
+#define R_68K_COPY      19              /* Copy symbol at runtime */
+#define R_68K_GLOB_DAT  20              /* Create GOT entry */
+#define R_68K_JMP_SLOT  21              /* Create PLT entry */
+#define R_68K_RELATIVE  22              /* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_68K_NUM       23
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE      0               /* No reloc */
+#define R_386_32        1               /* Direct 32 bit  */
+#define R_386_PC32      2               /* PC relative 32 bit */
+#define R_386_GOT32     3               /* 32 bit GOT entry */
+#define R_386_PLT32     4               /* 32 bit PLT address */
+#define R_386_COPY      5               /* Copy symbol at runtime */
+#define R_386_GLOB_DAT  6               /* Create GOT entry */
+#define R_386_JMP_SLOT  7               /* Create PLT entry */
+#define R_386_RELATIVE  8               /* Adjust by program base */
+#define R_386_GOTOFF    9               /* 32 bit offset to GOT */
+#define R_386_GOTPC     10              /* 32 bit PC relative offset to GOT */
+/* Keep this the last entry.  */
+#define R_386_NUM       11
+
+/* SUN SPARC specific definitions.  */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM           3
+#define EF_SPARCV9_TSO          0
+#define EF_SPARCV9_PSO          1
+#define EF_SPARCV9_RMO          2
+#define EF_SPARC_EXT_MASK       0xFFFF00
+#define EF_SPARC_SUN_US1        0x000200
+#define EF_SPARC_HAL_R1         0x000400
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE    0               /* No reloc */
+#define R_SPARC_8       1               /* Direct 8 bit */
+#define R_SPARC_16      2               /* Direct 16 bit */
+#define R_SPARC_32      3               /* Direct 32 bit */
+#define R_SPARC_DISP8   4               /* PC relative 8 bit */
+#define R_SPARC_DISP16  5               /* PC relative 16 bit */
+#define R_SPARC_DISP32  6               /* PC relative 32 bit */
+#define R_SPARC_WDISP30 7               /* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22 8               /* PC relative 22 bit shifted */
+#define R_SPARC_HI22    9               /* High 22 bit */
+#define R_SPARC_22      10              /* Direct 22 bit */
+#define R_SPARC_13      11              /* Direct 13 bit */
+#define R_SPARC_LO10    12              /* Truncated 10 bit */
+#define R_SPARC_GOT10   13              /* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13   14              /* 13 bit GOT entry */
+#define R_SPARC_GOT22   15              /* 22 bit GOT entry shifted */
+#define R_SPARC_PC10    16              /* PC relative 10 bit truncated */
+#define R_SPARC_PC22    17              /* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30  18              /* 30 bit PC relative PLT address */
+#define R_SPARC_COPY    19              /* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT 20             /* Create GOT entry */
+#define R_SPARC_JMP_SLOT 21             /* Create PLT entry */
+#define R_SPARC_RELATIVE 22             /* Adjust by program base */
+#define R_SPARC_UA32    23              /* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32   24              /* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22 25              /* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10 26              /* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32 27              /* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22 28              /* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10 29              /* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10      30              /* Direct 10 bit */
+#define R_SPARC_11      31              /* Direct 11 bit */
+#define R_SPARC_64      32              /* Direct 64 bit */
+#define R_SPARC_OLO10   33              /* ?? */
+#define R_SPARC_HH22    34              /* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10    35              /* High middle 10 bits of ... */
+#define R_SPARC_LM22    36              /* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22 37              /* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10 38              /* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22 39              /* Low miggle 22 bits of ... */
+#define R_SPARC_WDISP16 40              /* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19 41              /* PC relative 19 bit shifted */
+#define R_SPARC_7       43              /* Direct 7 bit */
+#define R_SPARC_5       44              /* Direct 5 bit */
+#define R_SPARC_6       45              /* Direct 6 bit */
+#define R_SPARC_DISP64  46              /* PC relative 64 bit */
+#define R_SPARC_PLT64   47              /* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22   48              /* High 22 bit complemented */
+#define R_SPARC_LOX10   49              /* Truncated 11 bit complemented */
+#define R_SPARC_H44     50              /* Direct high 12 of 44 bit */
+#define R_SPARC_M44     51              /* Direct mid 22 of 44 bit */
+#define R_SPARC_L44     52              /* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER 53             /* Global register usage */
+#define R_SPARC_UA64    54              /* Direct 64 bit unaligned */
+#define R_SPARC_UA16    55              /* Direct 16 bit unaligned */
+/* Keep this the last entry.  */
+#define R_SPARC_NUM     56
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+
+#define R_X86_64_NUM		24
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM    2
+
+/* Bits present in AT_HWCAP, primarily for Sparc32.  */
+
+#define HWCAP_SPARC_FLUSH       1       /* The cpu supports flush insn.  */
+#define HWCAP_SPARC_STBAR       2
+#define HWCAP_SPARC_SWAP        4
+#define HWCAP_SPARC_MULDIV      8
+#define HWCAP_SPARC_V9          16      /* The cpu is v9, so v8plus is ok.  */
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1           /* A .noreorder directive was used */
+#define EF_MIPS_PIC         2           /* Contains PIC code */
+#define EF_MIPS_CPIC        4           /* Uses PIC calling sequence */
+#define EF_MIPS_XGOT        8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2        32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH        0xf0000000  /* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1      0x00000000  /* -mips1 code.  */
+#define EF_MIPS_ARCH_2      0x10000000  /* -mips2 code.  */
+#define EF_MIPS_ARCH_3      0x20000000  /* -mips3 code.  */
+#define EF_MIPS_ARCH_4      0x30000000  /* -mips4 code.  */
+#define EF_MIPS_ARCH_5      0x40000000  /* -mips5 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1     0x00000000    /* -mips1 code.  */
+#define E_MIPS_ARCH_2     0x10000000    /* -mips2 code.  */
+#define E_MIPS_ARCH_3     0x20000000    /* -mips3 code.  */
+#define E_MIPS_ARCH_4     0x30000000    /* -mips4 code.  */
+#define E_MIPS_ARCH_5     0x40000000    /* -mips5 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON 0xff00         /* Allocated common symbols */
+#define SHN_MIPS_TEXT    0xff01         /* Allocated test symbols.  */
+#define SHN_MIPS_DATA    0xff02         /* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON 0xff03         /* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04      /* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM          0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB         0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE         0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG         0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD          0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR          0x70000010
+#define SHT_MIPS_FDESC         0x70000011
+#define SHT_MIPS_EXTSYM        0x70000012
+#define SHT_MIPS_DENSE         0x70000013
+#define SHT_MIPS_PDESC         0x70000014
+#define SHT_MIPS_LOCSYM        0x70000015
+#define SHT_MIPS_AUXSYM        0x70000016
+#define SHT_MIPS_OPTSYM        0x70000017
+#define SHT_MIPS_LOCSTR        0x70000018
+#define SHT_MIPS_LINE          0x70000019
+#define SHT_MIPS_RFDESC        0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS        0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE         0x70000023
+#define SHT_MIPS_XLATE         0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL         0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL   0x10000000     /* Must be part of global data area */
+#define SHF_MIPS_MERGE   0x20000000
+#define SHF_MIPS_ADDR    0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL   0x04000000
+#define SHF_MIPS_NAMES   0x02000000
+#define SHF_MIPS_NODUPE  0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT                0x0
+#define STO_MIPS_INTERNAL               0x1
+#define STO_MIPS_HIDDEN                 0x2
+#define STO_MIPS_PROTECTED              0x3
+#define STO_MIPS_SC_ALIGN_UNUSED        0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON           13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;    /* -G value used for compilation */
+      Elf32_Word gt_unused;             /* Not used */
+    } gt_header;                        /* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;            /* If this value were used for -G */
+      Elf32_Word gt_bytes;              /* This many bytes would be used */
+    } gt_entry;                         /* Subsequent entries in section */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word    ri_gprmask;             /* General registers used */
+  Elf32_Word    ri_cprmask[4];          /* Coprocessor registers used */
+  Elf32_Sword   ri_gp_value;            /* $gp register value */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;           /* Determines interpretation of the
+                                   variable part of descriptor.  */
+  unsigned char size;           /* Size of descriptor, including header.  */
+  Elf32_Section section;        /* Section header index of section affected,
+                                   0 for global options.  */
+  Elf32_Word info;              /* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL        0       /* Undefined.  */
+#define ODK_REGINFO     1       /* Register usage information.  */
+#define ODK_EXCEPTIONS  2       /* Exception processing options.  */
+#define ODK_PAD         3       /* Section padding options.  */
+#define ODK_HWPATCH     4       /* Hardware workarounds performed */
+#define ODK_FILL        5       /* record the fill value used by the linker. */
+#define ODK_TAGS        6       /* reserve space for desktop tools to write. */
+#define ODK_HWAND       7       /* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR        8       /* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN     0x1f    /* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX     0x1f00  /* FPE's which MAY be enabled.  */
+#define OEX_PAGE0       0x10000 /* page zero must be mapped.  */
+#define OEX_SMM         0x20000 /* Force sequential memory mode?  */
+#define OEX_FPDBUG      0x40000 /* Force floating point debug mode?  */
+#define OEX_PRECISEFP   OEX_FPDBUG
+#define OEX_DISMISS     0x80000 /* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL   0x10
+#define OEX_FPU_DIV0    0x08
+#define OEX_FPU_OFLO    0x04
+#define OEX_FPU_UFLO    0x02
+#define OEX_FPU_INEX    0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP      0x1     /* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH   0x2     /* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP      0x4     /* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL     0x8     /* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX     0x1
+#define OPAD_POSTFIX    0x2
+#define OPAD_SYMBOL     0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;        /* Extra flags.  */
+  Elf32_Word hwp_flags2;        /* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED    0x00000001
+#define OHWA1_R4KEOP_CLEAN      0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE             0       /* No reloc */
+#define R_MIPS_16               1       /* Direct 16 bit */
+#define R_MIPS_32               2       /* Direct 32 bit */
+#define R_MIPS_REL32            3       /* PC relative 32 bit */
+#define R_MIPS_26               4       /* Direct 26 bit shifted */
+#define R_MIPS_HI16             5       /* High 16 bit */
+#define R_MIPS_LO16             6       /* Low 16 bit */
+#define R_MIPS_GPREL16          7       /* GP relative 16 bit */
+#define R_MIPS_LITERAL          8       /* 16 bit literal entry */
+#define R_MIPS_GOT16            9       /* 16 bit GOT entry */
+#define R_MIPS_PC16             10      /* PC relative 16 bit */
+#define R_MIPS_CALL16           11      /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32          12      /* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5           16
+#define R_MIPS_SHIFT6           17
+#define R_MIPS_64               18
+#define R_MIPS_GOT_DISP         19
+#define R_MIPS_GOT_PAGE         20
+#define R_MIPS_GOT_OFST         21
+#define R_MIPS_GOT_HI16         22
+#define R_MIPS_GOT_LO16         23
+#define R_MIPS_SUB              24
+#define R_MIPS_INSERT_A         25
+#define R_MIPS_INSERT_B         26
+#define R_MIPS_DELETE           27
+#define R_MIPS_HIGHER           28
+#define R_MIPS_HIGHEST          29
+#define R_MIPS_CALL_HI16        30
+#define R_MIPS_CALL_LO16        31
+#define R_MIPS_SCN_DISP         32
+#define R_MIPS_REL16            33
+#define R_MIPS_ADD_IMMEDIATE    34
+#define R_MIPS_PJUMP            35
+#define R_MIPS_RELGOT           36
+#define R_MIPS_JALR             37
+/* Keep this the last entry.  */
+#define R_MIPS_NUM              38
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO 0x70000000      /* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001      /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL   0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001 /* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002 /* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003 /* Checksum */
+#define DT_MIPS_IVERSION     0x70000004 /* Version string (string tbl index) */
+#define DT_MIPS_FLAGS        0x70000005 /* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
+#define DT_MIPS_MSYM         0x70000007
+#define DT_MIPS_CONFLICT     0x70000008 /* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST      0x70000009 /* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a /* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b /* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010 /* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011 /* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012 /* First external DYNSYM */
+#define DT_MIPS_GOTSYM       0x70000013 /* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014 /* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP      0x70000016 /* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017 /* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+                                                DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+                                                DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+                                             DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+                                           relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+                                           DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+                                             class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+                                                DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS      0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+                                                    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+                                           by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+#define DT_MIPS_NUM          0x32
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE                   0            /* No flags */
+#define RHF_QUICKSTART             (1 << 0)     /* Use quickstart */
+#define RHF_NOTPOT                 (1 << 1)     /* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)     /* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE                (1 << 3)
+#define RHF_SGI_ONLY               (1 << 4)
+#define RHF_GUARANTEE_INIT         (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS      (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE                  (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD     (1 << 9)
+#define RHF_REQUICKSTART           (1 << 10)
+#define RHF_REQUICKSTARTED         (1 << 11)
+#define RHF_CORD                   (1 << 12)
+#define RHF_NO_UNRES_UNDEF         (1 << 13)
+#define RHF_RLD_ORDER_SAFE         (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;            /* Name (string table index) */
+  Elf32_Word l_time_stamp;      /* Timestamp */
+  Elf32_Word l_checksum;        /* Checksum */
+  Elf32_Word l_version;         /* Interface version */
+  Elf32_Word l_flags;           /* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;            /* Name (string table index) */
+  Elf64_Word l_time_stamp;      /* Timestamp */
+  Elf64_Word l_checksum;        /* Checksum */
+  Elf64_Word l_version;         /* Interface version */
+  Elf64_Word l_flags;           /* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE           0
+#define LL_EXACT_MATCH    (1 << 0)      /* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)      /* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS        (1 << 3)
+#define LL_DELAY_LOAD     (1 << 4)
+#define LL_DELTA          (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNL        1       /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT           2       /* Program uses arch. extensions.  */
+#define EF_PARISC_ARCH          0xffff0000 /* Architecture version.  */
+/* Defined values are:
+                                0x020b  PA-RISC 1.0 big-endian
+                                0x0210  PA-RISC 1.1 big-endian
+                                0x028b  PA-RISC 1.0 little-endian
+                                0x0290  PA-RISC 1.1 little-endian
+*/
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_GOT          0x70000000 /* GOT for external data.  */
+#define SHT_PARISC_ARCH         0x70000001 /* Architecture extensions.  */
+#define SHT_PARISC_GLOBAL       0x70000002 /* Definition of $global$.  */
+#define SHT_PARISC_MILLI        0x70000003 /* Millicode routines.  */
+#define SHT_PARISC_UNWIND       0x70000004 /* Unwind information.  */
+#define SHT_PARISC_PLT          0x70000005 /* Procedure linkage table.  */
+#define SHT_PARISC_SDATA        0x70000006 /* Short initialized data.  */
+#define SHT_PARISC_SBSS         0x70000007 /* Short uninitialized data.  */
+#define SHT_PARISC_SYMEXTN      0x70000008 /* Argument/relocation info.  */
+#define SHT_PARISC_STUBS        0x70000009 /* Linker stubs.  */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_GLOBAL       0x10000000 /* Section defines dp.  */
+#define SHF_PARISC_SHORT        0x20000000 /* Section with short addressing. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE    13      /* Millicode function entry point.  */
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE           0       /* No reloc.  */
+#define R_PARISC_DIR32          1       /* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L         2       /* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R         3       /* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR14R         4       /* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL21L       5       /* PC-relative, left 21 bits.  */
+#define R_PARISC_PCREL14R       6       /* PC-relative, right 14 bits.  */
+#define R_PARISC_PCREL17C       7       /* Conditional PC-relative, ignore
+                                           if displacement > 17bits.  */
+#define R_PARISC_PCREL17F       8       /* Conditional PC-relative, must
+                                           fit in 17bits.  */
+#define R_PARISC_DPREL21L       9       /* DP-relative, left 21 bits.  */
+#define R_PARISC_DPREL14R       10      /* DP-relative, right 14 bits.  */
+#define R_PARISC_DPREL14F       11      /* DP-relative, must bit in 14 bits. */
+#define R_PARISC_DLTREL21L      12      /* DLT-relative, left 21 bits.  */
+#define R_PARISC_DLTREL14R      13      /* DLT-relative, right 14 bits.  */
+#define R_PARISC_DLTREL14F      14      /* DLT-relative, must fit in 14 bits.*/
+#define R_PARISC_DLTIND21L      15      /* DLT-relative indirect, left
+                                           21 bits.  */
+#define R_PARISC_DLTIND14R      16      /* DLT-relative indirect, right
+                                           14 bits.  */
+#define R_PARISC_DLTIND14F      17      /* DLT-relative indirect, must fit
+                                           int 14 bits.  */
+#define R_PARISC_PLABEL32       18      /* Direct 32-bit reference to proc.  */
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT          1       /* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX       2       /* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primerily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG         0x70000001
+#define SHT_ALPHA_REGINFO       0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL         0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV          0x80    /* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD    0x88    /* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE            0       /* No reloc */
+#define R_ALPHA_REFLONG         1       /* Direct 32 bit */
+#define R_ALPHA_REFQUAD         2       /* Direct 64 bit */
+#define R_ALPHA_GPREL32         3       /* GP relative 32 bit */
+#define R_ALPHA_LITERAL         4       /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE          5       /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP          6       /* Add displacement to GP */
+#define R_ALPHA_BRADDR          7       /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT            8       /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16          9       /* PC relative 16 bit */
+#define R_ALPHA_SREL32          10      /* PC relative 32 bit */
+#define R_ALPHA_SREL64          11      /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH         12      /* OP stack push */
+#define R_ALPHA_OP_STORE        13      /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB         14      /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT      15      /* OP stack right shift */
+#define R_ALPHA_GPVALUE         16
+#define R_ALPHA_GPRELHIGH       17
+#define R_ALPHA_GPRELLOW        18
+#define R_ALPHA_IMMED_GP_16     19
+#define R_ALPHA_IMMED_GP_HI32   20
+#define R_ALPHA_IMMED_SCN_HI32  21
+#define R_ALPHA_IMMED_BR_HI32   22
+#define R_ALPHA_IMMED_LO32      23
+#define R_ALPHA_COPY            24      /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT        25      /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT        26      /* Create PLT entry */
+#define R_ALPHA_RELATIVE        27      /* Adjust by program base */
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM             28
+
+
+/* PowerPC specific declarations */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE              0
+#define R_PPC_ADDR32            1       /* 32bit absolute address */
+#define R_PPC_ADDR24            2       /* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16            3       /* 16bit absolute address */
+#define R_PPC_ADDR16_LO         4       /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI         5       /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA         6       /* adjusted high 16bit */
+#define R_PPC_ADDR14            7       /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN    8
+#define R_PPC_ADDR14_BRNTAKEN   9
+#define R_PPC_REL24             10      /* PC relative 26 bit */
+#define R_PPC_REL14             11      /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN     12
+#define R_PPC_REL14_BRNTAKEN    13
+#define R_PPC_GOT16             14
+#define R_PPC_GOT16_LO          15
+#define R_PPC_GOT16_HI          16
+#define R_PPC_GOT16_HA          17
+#define R_PPC_PLTREL24          18
+#define R_PPC_COPY              19
+#define R_PPC_GLOB_DAT          20
+#define R_PPC_JMP_SLOT          21
+#define R_PPC_RELATIVE          22
+#define R_PPC_LOCAL24PC         23
+#define R_PPC_UADDR32           24
+#define R_PPC_UADDR16           25
+#define R_PPC_REL32             26
+#define R_PPC_PLT32             27
+#define R_PPC_PLTREL32          28
+#define R_PPC_PLT16_LO          29
+#define R_PPC_PLT16_HI          30
+#define R_PPC_PLT16_HA          31
+#define R_PPC_SDAREL16          32
+#define R_PPC_SECTOFF           33
+#define R_PPC_SECTOFF_LO        34
+#define R_PPC_SECTOFF_HI        35
+#define R_PPC_SECTOFF_HA        36
+/* Keep this the last entry.  */
+#define R_PPC_NUM               37
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32       101
+#define R_PPC_EMB_NADDR16       102
+#define R_PPC_EMB_NADDR16_LO    103
+#define R_PPC_EMB_NADDR16_HI    104
+#define R_PPC_EMB_NADDR16_HA    105
+#define R_PPC_EMB_SDAI16        106
+#define R_PPC_EMB_SDA2I16       107
+#define R_PPC_EMB_SDA2REL       108
+#define R_PPC_EMB_SDA21         109     /* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF        110
+#define R_PPC_EMB_RELSEC16      111
+#define R_PPC_EMB_RELST_LO      112
+#define R_PPC_EMB_RELST_HI      113
+#define R_PPC_EMB_RELST_HA      114
+#define R_PPC_EMB_BIT_FLD       115
+#define R_PPC_EMB_RELSDA        116     /* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO     180     /* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI     181     /* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA     182     /* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO    183     /* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI    184     /* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA    185     /* like EMB_RELSDA, adjusted high 16 */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16             255
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC     0x01
+#define EF_ARM_HASENTRY    0x02
+#define EF_ARM_INTERWORK   0x04
+#define EF_ARM_APCS_26     0x08
+#define EF_ARM_APCS_FLOAT  0x10
+#define EF_ARM_PIC         0x20
+#define EF_ALIGN8          0x40         /* 8-bit structure alignment is in use */
+#define EF_NEW_ABI         0x80
+#define EF_OLD_ABI         0x100
+
+/* Additional symbol types for Thumb */
+#define STT_ARM_TFUNC      0xd
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
+#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
+                                           in the input to a link step */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB          0x10000000   /* Segment contains the location
+                                           addressed by the static base */
+
+/* ARM relocs.  */
+#define R_ARM_NONE              0       /* No reloc */
+#define R_ARM_PC24              1       /* PC relative 26 bit branch */
+#define R_ARM_ABS32             2       /* Direct 32 bit  */
+#define R_ARM_REL32             3       /* PC relative 32 bit */
+#define R_ARM_PC13              4
+#define R_ARM_ABS16             5       /* Direct 16 bit */
+#define R_ARM_ABS12             6       /* Direct 12 bit */
+#define R_ARM_THM_ABS5          7
+#define R_ARM_ABS8              8       /* Direct 8 bit */
+#define R_ARM_SBREL32           9
+#define R_ARM_THM_PC22          10
+#define R_ARM_THM_PC8           11
+#define R_ARM_AMP_VCALL9        12
+#define R_ARM_SWI24             13
+#define R_ARM_THM_SWI8          14
+#define R_ARM_XPC25             15
+#define R_ARM_THM_XPC22         16
+#define R_ARM_COPY              20      /* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT          21      /* Create GOT entry */
+#define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
+#define R_ARM_RELATIVE          23      /* Adjust by program base */
+#define R_ARM_GOTOFF32          24      /* 32 bit offset to GOT */
+#define R_ARM_BASE_PREL         25      /* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT_BREL          26      /* 32 bit GOT entry */
+#define R_ARM_PLT32             27      /* 32 bit PLT address */
+#define R_ARM_CALL              28
+#define R_ARM_JUMP24            29
+#define R_ARM_PREL31            42
+#define R_ARM_GNU_VTENTRY       100
+#define R_ARM_GNU_VTINHERIT     101
+#define R_ARM_THM_PC11          102     /* thumb unconditional branch */
+#define R_ARM_THM_PC9           103     /* thumb conditional branch */
+#define R_ARM_RXPC25            249
+#define R_ARM_RSBREL32          250
+#define R_ARM_THM_RPC22         251
+#define R_ARM_RREL32            252
+#define R_ARM_RABS22            253
+#define R_ARM_RPC24             254
+#define R_ARM_RBASE             255
+/* Keep this the last entry.  */
+#define R_ARM_NUM               256
+
+/* TMS320C67xx specific declarations */
+/* XXX: no ELF standard yet */
+
+/* TMS320C67xx relocs. */
+#define R_C60_32       1
+#define R_C60_GOT32     3               /* 32 bit GOT entry */
+#define R_C60_PLT32     4               /* 32 bit PLT address */
+#define R_C60_COPY      5               /* Copy symbol at runtime */
+#define R_C60_GLOB_DAT  6               /* Create GOT entry */
+#define R_C60_JMP_SLOT  7               /* Create PLT entry */
+#define R_C60_RELATIVE  8               /* Adjust by program base */
+#define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
+#define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
+
+#define R_C60HI16      0x55       // high 16 bit MVKH embedded
+#define R_C60LO16      0x54       // low 16 bit MVKL embedded
+
+#ifdef TCC_TARGET_X86_64
+#define TCC_ELFCLASS ELFCLASS64
+#define ElfW(type) Elf##64##_##type
+#define ELFW(type) ELF##64##_##type
+#else
+#define TCC_ELFCLASS ELFCLASS32
+#define ElfW(type) Elf##32##_##type
+#define ELFW(type) ELF##32##_##type
+#endif
+
+#endif  /* elf.h */
diff --git a/tinyc/examples/ex1.c b/tinyc/examples/ex1.c
new file mode 100755
index 000000000..28139f92e
--- /dev/null
+++ b/tinyc/examples/ex1.c
@@ -0,0 +1,8 @@
+#! /usr/local/bin/tcc -run
+#include <tcclib.h>
+
+int main()
+{
+    printf("Hello World\n");
+    return 0;
+}
diff --git a/tinyc/examples/ex2.c b/tinyc/examples/ex2.c
new file mode 100755
index 000000000..d415e39d7
--- /dev/null
+++ b/tinyc/examples/ex2.c
@@ -0,0 +1,98 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define N 20
+
+int nb_num;
+int tab[N];
+int stack_ptr;
+int stack_op[N];
+int stack_res[60];
+int result;
+
+int find(int n, int i1, int a, int b, int op)
+{
+    int i, j;
+    int c;
+
+    if (stack_ptr >= 0) {
+        stack_res[3*stack_ptr] = a;
+        stack_op[stack_ptr] = op;
+        stack_res[3*stack_ptr+1] = b;
+        stack_res[3*stack_ptr+2] = n;
+        if (n == result)
+            return 1;
+        tab[i1] = n;
+    }
+
+    for(i=0;i<nb_num;i++) {
+        for(j=i+1;j<nb_num;j++) {
+            a = tab[i];
+            b = tab[j];
+            if (a != 0 && b != 0) {
+
+                tab[j] = 0;
+                stack_ptr++;
+
+                if (find(a + b, i, a, b, '+'))
+                    return 1;
+                if (find(a - b, i, a, b, '-'))
+                    return 1;
+                if (find(b - a, i, b, a, '-'))
+                    return 1;
+                if (find(a * b, i, a, b, '*'))
+                    return 1;
+                if (b != 0) {
+                    c = a / b;
+                    if (find(c, i, a, b, '/'))
+                        return 1;
+                }
+
+                if (a != 0) {
+                    c = b / a;
+                    if (find(c, i, b, a, '/'))
+                        return 1;
+                }
+
+                stack_ptr--;
+                tab[i] = a;
+                tab[j] = b;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    int i, res, p;
+
+    if (argc < 3) {
+        printf("usage: %s: result numbers...\n"
+               "Try to find result from numbers with the 4 basic operations.\n", argv[0]);
+        exit(1);
+    }
+
+    p = 1;
+    result = atoi(argv[p]);
+    printf("result=%d\n", result);
+    nb_num = 0;
+    for(i=p+1;i<argc;i++) {
+        tab[nb_num++] = atoi(argv[i]);
+    }
+
+    stack_ptr = -1;
+    res = find(0, 0, 0, 0, ' ');
+    if (res) {
+        for(i=0;i<=stack_ptr;i++) {
+            printf("%d %c %d = %d\n",
+                   stack_res[3*i], stack_op[i],
+                   stack_res[3*i+1], stack_res[3*i+2]);
+        }
+        return 0;
+    } else {
+        printf("Impossible\n");
+        return 1;
+    }
+}
diff --git a/tinyc/examples/ex3.c b/tinyc/examples/ex3.c
new file mode 100755
index 000000000..7c466ad54
--- /dev/null
+++ b/tinyc/examples/ex3.c
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int fib(n)
+{
+    if (n <= 2)
+        return 1;
+    else
+        return fib(n-1) + fib(n-2);
+}
+
+int main(int argc, char **argv)
+{
+    int n;
+    if (argc < 2) {
+        printf("usage: fib n\n"
+               "Compute nth Fibonacci number\n");
+        return 1;
+    }
+
+    n = atoi(argv[1]);
+    printf("fib(%d) = %d\n", n, fib(n, 2));
+    return 0;
+}
diff --git a/tinyc/examples/ex4.c b/tinyc/examples/ex4.c
new file mode 100755
index 000000000..b33b0331d
--- /dev/null
+++ b/tinyc/examples/ex4.c
@@ -0,0 +1,26 @@
+#!./tcc -run -L/usr/X11R6/lib -lX11
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+
+/* Yes, TCC can use X11 too ! */
+
+int main(int argc, char **argv)
+{
+    Display *display;
+    Screen *screen;
+
+    display = XOpenDisplay("");
+    if (!display) {
+        fprintf(stderr, "Could not open X11 display\n");
+        exit(1);
+    }
+    printf("X11 display opened.\n");
+    screen = XScreenOfDisplay(display, 0);
+    printf("width = %d\nheight = %d\ndepth = %d\n",
+           screen->width,
+           screen->height,
+           screen->root_depth);
+    XCloseDisplay(display);
+    return 0;
+}
diff --git a/tinyc/examples/ex5.c b/tinyc/examples/ex5.c
new file mode 100755
index 000000000..156425e39
--- /dev/null
+++ b/tinyc/examples/ex5.c
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+    printf("Hello World\n");
+    return 0;
+}
diff --git a/tinyc/i386-asm.c b/tinyc/i386-asm.c
new file mode 100755
index 000000000..21b28d7a0
--- /dev/null
+++ b/tinyc/i386-asm.c
@@ -0,0 +1,1211 @@
+/*
+ *  i386 specific functions for TCC assembler
+ * 
+ *  Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define MAX_OPERANDS 3
+
+typedef struct ASMInstr {
+    uint16_t sym;
+    uint16_t opcode;
+    uint16_t instr_type;
+#define OPC_JMP       0x01  /* jmp operand */
+#define OPC_B         0x02  /* only used zith OPC_WL */
+#define OPC_WL        0x04  /* accepts w, l or no suffix */
+#define OPC_BWL       (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
+#define OPC_REG       0x08 /* register is added to opcode */
+#define OPC_MODRM     0x10 /* modrm encoding */
+#define OPC_FWAIT     0x20 /* add fwait opcode */
+#define OPC_TEST      0x40 /* test opcodes */
+#define OPC_SHIFT     0x80 /* shift opcodes */
+#define OPC_D16      0x0100 /* generate data16 prefix */
+#define OPC_ARITH    0x0200 /* arithmetic opcodes */
+#define OPC_SHORTJMP 0x0400 /* short jmp operand */
+#define OPC_FARITH   0x0800 /* FPU arithmetic opcodes */
+#define OPC_GROUP_SHIFT 13
+
+/* in order to compress the operand type, we use specific operands and
+   we or only with EA  */ 
+#define OPT_REG8  0 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_REG16 1 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_REG32 2 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_MMX   3 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_SSE   4 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_CR    5 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_TR    6 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_DB    7 /* warning: value is hardcoded from TOK_ASM_xxx */
+#define OPT_SEG   8
+#define OPT_ST    9
+#define OPT_IM8   10
+#define OPT_IM8S  11
+#define OPT_IM16  12
+#define OPT_IM32  13
+#define OPT_EAX   14 /* %al, %ax or %eax register */
+#define OPT_ST0   15 /* %st(0) register */
+#define OPT_CL    16 /* %cl register */
+#define OPT_DX    17 /* %dx register */
+#define OPT_ADDR  18 /* OP_EA with only offset */
+#define OPT_INDIR 19 /* *(expr) */
+
+/* composite types */ 
+#define OPT_COMPOSITE_FIRST   20
+#define OPT_IM       20 /* IM8 | IM16 | IM32 */
+#define OPT_REG      21 /* REG8 | REG16 | REG32 */ 
+#define OPT_REGW     22 /* REG16 | REG32 */
+#define OPT_IMW      23 /* IM16 | IM32 */ 
+
+/* can be ored with any OPT_xxx */
+#define OPT_EA    0x80
+
+    uint8_t nb_ops;
+    uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
+} ASMInstr;
+
+typedef struct Operand {
+    uint32_t type;
+#define OP_REG8   (1 << OPT_REG8)
+#define OP_REG16  (1 << OPT_REG16)
+#define OP_REG32  (1 << OPT_REG32)
+#define OP_MMX    (1 << OPT_MMX)
+#define OP_SSE    (1 << OPT_SSE)
+#define OP_CR     (1 << OPT_CR)
+#define OP_TR     (1 << OPT_TR)
+#define OP_DB     (1 << OPT_DB)
+#define OP_SEG    (1 << OPT_SEG)
+#define OP_ST     (1 << OPT_ST)
+#define OP_IM8    (1 << OPT_IM8)
+#define OP_IM8S   (1 << OPT_IM8S)
+#define OP_IM16   (1 << OPT_IM16)
+#define OP_IM32   (1 << OPT_IM32)
+#define OP_EAX    (1 << OPT_EAX)
+#define OP_ST0    (1 << OPT_ST0)
+#define OP_CL     (1 << OPT_CL)
+#define OP_DX     (1 << OPT_DX)
+#define OP_ADDR   (1 << OPT_ADDR)
+#define OP_INDIR  (1 << OPT_INDIR)
+
+#define OP_EA     0x40000000
+#define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32)
+#define OP_IM     OP_IM32
+    int8_t  reg; /* register, -1 if none */
+    int8_t  reg2; /* second register, -1 if none */
+    uint8_t shift;
+    ExprValue e;
+} Operand;
+
+static const uint8_t reg_to_size[5] = {
+/*
+    [OP_REG8] = 0,
+    [OP_REG16] = 1,
+    [OP_REG32] = 2,
+*/
+    0, 0, 1, 0, 2
+};
+    
+#define WORD_PREFIX_OPCODE 0x66
+
+#define NB_TEST_OPCODES 30
+
+static const uint8_t test_bits[NB_TEST_OPCODES] = {
+ 0x00, /* o */
+ 0x01, /* no */
+ 0x02, /* b */
+ 0x02, /* c */
+ 0x02, /* nae */
+ 0x03, /* nb */
+ 0x03, /* nc */
+ 0x03, /* ae */
+ 0x04, /* e */
+ 0x04, /* z */
+ 0x05, /* ne */
+ 0x05, /* nz */
+ 0x06, /* be */
+ 0x06, /* na */
+ 0x07, /* nbe */
+ 0x07, /* a */
+ 0x08, /* s */
+ 0x09, /* ns */
+ 0x0a, /* p */
+ 0x0a, /* pe */
+ 0x0b, /* np */
+ 0x0b, /* po */
+ 0x0c, /* l */
+ 0x0c, /* nge */
+ 0x0d, /* nl */
+ 0x0d, /* ge */
+ 0x0e, /* le */
+ 0x0e, /* ng */
+ 0x0f, /* nle */
+ 0x0f, /* g */
+};
+
+static const uint8_t segment_prefixes[] = {
+ 0x26, /* es */
+ 0x2e, /* cs */
+ 0x36, /* ss */
+ 0x3e, /* ds */
+ 0x64, /* fs */
+ 0x65  /* gs */
+};
+
+static const ASMInstr asm_instrs[] = {
+#define ALT(x) x
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 0 },
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 1, { op0 }},
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 2, { op0, op1 }},
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, opcode, (instr_type | group << OPC_GROUP_SHIFT), 3, { op0, op1, op2 }},
+#include "i386-asm.h"
+
+    /* last operation */
+    { 0, },
+};
+
+static const uint16_t op0_codes[] = {
+#define ALT(x)
+#define DEF_ASM_OP0(x, opcode) opcode,
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#include "i386-asm.h"
+};
+
+static inline int get_reg_shift(TCCState *s1)
+{
+    int shift, v;
+
+    v = asm_int_expr(s1);
+    switch(v) {
+    case 1:
+        shift = 0;
+        break;
+    case 2:
+        shift = 1;
+        break;
+    case 4:
+        shift = 2;
+        break;
+    case 8:
+        shift = 3;
+        break;
+    default:
+        expect("1, 2, 4 or 8 constant");
+        shift = 0;
+        break;
+    }
+    return shift;
+}
+
+static int asm_parse_reg(void)
+{
+    int reg;
+    if (tok != '%')
+        goto error_32;
+    next();
+    if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
+        reg = tok - TOK_ASM_eax;
+        next();
+        return reg;
+    } else {
+    error_32:
+        expect("32 bit register");
+        return 0;
+    }
+}
+
+static void parse_operand(TCCState *s1, Operand *op)
+{
+    ExprValue e;
+    int reg, indir;
+    const char *p;
+
+    indir = 0;
+    if (tok == '*') {
+        next();
+        indir = OP_INDIR;
+    }
+
+    if (tok == '%') {
+        next();
+        if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
+            reg = tok - TOK_ASM_al;
+            op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
+            op->reg = reg & 7;
+            if ((op->type & OP_REG) && op->reg == TREG_EAX)
+                op->type |= OP_EAX;
+            else if (op->type == OP_REG8 && op->reg == TREG_ECX)
+                op->type |= OP_CL;
+            else if (op->type == OP_REG16 && op->reg == TREG_EDX)
+                op->type |= OP_DX;
+        } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
+            op->type = OP_DB;
+            op->reg = tok - TOK_ASM_dr0;
+        } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
+            op->type = OP_SEG;
+            op->reg = tok - TOK_ASM_es;
+        } else if (tok == TOK_ASM_st) {
+            op->type = OP_ST;
+            op->reg = 0;
+            next();
+            if (tok == '(') {
+                next();
+                if (tok != TOK_PPNUM)
+                    goto reg_error;
+                p = tokc.cstr->data;
+                reg = p[0] - '0';
+                if ((unsigned)reg >= 8 || p[1] != '\0')
+                    goto reg_error;
+                op->reg = reg;
+                next();
+                skip(')');
+            }
+            if (op->reg == 0)
+                op->type |= OP_ST0;
+            goto no_skip;
+        } else {
+        reg_error:
+            error("unknown register");
+        }
+        next();
+    no_skip: ;
+    } else if (tok == '$') {
+        /* constant value */
+        next();
+        asm_expr(s1, &e);
+        op->type = OP_IM32;
+        op->e.v = e.v;
+        op->e.sym = e.sym;
+        if (!op->e.sym) {
+            if (op->e.v == (uint8_t)op->e.v)
+                op->type |= OP_IM8;
+            if (op->e.v == (int8_t)op->e.v)
+                op->type |= OP_IM8S;
+            if (op->e.v == (uint16_t)op->e.v)
+                op->type |= OP_IM16;
+        }
+    } else {
+        /* address(reg,reg2,shift) with all variants */
+        op->type = OP_EA;
+        op->reg = -1;
+        op->reg2 = -1;
+        op->shift = 0;
+        if (tok != '(') {
+            asm_expr(s1, &e);
+            op->e.v = e.v;
+            op->e.sym = e.sym;
+        } else {
+            op->e.v = 0;
+            op->e.sym = NULL;
+        }
+        if (tok == '(') {
+            next();
+            if (tok != ',') {
+                op->reg = asm_parse_reg();
+            }
+            if (tok == ',') {
+                next();
+                if (tok != ',') {
+                    op->reg2 = asm_parse_reg();
+                } 
+                if (tok == ',') {
+                    next();
+                    op->shift = get_reg_shift(s1);
+                }
+            }
+            skip(')');
+        }
+        if (op->reg == -1 && op->reg2 == -1)
+            op->type |= OP_ADDR;
+    }
+    op->type |= indir;
+}
+
+/* XXX: unify with C code output ? */
+static void gen_expr32(ExprValue *pe)
+{
+    if (pe->sym)
+        greloc(cur_text_section, pe->sym, ind, R_386_32);
+    gen_le32(pe->v);
+}
+
+/* XXX: unify with C code output ? */
+static void gen_disp32(ExprValue *pe)
+{
+    Sym *sym;
+    sym = pe->sym;
+    if (sym) {
+        if (sym->r == cur_text_section->sh_num) {
+            /* same section: we can output an absolute value. Note
+               that the TCC compiler behaves differently here because
+               it always outputs a relocation to ease (future) code
+               elimination in the linker */
+            gen_le32(pe->v + (long)sym->next - ind - 4);
+        } else {
+            greloc(cur_text_section, sym, ind, R_386_PC32);
+            gen_le32(pe->v - 4);
+        }
+    } else {
+        /* put an empty PC32 relocation */
+        put_elf_reloc(symtab_section, cur_text_section, 
+                      ind, R_386_PC32, 0);
+        gen_le32(pe->v - 4);
+    }
+}
+
+
+static void gen_le16(int v)
+{
+    g(v);
+    g(v >> 8);
+}
+
+/* generate the modrm operand */
+static inline void asm_modrm(int reg, Operand *op)
+{
+    int mod, reg1, reg2, sib_reg1;
+
+    if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
+        g(0xc0 + (reg << 3) + op->reg);
+    } else if (op->reg == -1 && op->reg2 == -1) {
+        /* displacement only */
+        g(0x05 + (reg << 3));
+        gen_expr32(&op->e);
+    } else {
+        sib_reg1 = op->reg;
+        /* fist compute displacement encoding */
+        if (sib_reg1 == -1) {
+            sib_reg1 = 5;
+            mod = 0x00;
+        } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
+            mod = 0x00;
+        } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
+            mod = 0x40;
+        } else {
+            mod = 0x80;
+        }
+        /* compute if sib byte needed */
+        reg1 = op->reg;
+        if (op->reg2 != -1)
+            reg1 = 4;
+        g(mod + (reg << 3) + reg1);
+        if (reg1 == 4) {
+            /* add sib byte */
+            reg2 = op->reg2;
+            if (reg2 == -1)
+                reg2 = 4; /* indicate no index */
+            g((op->shift << 6) + (reg2 << 3) + sib_reg1);
+        }
+
+        /* add offset */
+        if (mod == 0x40) {
+            g(op->e.v);
+        } else if (mod == 0x80 || op->reg == -1) {
+            gen_expr32(&op->e);
+        }
+    }
+}
+
+static void asm_opcode(TCCState *s1, int opcode)
+{
+    const ASMInstr *pa;
+    int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix;
+    int nb_ops, s, ss;
+    Operand ops[MAX_OPERANDS], *pop;
+    int op_type[3]; /* decoded op type */
+
+    /* get operands */
+    pop = ops;
+    nb_ops = 0;
+    seg_prefix = 0;
+    for(;;) {
+        if (tok == ';' || tok == TOK_LINEFEED)
+            break;
+        if (nb_ops >= MAX_OPERANDS) {
+            error("incorrect number of operands");
+        }
+        parse_operand(s1, pop);
+        if (tok == ':') {
+           if (pop->type != OP_SEG || seg_prefix) {
+               error("incorrect prefix");
+           }
+           seg_prefix = segment_prefixes[pop->reg];
+           next();
+           parse_operand(s1, pop);
+           if (!(pop->type & OP_EA)) {
+               error("segment prefix must be followed by memory reference");
+           }
+        }
+        pop++;
+        nb_ops++;
+        if (tok != ',')
+            break;
+        next();
+    }
+
+    is_short_jmp = 0;
+    s = 0; /* avoid warning */
+    
+    /* optimize matching by using a lookup table (no hashing is needed
+       !) */
+    for(pa = asm_instrs; pa->sym != 0; pa++) {
+        s = 0;
+        if (pa->instr_type & OPC_FARITH) {
+            v = opcode - pa->sym;
+            if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
+                continue;
+        } else if (pa->instr_type & OPC_ARITH) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + 8 * 4))
+                continue;
+            goto compute_size;
+        } else if (pa->instr_type & OPC_SHIFT) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + 7 * 4))
+                continue;
+            goto compute_size;
+        } else if (pa->instr_type & OPC_TEST) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
+                continue;
+        } else if (pa->instr_type & OPC_B) {
+            if (!(opcode >= pa->sym && opcode <= pa->sym + 3))
+                continue;
+        compute_size:
+            s = (opcode - pa->sym) & 3;
+        } else if (pa->instr_type & OPC_WL) {
+            if (!(opcode >= pa->sym && opcode <= pa->sym + 2))
+                continue;
+            s = opcode - pa->sym + 1;
+        } else {
+            if (pa->sym != opcode)
+                continue;
+        }
+        if (pa->nb_ops != nb_ops)
+            continue;
+        /* now decode and check each operand */
+        for(i = 0; i < nb_ops; i++) {
+            int op1, op2;
+            op1 = pa->op_type[i];
+            op2 = op1 & 0x1f;
+            switch(op2) {
+            case OPT_IM:
+                v = OP_IM8 | OP_IM16 | OP_IM32;
+                break;
+            case OPT_REG:
+                v = OP_REG8 | OP_REG16 | OP_REG32;
+                break;
+            case OPT_REGW:
+                v = OP_REG16 | OP_REG32;
+                break;
+            case OPT_IMW:
+                v = OP_IM16 | OP_IM32;
+                break;
+            default:
+                v = 1 << op2;
+                break;
+            }
+            if (op1 & OPT_EA)
+                v |= OP_EA;
+            op_type[i] = v;
+            if ((ops[i].type & v) == 0)
+                goto next;
+        }
+        /* all is matching ! */
+        break;
+    next: ;
+    }
+    if (pa->sym == 0) {
+        if (opcode >= TOK_ASM_pusha && opcode <= TOK_ASM_emms) {
+            int b;
+            b = op0_codes[opcode - TOK_ASM_pusha];
+            if (b & 0xff00) 
+                g(b >> 8);
+            g(b);
+            return;
+        } else {
+            error("unknown opcode '%s'", 
+                  get_tok_str(opcode, NULL));
+        }
+    }
+    /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
+    if (s == 3) {
+        for(i = 0; s == 3 && i < nb_ops; i++) {
+            if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
+                s = reg_to_size[ops[i].type & OP_REG];
+        }
+        if (s == 3) {
+            if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) && 
+                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
+                s = 2;
+            else
+                error("cannot infer opcode suffix");
+        }
+    }
+
+    /* generate data16 prefix if needed */
+    ss = s;
+    if (s == 1 || (pa->instr_type & OPC_D16))
+        g(WORD_PREFIX_OPCODE);
+    else if (s == 2)
+        s = 1;
+    /* now generates the operation */
+    if (pa->instr_type & OPC_FWAIT)
+        g(0x9b);
+    if (seg_prefix)
+        g(seg_prefix);
+
+    v = pa->opcode;
+    if (v == 0x69 || v == 0x69) {
+        /* kludge for imul $im, %reg */
+        nb_ops = 3;
+        ops[2] = ops[1];
+    } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
+        v--; /* int $3 case */
+        nb_ops = 0;
+    } else if ((v == 0x06 || v == 0x07)) {
+        if (ops[0].reg >= 4) {
+            /* push/pop %fs or %gs */
+            v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
+        } else {
+            v += ops[0].reg << 3;
+        }
+        nb_ops = 0;
+    } else if (v <= 0x05) {
+        /* arith case */
+        v += ((opcode - TOK_ASM_addb) >> 2) << 3;
+    } else if ((pa->instr_type & (OPC_FARITH | OPC_MODRM)) == OPC_FARITH) {
+        /* fpu arith case */
+        v += ((opcode - pa->sym) / 6) << 3;
+    }
+    if (pa->instr_type & OPC_REG) {
+        for(i = 0; i < nb_ops; i++) {
+            if (op_type[i] & (OP_REG | OP_ST)) {
+                v += ops[i].reg;
+                break;
+            }
+        }
+        /* mov $im, %reg case */
+        if (pa->opcode == 0xb0 && s >= 1)
+            v += 7;
+    }
+    if (pa->instr_type & OPC_B)
+        v += s;
+    if (pa->instr_type & OPC_TEST)
+        v += test_bits[opcode - pa->sym]; 
+    if (pa->instr_type & OPC_SHORTJMP) {
+        Sym *sym;
+        int jmp_disp;
+
+        /* see if we can really generate the jump with a byte offset */
+        sym = ops[0].e.sym;
+        if (!sym)
+            goto no_short_jump;
+        if (sym->r != cur_text_section->sh_num)
+            goto no_short_jump;
+        jmp_disp = ops[0].e.v + (long)sym->next - ind - 2;
+        if (jmp_disp == (int8_t)jmp_disp) {
+            /* OK to generate jump */
+            is_short_jmp = 1;
+            ops[0].e.v = jmp_disp;
+        } else {
+        no_short_jump:
+            if (pa->instr_type & OPC_JMP) {
+                /* long jump will be allowed. need to modify the
+                   opcode slightly */
+                if (v == 0xeb)
+                    v = 0xe9;
+                else 
+                    v += 0x0f10;
+            } else {
+                error("invalid displacement");
+            }
+        }
+    }
+    op1 = v >> 8;
+    if (op1)
+        g(op1);
+    g(v);
+        
+    /* search which operand will used for modrm */
+    modrm_index = 0;
+    if (pa->instr_type & OPC_SHIFT) {
+        reg = (opcode - pa->sym) >> 2; 
+        if (reg == 6)
+            reg = 7;
+    } else if (pa->instr_type & OPC_ARITH) {
+        reg = (opcode - pa->sym) >> 2;
+    } else if (pa->instr_type & OPC_FARITH) {
+        reg = (opcode - pa->sym) / 6;
+    } else {
+        reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
+    }
+    if (pa->instr_type & OPC_MODRM) {
+        /* first look for an ea operand */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & OP_EA)
+                goto modrm_found;
+        }
+        /* then if not found, a register or indirection (shift instructions) */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
+                goto modrm_found;
+        }
+#ifdef ASM_DEBUG
+        error("bad op table");
+#endif      
+    modrm_found:
+        modrm_index = i;
+        /* if a register is used in another operand then it is
+           used instead of group */
+        for(i = 0;i < nb_ops; i++) {
+            v = op_type[i];
+            if (i != modrm_index && 
+                (v & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
+                reg = ops[i].reg;
+                break;
+            }
+        }
+
+        asm_modrm(reg, &ops[modrm_index]);
+    }
+
+    /* emit constants */
+    if (pa->opcode == 0x9a || pa->opcode == 0xea) {
+        /* ljmp or lcall kludge */
+        gen_expr32(&ops[1].e);
+        if (ops[0].e.sym)
+            error("cannot relocate");
+        gen_le16(ops[0].e.v);
+    } else {
+        for(i = 0;i < nb_ops; i++) {
+            v = op_type[i];
+            if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM8S | OP_ADDR)) {
+                /* if multiple sizes are given it means we must look
+                   at the op size */
+                if (v == (OP_IM8 | OP_IM16 | OP_IM32) ||
+                    v == (OP_IM16 | OP_IM32)) {
+                    if (ss == 0)
+                        v = OP_IM8;
+                    else if (ss == 1)
+                        v = OP_IM16;
+                    else
+                        v = OP_IM32;
+                }
+                if (v & (OP_IM8 | OP_IM8S)) {
+                    if (ops[i].e.sym)
+                        goto error_relocate;
+                    g(ops[i].e.v);
+                } else if (v & OP_IM16) {
+                    if (ops[i].e.sym) {
+                    error_relocate:
+                        error("cannot relocate");
+                    }
+                    gen_le16(ops[i].e.v);
+                } else {
+                    if (pa->instr_type & (OPC_JMP | OPC_SHORTJMP)) {
+                        if (is_short_jmp)
+                            g(ops[i].e.v);
+                        else
+                            gen_disp32(&ops[i].e);
+                    } else {
+                        gen_expr32(&ops[i].e);
+                    }
+                }
+            }
+        }
+    }
+}
+
+#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)
+{
+    int priority, c, pr;
+
+    /* we take the lowest priority */
+    priority = 0;
+    for(;;) {
+        c = *str;
+        if (c == '\0')
+            break;
+        str++;
+        switch(c) {
+        case 'A':
+            pr = 0;
+            break;
+        case 'a':
+        case 'b':
+        case 'c':
+        case 'd':
+        case 'S':
+        case 'D':
+            pr = 1;
+            break;
+        case 'q':
+            pr = 2;
+            break;
+        case 'r':
+            pr = 3;
+            break;
+        case 'N':
+        case 'M':
+        case 'I':
+        case 'i':
+        case 'm':
+        case 'g':
+            pr = 4;
+            break;
+        default:
+            error("unknown constraint '%c'", c);
+            pr = 0;
+        }
+        if (pr > priority)
+            priority = pr;
+    }
+    return priority;
+}
+
+static const char *skip_constraint_modifiers(const char *p)
+{
+    while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
+        p++;
+    return p;
+}
+
+#define REG_OUT_MASK 0x01
+#define REG_IN_MASK  0x02
+
+#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
+
+static void asm_compute_constraints(ASMOperand *operands, 
+                                    int nb_operands, int nb_outputs, 
+                                    const uint8_t *clobber_regs,
+                                    int *pout_reg)
+{
+    ASMOperand *op;
+    int sorted_op[MAX_ASM_OPERANDS];
+    int i, j, k, p1, p2, tmp, reg, c, reg_mask;
+    const char *str;
+    uint8_t regs_allocated[NB_ASM_REGS];
+    
+    /* init fields */
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        op->input_index = -1;
+        op->ref_index = -1;
+        op->reg = -1;
+        op->is_memory = 0;
+        op->is_rw = 0;
+    }
+    /* compute constraint priority and evaluate references to output
+       constraints if input constraints */
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        str = op->constraint;
+        str = skip_constraint_modifiers(str);
+        if (isnum(*str) || *str == '[') {
+            /* this is a reference to another constraint */
+            k = find_constraint(operands, nb_operands, str, NULL);
+            if ((unsigned)k >= i || i < nb_outputs)
+                error("invalid reference in constraint %d ('%s')",
+                      i, str);
+            op->ref_index = k;
+            if (operands[k].input_index >= 0)
+                error("cannot reference twice the same operand");
+            operands[k].input_index = i;
+            op->priority = 5;
+        } else {
+            op->priority = constraint_priority(str);
+        }
+    }
+    
+    /* sort operands according to their priority */
+    for(i=0;i<nb_operands;i++)
+        sorted_op[i] = i;
+    for(i=0;i<nb_operands - 1;i++) {
+        for(j=i+1;j<nb_operands;j++) {
+            p1 = operands[sorted_op[i]].priority; 
+            p2 = operands[sorted_op[j]].priority;
+            if (p2 < p1) {
+                tmp = sorted_op[i];
+                sorted_op[i] = sorted_op[j];
+                sorted_op[j] = tmp;
+            }
+        }
+    }
+
+    for(i = 0;i < NB_ASM_REGS; i++) {
+        if (clobber_regs[i])
+            regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
+        else
+            regs_allocated[i] = 0;
+    }
+    /* esp cannot be used */
+    regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK; 
+    /* ebp cannot be used yet */
+    regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK; 
+
+    /* allocate registers and generate corresponding asm moves */
+    for(i=0;i<nb_operands;i++) {
+        j = sorted_op[i];
+        op = &operands[j];
+        str = op->constraint;
+        /* no need to allocate references */
+        if (op->ref_index >= 0)
+            continue;
+        /* select if register is used for output, input or both */
+        if (op->input_index >= 0) {
+            reg_mask = REG_IN_MASK | REG_OUT_MASK;
+        } else if (j < nb_outputs) {
+            reg_mask = REG_OUT_MASK;
+        } else {
+            reg_mask = REG_IN_MASK;
+        }
+    try_next:
+        c = *str++;
+        switch(c) {
+        case '=':
+            goto try_next;
+        case '+':
+            op->is_rw = 1;
+            /* FALL THRU */
+        case '&':
+            if (j >= nb_outputs)
+                error("'%c' modifier can only be applied to outputs", c);
+            reg_mask = REG_IN_MASK | REG_OUT_MASK;
+            goto try_next;
+        case 'A':
+            /* allocate both eax and edx */
+            if (is_reg_allocated(TREG_EAX) || 
+                is_reg_allocated(TREG_EDX))
+                goto try_next;
+            op->is_llong = 1;
+            op->reg = TREG_EAX;
+            regs_allocated[TREG_EAX] |= reg_mask;
+            regs_allocated[TREG_EDX] |= reg_mask;
+            break;
+        case 'a':
+            reg = TREG_EAX;
+            goto alloc_reg;
+        case 'b':
+            reg = 3;
+            goto alloc_reg;
+        case 'c':
+            reg = TREG_ECX;
+            goto alloc_reg;
+        case 'd':
+            reg = TREG_EDX;
+            goto alloc_reg;
+        case 'S':
+            reg = 6;
+            goto alloc_reg;
+        case 'D':
+            reg = 7;
+        alloc_reg:
+            if (is_reg_allocated(reg))
+                goto try_next;
+            goto reg_found;
+        case 'q':
+            /* eax, ebx, ecx or edx */
+            for(reg = 0; reg < 4; reg++) {
+                if (!is_reg_allocated(reg))
+                    goto reg_found;
+            }
+            goto try_next;
+        case 'r':
+            /* any general register */
+            for(reg = 0; reg < 8; reg++) {
+                if (!is_reg_allocated(reg))
+                    goto reg_found;
+            }
+            goto try_next;
+        reg_found:
+            /* now we can reload in the register */
+            op->is_llong = 0;
+            op->reg = reg;
+            regs_allocated[reg] |= reg_mask;
+            break;
+        case 'i':
+            if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
+                goto try_next;
+            break;
+        case 'I':
+        case 'N':
+        case 'M':
+            if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
+                goto try_next;
+            break;
+        case 'm':
+        case 'g':
+            /* nothing special to do because the operand is already in
+               memory, except if the pointer itself is stored in a
+               memory variable (VT_LLOCAL case) */
+            /* XXX: fix constant case */
+            /* if it is a reference to a memory zone, it must lie
+               in a register, so we reserve the register in the
+               input registers and a load will be generated
+               later */
+            if (j < nb_outputs || c == 'm') {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+                    /* any general register */
+                    for(reg = 0; reg < 8; reg++) {
+                        if (!(regs_allocated[reg] & REG_IN_MASK))
+                            goto reg_found1;
+                    }
+                    goto try_next;
+                reg_found1:
+                    /* now we can reload in the register */
+                    regs_allocated[reg] |= REG_IN_MASK;
+                    op->reg = reg;
+                    op->is_memory = 1;
+                }
+            }
+            break;
+        default:
+            error("asm constraint %d ('%s') could not be satisfied", 
+                  j, op->constraint);
+            break;
+        }
+        /* if a reference is present for that operand, we assign it too */
+        if (op->input_index >= 0) {
+            operands[op->input_index].reg = op->reg;
+            operands[op->input_index].is_llong = op->is_llong;
+        }
+    }
+    
+    /* compute out_reg. It is used to store outputs registers to memory
+       locations references by pointers (VT_LLOCAL case) */
+    *pout_reg = -1;
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        if (op->reg >= 0 && 
+            (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
+            !op->is_memory) {
+            for(reg = 0; reg < 8; reg++) {
+                if (!(regs_allocated[reg] & REG_OUT_MASK))
+                    goto reg_found2;
+            }
+            error("could not find free output register for reloading");
+        reg_found2:
+            *pout_reg = reg;
+            break;
+        }
+    }
+    
+    /* print sorted constraints */
+#ifdef ASM_DEBUG
+    for(i=0;i<nb_operands;i++) {
+        j = sorted_op[i];
+        op = &operands[j];
+        printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n", 
+               j,                
+               op->id ? get_tok_str(op->id, NULL) : "", 
+               op->constraint,
+               op->vt->r,
+               op->reg);
+    }
+    if (*pout_reg >= 0)
+        printf("out_reg=%d\n", *pout_reg);
+#endif
+}
+
+static void subst_asm_operand(CString *add_str, 
+                              SValue *sv, int modifier)
+{
+    int r, reg, size, val;
+    char buf[64];
+
+    r = sv->r;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n')
+            cstr_ccat(add_str, '$');
+        if (r & VT_SYM) {
+            cstr_cat(add_str, get_tok_str(sv->sym->v, NULL));
+            if (sv->c.i != 0) {
+                cstr_ccat(add_str, '+');
+            } else {
+                return;
+            }
+        }
+        val = sv->c.i;
+        if (modifier == 'n')
+            val = -val;
+        snprintf(buf, sizeof(buf), "%d", sv->c.i);
+        cstr_cat(add_str, buf);
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+        snprintf(buf, sizeof(buf), "%d(%%ebp)", sv->c.i);
+        cstr_cat(add_str, buf);
+    } else if (r & VT_LVAL) {
+        reg = r & VT_VALMASK;
+        if (reg >= VT_CONST)
+            error("internal compiler error");
+        snprintf(buf, sizeof(buf), "(%%%s)", 
+                 get_tok_str(TOK_ASM_eax + reg, NULL));
+        cstr_cat(add_str, buf);
+    } else {
+        /* register case */
+        reg = r & VT_VALMASK;
+        if (reg >= VT_CONST)
+            error("internal compiler error");
+
+        /* choose register operand size */
+        if ((sv->type.t & VT_BTYPE) == VT_BYTE)
+            size = 1;
+        else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
+            size = 2;
+        else
+            size = 4;
+        if (size == 1 && reg >= 4)
+            size = 4;
+
+        if (modifier == 'b') {
+            if (reg >= 4)
+                error("cannot use byte register");
+            size = 1;
+        } else if (modifier == 'h') {
+            if (reg >= 4)
+                error("cannot use byte register");
+            size = -1;
+        } else if (modifier == 'w') {
+            size = 2;
+        }
+
+        switch(size) {
+        case -1:
+            reg = TOK_ASM_ah + reg;
+            break;
+        case 1:
+            reg = TOK_ASM_al + reg;
+            break;
+        case 2:
+            reg = TOK_ASM_ax + reg;
+            break;
+        default:
+            reg = TOK_ASM_eax + reg;
+            break;
+        }
+        snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
+        cstr_cat(add_str, buf);
+    }
+}
+
+/* generate prolog and epilog code for asm statment */
+static void asm_gen_code(ASMOperand *operands, int nb_operands, 
+                         int nb_outputs, int is_output,
+                         uint8_t *clobber_regs,
+                         int out_reg)
+{
+    uint8_t regs_allocated[NB_ASM_REGS];
+    ASMOperand *op;
+    int i, reg;
+    static uint8_t reg_saved[NB_SAVED_REGS] = { 3, 6, 7 };
+
+    /* mark all used registers */
+    memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
+    for(i = 0; i < nb_operands;i++) {
+        op = &operands[i];
+        if (op->reg >= 0)
+            regs_allocated[op->reg] = 1;
+    }
+    if (!is_output) {
+        /* generate reg save code */
+        for(i = 0; i < NB_SAVED_REGS; i++) {
+            reg = reg_saved[i];
+            if (regs_allocated[reg]) 
+                g(0x50 + reg);
+        }
+
+        /* generate load code */
+        for(i = 0; i < nb_operands; i++) {
+            op = &operands[i];
+            if (op->reg >= 0) {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
+                    op->is_memory) {
+                    /* memory reference case (for both input and
+                       output cases) */
+                    SValue sv;
+                    sv = *op->vt;
+                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+                    load(op->reg, &sv);
+                } else if (i >= nb_outputs || op->is_rw) {
+                    /* load value in register */
+                    load(op->reg, op->vt);
+                    if (op->is_llong) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.c.ul += 4;
+                        load(TREG_EDX, &sv);
+                    }
+                }
+            }
+        }
+    } else {
+        /* generate save code */
+        for(i = 0 ; i < nb_outputs; i++) {
+            op = &operands[i];
+            if (op->reg >= 0) {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+                    if (!op->is_memory) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+                        load(out_reg, &sv);
+
+                        sv.r = (sv.r & ~VT_VALMASK) | out_reg;
+                        store(op->reg, &sv);
+                    }
+                } else {
+                    store(op->reg, op->vt);
+                    if (op->is_llong) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.c.ul += 4;
+                        store(TREG_EDX, &sv);
+                    }
+                }
+            }
+        }
+        /* generate reg restore code */
+        for(i = NB_SAVED_REGS - 1; i >= 0; i--) {
+            reg = reg_saved[i];
+            if (regs_allocated[reg]) 
+                g(0x58 + reg);
+        }
+    }
+}
+
+static void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+    int reg;
+    TokenSym *ts;
+
+    if (!strcmp(str, "memory") || 
+        !strcmp(str, "cc"))
+        return;
+    ts = tok_alloc(str, strlen(str));
+    reg = ts->tok;
+    if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
+        reg -= TOK_ASM_eax;
+    } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
+        reg -= TOK_ASM_ax;
+    } else {
+        error("invalid clobber register '%s'", str);
+    }
+    clobber_regs[reg] = 1;
+}
diff --git a/tinyc/i386-asm.h b/tinyc/i386-asm.h
new file mode 100755
index 000000000..a3b28d4d9
--- /dev/null
+++ b/tinyc/i386-asm.h
@@ -0,0 +1,446 @@
+     DEF_ASM_OP0(pusha, 0x60) /* must be first OP0 */
+     DEF_ASM_OP0(popa, 0x61)
+     DEF_ASM_OP0(clc, 0xf8)
+     DEF_ASM_OP0(cld, 0xfc)
+     DEF_ASM_OP0(cli, 0xfa)
+     DEF_ASM_OP0(clts, 0x0f06)
+     DEF_ASM_OP0(cmc, 0xf5)
+     DEF_ASM_OP0(lahf, 0x9f)
+     DEF_ASM_OP0(sahf, 0x9e)
+     DEF_ASM_OP0(pushfl, 0x9c)
+     DEF_ASM_OP0(popfl, 0x9d)
+     DEF_ASM_OP0(pushf, 0x9c)
+     DEF_ASM_OP0(popf, 0x9d)
+     DEF_ASM_OP0(stc, 0xf9)
+     DEF_ASM_OP0(std, 0xfd)
+     DEF_ASM_OP0(sti, 0xfb)
+     DEF_ASM_OP0(aaa, 0x37)
+     DEF_ASM_OP0(aas, 0x3f)
+     DEF_ASM_OP0(daa, 0x27)
+     DEF_ASM_OP0(das, 0x2f)
+     DEF_ASM_OP0(aad, 0xd50a)
+     DEF_ASM_OP0(aam, 0xd40a)
+     DEF_ASM_OP0(cbw, 0x6698)
+     DEF_ASM_OP0(cwd, 0x6699)
+     DEF_ASM_OP0(cwde, 0x98)
+     DEF_ASM_OP0(cdq, 0x99)
+     DEF_ASM_OP0(cbtw, 0x6698)
+     DEF_ASM_OP0(cwtl, 0x98)
+     DEF_ASM_OP0(cwtd, 0x6699)
+     DEF_ASM_OP0(cltd, 0x99)
+     DEF_ASM_OP0(int3, 0xcc)
+     DEF_ASM_OP0(into, 0xce)
+     DEF_ASM_OP0(iret, 0xcf)
+     DEF_ASM_OP0(rsm, 0x0faa)
+     DEF_ASM_OP0(hlt, 0xf4)
+     DEF_ASM_OP0(wait, 0x9b)
+     DEF_ASM_OP0(nop, 0x90)
+     DEF_ASM_OP0(xlat, 0xd7)
+
+     /* strings */
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
+
+     /* bits */
+     
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA))
+
+     /* prefixes */
+     DEF_ASM_OP0(aword, 0x67)
+     DEF_ASM_OP0(addr16, 0x67)
+     DEF_ASM_OP0(word, 0x66)
+     DEF_ASM_OP0(data16, 0x66)
+     DEF_ASM_OP0(lock, 0xf0)
+     DEF_ASM_OP0(rep, 0xf3)
+     DEF_ASM_OP0(repe, 0xf3)
+     DEF_ASM_OP0(repz, 0xf3)
+     DEF_ASM_OP0(repne, 0xf2)
+     DEF_ASM_OP0(repnz, 0xf2)
+             
+     DEF_ASM_OP0(invd, 0x0f08)
+     DEF_ASM_OP0(wbinvd, 0x0f09)
+     DEF_ASM_OP0(cpuid, 0x0fa2)
+     DEF_ASM_OP0(wrmsr, 0x0f30)
+     DEF_ASM_OP0(rdtsc, 0x0f31)
+     DEF_ASM_OP0(rdmsr, 0x0f32)
+     DEF_ASM_OP0(rdpmc, 0x0f33)
+     DEF_ASM_OP0(ud2, 0x0f0b)
+
+     /* NOTE: we took the same order as gas opcode definition order */
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWL, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWL, OPT_EAX, OPT_ADDR))
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWL, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WL, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WL, OPT_CR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WL, OPT_DB, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WL, OPT_TR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_DB))
+ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WL, OPT_REG32, OPT_TR))
+
+ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movsbw, 0x0fbe, 0, OPC_MODRM | OPC_D16, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WL, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WL, OPT_REGW))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WL, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WL, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WL, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WL, OPT_REGW))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WL, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_REG, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WL, OPT_EAX, OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
+
+ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
+ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
+ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WL, OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+
+     /* arith */
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWL, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WL, OPT_IM8S, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWL, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWL, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WL, OPT_REGW))
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WL, OPT_REGW))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WL, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WL, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WL, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWL, OPT_REG | OPT_EA, OPT_EAX))
+
+     /* shifts */
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWL | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_EA | OPT_REGW))
+
+ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR))
+ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR))
+
+ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, 0, OPT_EA))
+ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 0, OPT_EA))
+
+ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
+ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
+    DEF_ASM_OP0(leave, 0xc9)
+    DEF_ASM_OP0(ret, 0xc3)
+ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
+    DEF_ASM_OP0(lret, 0xcb)
+ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
+
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
+    DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
+    DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
+    DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
+    DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
+    DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
+    DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
+     
+     /* float */
+     /* specific fcomp handling */
+ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
+
+ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+
+     DEF_ASM_OP0(fucompp, 0xdae9)
+     DEF_ASM_OP0(ftst, 0xd9e4)
+     DEF_ASM_OP0(fxam, 0xd9e5)
+     DEF_ASM_OP0(fld1, 0xd9e8)
+     DEF_ASM_OP0(fldl2t, 0xd9e9)
+     DEF_ASM_OP0(fldl2e, 0xd9ea)
+     DEF_ASM_OP0(fldpi, 0xd9eb)
+     DEF_ASM_OP0(fldlg2, 0xd9ec)
+     DEF_ASM_OP0(fldln2, 0xd9ed)
+     DEF_ASM_OP0(fldz, 0xd9ee)
+
+     DEF_ASM_OP0(f2xm1, 0xd9f0)
+     DEF_ASM_OP0(fyl2x, 0xd9f1)
+     DEF_ASM_OP0(fptan, 0xd9f2)
+     DEF_ASM_OP0(fpatan, 0xd9f3)
+     DEF_ASM_OP0(fxtract, 0xd9f4)
+     DEF_ASM_OP0(fprem1, 0xd9f5)
+     DEF_ASM_OP0(fdecstp, 0xd9f6)
+     DEF_ASM_OP0(fincstp, 0xd9f7)
+     DEF_ASM_OP0(fprem, 0xd9f8)
+     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
+     DEF_ASM_OP0(fsqrt, 0xd9fa)
+     DEF_ASM_OP0(fsincos, 0xd9fb)
+     DEF_ASM_OP0(frndint, 0xd9fc)
+     DEF_ASM_OP0(fscale, 0xd9fd)
+     DEF_ASM_OP0(fsin, 0xd9fe)
+     DEF_ASM_OP0(fcos, 0xd9ff)
+     DEF_ASM_OP0(fchs, 0xd9e0)
+     DEF_ASM_OP0(fabs, 0xd9e1)
+     DEF_ASM_OP0(fninit, 0xdbe3)
+     DEF_ASM_OP0(fnclex, 0xdbe2)
+     DEF_ASM_OP0(fnop, 0xd9d0)
+     DEF_ASM_OP0(fwait, 0x9b)
+
+    /* fp load */
+    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
+    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
+    
+    /* fp store */
+    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
+
+    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
+
+    /* exchange */
+    DEF_ASM_OP0(fxch, 0xd9c9)
+ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
+
+    /* misc FPU */
+    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
+
+    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP0(fnstsw, 0xdfe0)
+ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
+ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
+    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
+ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
+ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
+    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+
+    /* segments */
+    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
+    DEF_ASM_OP2(lar, 0x0f02, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG32)
+    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
+    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WL, OPT_EA | OPT_REG, OPT_REG))
+    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
+    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
+    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+
+    /* 486 */
+    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT_EA ))
+    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
+
+    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
+    DEF_ASM_OP2(boundw, 0x62, 0, OPC_MODRM | OPC_D16, OPT_REG16, OPT_EA)
+
+    /* pentium */
+    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
+    
+    /* pentium pro */
+    ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
+
+    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    /* mmx */
+    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
+    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMX )
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
+    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMX ))
+    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+
+#undef ALT
+#undef DEF_ASM_OP0
+#undef DEF_ASM_OP0L
+#undef DEF_ASM_OP1
+#undef DEF_ASM_OP2
+#undef DEF_ASM_OP3
diff --git a/tinyc/i386-gen.c b/tinyc/i386-gen.c
new file mode 100755
index 000000000..f958ab547
--- /dev/null
+++ b/tinyc/i386-gen.c
@@ -0,0 +1,1034 @@
+/*
+ *  X86 code generator for TCC
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* number of available registers */
+#define NB_REGS             4
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_EAX     0x0004
+#define RC_ST0     0x0008 
+#define RC_ECX     0x0010
+#define RC_EDX     0x0020
+#define RC_IRET    RC_EAX /* function return: integer register */
+#define RC_LRET    RC_EDX /* function return: second integer register */
+#define RC_FRET    RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_EAX = 0,
+    TREG_ECX,
+    TREG_EDX,
+    TREG_ST0,
+};
+
+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) */
+#define REG_FRET TREG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+//#define FUNC_STRUCT_PARAM_AS_PTR
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+/******************************************************/
+/* ELF defines */
+
+#define EM_TCC_TARGET EM_386
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_386_32
+#define R_JMP_SLOT  R_386_JMP_SLOT
+#define R_COPY      R_386_COPY
+
+#define ELF_START_ADDR 0x08048000
+#define ELF_PAGE_SIZE  0x1000
+
+/******************************************************/
+
+static unsigned long func_sub_sp_offset;
+static unsigned long func_bound_offset;
+static int func_ret_sub;
+
+/* XXX: make it faster ? */
+void g(int c)
+{
+    int ind1;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+void o(unsigned int c)
+{
+    while (c) {
+        g(c);
+        c = c >> 8;
+    }
+}
+
+void gen_le32(int c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+    int n, *ptr;
+    while (t) {
+        ptr = (int *)(cur_text_section->data + t);
+        n = *ptr; /* next value */
+        *ptr = a - t - 4;
+        t = n;
+    }
+}
+
+void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+/* psym is used to put an instruction with a data field which is a
+   reference to a symbol. It is in fact the same as oad ! */
+#define psym oad
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+    int ind1;
+
+    o(c);
+    ind1 = ind + 4;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    *(int *)(cur_text_section->data + ind) = s;
+    s = ind;
+    ind = ind1;
+    return s;
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+static 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);
+}
+
+/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+   opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+    op_reg = op_reg << 3;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        /* constant memory reference */
+        o(0x05 | op_reg);
+        gen_addr32(r, sym, c);
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+        /* currently, we use only ebp as base */
+        if (c == (char)c) {
+            /* short reference */
+            o(0x45 | op_reg);
+            g(c);
+        } else {
+            oad(0x85 | op_reg, c);
+        }
+    } else {
+        g(0x00 | op_reg | (r & VT_VALMASK));
+    }
+}
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+    int v, t, ft, fc, fr;
+    SValue v1;
+
+    fr = sv->r;
+    ft = sv->type.t;
+    fc = sv->c.ul;
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+        if (v == VT_LLOCAL) {
+            v1.type.t = VT_INT;
+            v1.r = VT_LOCAL | VT_LVAL;
+            v1.c.ul = fc;
+            load(r, &v1);
+            fr = r;
+        }
+        if ((ft & VT_BTYPE) == VT_FLOAT) {
+            o(0xd9); /* flds */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+            o(0xdd); /* fldl */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            o(0xdb); /* fldt */
+            r = 5;
+        } else if ((ft & VT_TYPE) == VT_BYTE) {
+            o(0xbe0f);   /* movsbl */
+        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+            o(0xb60f);   /* movzbl */
+        } else if ((ft & VT_TYPE) == VT_SHORT) {
+            o(0xbf0f);   /* movswl */
+        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+            o(0xb70f);   /* movzwl */
+        } else {
+            o(0x8b);     /* movl */
+        }
+        gen_modrm(r, fr, sv->sym, fc);
+    } else {
+        if (v == VT_CONST) {
+            o(0xb8 + r); /* mov $xx, r */
+            gen_addr32(fr, sv->sym, fc);
+        } else if (v == VT_LOCAL) {
+            o(0x8d); /* lea xxx(%ebp), r */
+            gen_modrm(r, VT_LOCAL, sv->sym, fc);
+        } else if (v == VT_CMP) {
+            oad(0xb8 + r, 0); /* mov $0, r */
+            o(0x0f); /* setxx %br */
+            o(fc);
+            o(0xc0 + r);
+        } else if (v == VT_JMP || v == VT_JMPI) {
+            t = v & 1;
+            oad(0xb8 + r, t); /* mov $1, r */
+            o(0x05eb); /* jmp after */
+            gsym(fc);
+            oad(0xb8 + r, t ^ 1); /* mov $0, r */
+        } else if (v != r) {
+            o(0x89);
+            o(0xc0 + r + v * 8); /* mov v, r */
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *v)
+{
+    int fr, bt, ft, fc;
+
+    ft = v->type.t;
+    fc = v->c.ul;
+    fr = v->r & VT_VALMASK;
+    bt = ft & VT_BTYPE;
+    /* XXX: incorrect if float reg to reg */
+    if (bt == VT_FLOAT) {
+        o(0xd9); /* fsts */
+        r = 2;
+    } else if (bt == VT_DOUBLE) {
+        o(0xdd); /* fstpl */
+        r = 2;
+    } else if (bt == VT_LDOUBLE) {
+        o(0xc0d9); /* fld %st(0) */
+        o(0xdb); /* fstpt */
+        r = 7;
+    } else {
+        if (bt == VT_SHORT)
+            o(0x66);
+        if (bt == VT_BYTE || bt == VT_BOOL)
+            o(0x88);
+        else
+            o(0x89);
+    }
+    if (fr == VT_CONST ||
+        fr == VT_LOCAL ||
+        (v->r & VT_LVAL)) {
+        gen_modrm(r, v->r, v->sym, fc);
+    } else if (fr != r) {
+        o(0xc0 + fr + r * 8); /* mov r, fr */
+    }
+}
+
+static void gadd_sp(int val)
+{
+    if (val == (char)val) {
+        o(0xc483);
+        g(val);
+    } else {
+        oad(0xc481, val); /* add $xxx, %esp */
+    }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        /* constant case */
+        if (vtop->r & VT_SYM) {
+            /* relocation case */
+            greloc(cur_text_section, vtop->sym, 
+                   ind + 1, R_386_PC32);
+        } else {
+            /* put an empty PC32 relocation */
+            put_elf_reloc(symtab_section, cur_text_section, 
+                          ind + 1, R_386_PC32, 0);
+        }
+        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
+    } else {
+        /* otherwise, indirect call */
+        r = gv(RC_INT);
+        o(0xff); /* call/jmp *r */
+        o(0xd0 + r + (is_jmp << 4));
+    }
+}
+
+static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
+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)
+{
+    int size, align, r, args_size, i, func_call;
+    Sym *func_sym;
+    
+    args_size = 0;
+    for(i = 0;i < nb_args; i++) {
+        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+            size = type_size(&vtop->type, &align);
+            /* align to stack align size */
+            size = (size + 3) & ~3;
+            /* allocate the necessary size on stack */
+            oad(0xec81, size); /* sub $xxx, %esp */
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            o(0x89); /* mov %esp, r */
+            o(0xe0 + r);
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore();
+            args_size += size;
+        } else if (is_float(vtop->type.t)) {
+            gv(RC_FLOAT); /* only one float register */
+            if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+            else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+                size = 8;
+            else
+                size = 12;
+            oad(0xec81, size); /* sub $xxx, %esp */
+            if (size == 12)
+                o(0x7cdb);
+            else
+                o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
+            g(0x24);
+            g(0x00);
+            args_size += size;
+        } else {
+            /* simple type (currently always same size) */
+            /* XXX: implicit cast ? */
+            r = gv(RC_INT);
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                size = 8;
+                o(0x50 + vtop->r2); /* push r */
+            } else {
+                size = 4;
+            }
+            o(0x50 + r); /* push r */
+            args_size += size;
+        }
+        vtop--;
+    }
+    save_regs(0); /* save used temporary registers */
+    func_sym = vtop->type.ref;
+    func_call = FUNC_CALL(func_sym->r);
+    /* fast call case */
+    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
+        func_call == FUNC_FASTCALLW) {
+        int fastcall_nb_regs;
+        uint8_t *fastcall_regs_ptr;
+        if (func_call == FUNC_FASTCALLW) {
+            fastcall_regs_ptr = fastcallw_regs;
+            fastcall_nb_regs = 2;
+        } else {
+            fastcall_regs_ptr = fastcall_regs;
+            fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+        }
+        for(i = 0;i < fastcall_nb_regs; i++) {
+            if (args_size <= 0)
+                break;
+            o(0x58 + fastcall_regs_ptr[i]); /* pop r */
+            /* XXX: incorrect for struct/floats */
+            args_size -= 4;
+        }
+    }
+    gcall_or_jmp(0);
+    if (args_size && func_call != FUNC_STDCALL)
+        gadd_sp(args_size);
+    vtop--;
+}
+
+#ifdef TCC_TARGET_PE
+#define FUNC_PROLOG_SIZE 10
+#else
+#define FUNC_PROLOG_SIZE 9
+#endif
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+    int addr, align, size, func_call, fastcall_nb_regs;
+    int param_index, param_addr;
+    uint8_t *fastcall_regs_ptr;
+    Sym *sym;
+    CType *type;
+
+    sym = func_type->ref;
+    func_call = FUNC_CALL(sym->r);
+    addr = 8;
+    loc = 0;
+    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
+        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+        fastcall_regs_ptr = fastcall_regs;
+    } else if (func_call == FUNC_FASTCALLW) {
+        fastcall_nb_regs = 2;
+        fastcall_regs_ptr = fastcallw_regs;
+    } else {
+        fastcall_nb_regs = 0;
+        fastcall_regs_ptr = NULL;
+    }
+    param_index = 0;
+
+    ind += FUNC_PROLOG_SIZE;
+    func_sub_sp_offset = ind;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+        /* XXX: fastcall case ? */
+        func_vc = addr;
+        addr += 4;
+        param_index++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        type = &sym->type;
+        size = type_size(type, &align);
+        size = (size + 3) & ~3;
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+        /* structs are passed as pointer */
+        if ((type->t & VT_BTYPE) == VT_STRUCT) {
+            size = 4;
+        }
+#endif
+        if (param_index < fastcall_nb_regs) {
+            /* save FASTCALL register */
+            loc -= 4;
+            o(0x89);     /* movl */
+            gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
+            param_addr = loc;
+        } else {
+            param_addr = addr;
+            addr += size;
+        }
+        sym_push(sym->v & ~SYM_FIELD, type,
+                 VT_LOCAL | lvalue_type(type->t), param_addr);
+        param_index++;
+    }
+    func_ret_sub = 0;
+    /* pascal type call ? */
+    if (func_call == FUNC_STDCALL)
+        func_ret_sub = addr - 8;
+
+    /* leave some room for bound checking code */
+    if (tcc_state->do_bounds_check) {
+        oad(0xb8, 0); /* lbound section pointer */
+        oad(0xb8, 0); /* call to function */
+        func_bound_offset = lbounds_section->data_offset;
+    }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    int v, saved_ind;
+
+#ifdef CONFIG_TCC_BCHECK
+    if (tcc_state->do_bounds_check
+     && func_bound_offset != lbounds_section->data_offset) {
+        int saved_ind;
+        int *bounds_ptr;
+        Sym *sym, *sym_data;
+        /* add end of table info */
+        bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
+        *bounds_ptr = 0;
+        /* generate bound local allocation */
+        saved_ind = ind;
+        ind = func_sub_sp_offset;
+        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
+                               func_bound_offset, lbounds_section->data_offset);
+        greloc(cur_text_section, sym_data,
+               ind + 1, R_386_32);
+        oad(0xb8, 0); /* mov %eax, xxx */
+        sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
+        greloc(cur_text_section, sym, 
+               ind + 1, R_386_PC32);
+        oad(0xe8, -4);
+        ind = saved_ind;
+        /* generate bound check local freeing */
+        o(0x5250); /* save returned value, if any */
+        greloc(cur_text_section, sym_data,
+               ind + 1, R_386_32);
+        oad(0xb8, 0); /* mov %eax, xxx */
+        sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
+        greloc(cur_text_section, sym, 
+               ind + 1, R_386_PC32);
+        oad(0xe8, -4);
+        o(0x585a); /* restore returned value, if any */
+    }
+#endif
+    o(0xc9); /* leave */
+    if (func_ret_sub == 0) {
+        o(0xc3); /* ret */
+    } else {
+        o(0xc2); /* ret n */
+        g(func_ret_sub);
+        g(func_ret_sub >> 8);
+    }
+    /* align local size to word & save local variables */
+    
+    v = (-loc + 3) & -4; 
+    saved_ind = ind;
+    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+#ifdef TCC_TARGET_PE
+    if (v >= 4096) {
+        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
+        oad(0xb8, v); /* mov stacksize, %eax */
+        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
+        greloc(cur_text_section, sym, ind-4, R_386_PC32);
+    } else
+#endif
+    {
+        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
+        o(0xec81);  /* sub esp, stacksize */
+        gen_le32(v);
+#if FUNC_PROLOG_SIZE == 10
+        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
+#endif
+    }
+    ind = saved_ind;
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    return psym(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    int r;
+    r = a - ind - 2;
+    if (r == (char)r) {
+        g(0xeb);
+        g(r);
+    } else {
+        oad(0xe9, a - ind - 5);
+    }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int v, *p;
+
+    v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+        /* fast case : can jump directly since flags are set */
+        g(0x0f);
+        t = psym((vtop->c.i - 16) ^ inv, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            p = &vtop->c.i;
+            while (*p != 0)
+                p = (int *)(cur_text_section->data + *p);
+            *p = t;
+            t = vtop->c.i;
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    } else {
+        if (is_float(vtop->type.t) || 
+            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            vpushi(0);
+            gen_op(TOK_NE);
+        }
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant jmp optimization */
+            if ((vtop->c.i != 0) != inv) 
+                t = gjmp(t);
+        } else {
+            v = gv(RC_INT);
+            o(0x85);
+            o(0xc0 + v * 9);
+            g(0x0f);
+            t = psym(0x85 ^ inv, t);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    int r, fr, opc, c;
+
+    switch(op) {
+    case '+':
+    case TOK_ADDC1: /* add with carry generation */
+        opc = 0;
+    gen_op8:
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            c = vtop->c.i;
+            if (c == (char)c) {
+                /* XXX: generate inc and dec for smaller code ? */
+                o(0x83);
+                o(0xc0 | (opc << 3) | r);
+                g(c);
+            } else {
+                o(0x81);
+                oad(0xc0 | (opc << 3) | r, c);
+            }
+        } else {
+            gv2(RC_INT, RC_INT);
+            r = vtop[-1].r;
+            fr = vtop[0].r;
+            o((opc << 3) | 0x01);
+            o(0xc0 + r + fr * 8); 
+        }
+        vtop--;
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        }
+        break;
+    case '-':
+    case TOK_SUBC1: /* sub with carry generation */
+        opc = 5;
+        goto gen_op8;
+    case TOK_ADDC2: /* add with carry use */
+        opc = 2;
+        goto gen_op8;
+    case TOK_SUBC2: /* sub with carry use */
+        opc = 3;
+        goto gen_op8;
+    case '&':
+        opc = 4;
+        goto gen_op8;
+    case '^':
+        opc = 6;
+        goto gen_op8;
+    case '|':
+        opc = 1;
+        goto gen_op8;
+    case '*':
+        gv2(RC_INT, RC_INT);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        o(0xaf0f); /* imul fr, r */
+        o(0xc0 + fr + r * 8);
+        break;
+    case TOK_SHL:
+        opc = 4;
+        goto gen_shift;
+    case TOK_SHR:
+        opc = 5;
+        goto gen_shift;
+    case TOK_SAR:
+        opc = 7;
+    gen_shift:
+        opc = 0xc0 | (opc << 3);
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            c = vtop->c.i & 0x1f;
+            o(0xc1); /* shl/shr/sar $xxx, r */
+            o(opc | r);
+            g(c);
+        } else {
+            /* we generate the shift in ecx */
+            gv2(RC_INT, RC_ECX);
+            r = vtop[-1].r;
+            o(0xd3); /* shl/shr/sar %cl, r */
+            o(opc | r);
+        }
+        vtop--;
+        break;
+    case '/':
+    case TOK_UDIV:
+    case TOK_PDIV:
+    case '%':
+    case TOK_UMOD:
+    case TOK_UMULL:
+        /* first operand must be in eax */
+        /* XXX: need better constraint for second operand */
+        gv2(RC_EAX, RC_ECX);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        save_reg(TREG_EDX);
+        if (op == TOK_UMULL) {
+            o(0xf7); /* mul fr */
+            o(0xe0 + fr);
+            vtop->r2 = TREG_EDX;
+            r = TREG_EAX;
+        } else {
+            if (op == TOK_UDIV || op == TOK_UMOD) {
+                o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
+                o(0xf0 + fr);
+            } else {
+                o(0xf799); /* cltd, idiv fr, %eax */
+                o(0xf8 + fr);
+            }
+            if (op == '%' || op == TOK_UMOD)
+                r = TREG_EDX;
+            else
+                r = TREG_EAX;
+        }
+        vtop->r = r;
+        break;
+    default:
+        opc = 7;
+        goto gen_op8;
+    }
+}
+
+/* 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)
+{
+    int a, ft, fc, swapped, r;
+
+    /* convert constants to memory references */
+    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        vswap();
+        gv(RC_FLOAT);
+        vswap();
+    }
+    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+        gv(RC_FLOAT);
+
+    /* must put at least one value in the floating point register */
+    if ((vtop[-1].r & VT_LVAL) &&
+        (vtop[0].r & VT_LVAL)) {
+        vswap();
+        gv(RC_FLOAT);
+        vswap();
+    }
+    swapped = 0;
+    /* swap the stack if needed so that t1 is the register and t2 is
+       the memory reference */
+    if (vtop[-1].r & VT_LVAL) {
+        vswap();
+        swapped = 1;
+    }
+    if (op >= TOK_ULT && op <= TOK_GT) {
+        /* load on stack second operand */
+        load(TREG_ST0, vtop);
+        save_reg(TREG_EAX); /* eax is used by FP comparison code */
+        if (op == TOK_GE || op == TOK_GT)
+            swapped = !swapped;
+        else if (op == TOK_EQ || op == TOK_NE)
+            swapped = 0;
+        if (swapped)
+            o(0xc9d9); /* fxch %st(1) */
+        o(0xe9da); /* fucompp */
+        o(0xe0df); /* fnstsw %ax */
+        if (op == TOK_EQ) {
+            o(0x45e480); /* and $0x45, %ah */
+            o(0x40fC80); /* cmp $0x40, %ah */
+        } else if (op == TOK_NE) {
+            o(0x45e480); /* and $0x45, %ah */
+            o(0x40f480); /* xor $0x40, %ah */
+            op = TOK_NE;
+        } else if (op == TOK_GE || op == TOK_LE) {
+            o(0x05c4f6); /* test $0x05, %ah */
+            op = TOK_EQ;
+        } else {
+            o(0x45c4f6); /* test $0x45, %ah */
+            op = TOK_EQ;
+        }
+        vtop--;
+        vtop->r = VT_CMP;
+        vtop->c.i = op;
+    } else {
+        /* no memory reference possible for long double operations */
+        if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+            load(TREG_ST0, vtop);
+            swapped = !swapped;
+        }
+        
+        switch(op) {
+        default:
+        case '+':
+            a = 0;
+            break;
+        case '-':
+            a = 4;
+            if (swapped)
+                a++;
+            break;
+        case '*':
+            a = 1;
+            break;
+        case '/':
+            a = 6;
+            if (swapped)
+                a++;
+            break;
+        }
+        ft = vtop->type.t;
+        fc = vtop->c.ul;
+        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            o(0xde); /* fxxxp %st, %st(1) */
+            o(0xc1 + (a << 3));
+        } else {
+            /* if saved lvalue, then we must reload it */
+            r = vtop->r;
+            if ((r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_INT;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.ul = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+
+            if ((ft & VT_BTYPE) == VT_DOUBLE)
+                o(0xdc);
+            else
+                o(0xd8);
+            gen_modrm(a, r, vtop->sym, fc);
+        }
+        vtop--;
+    }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    save_reg(TREG_ST0);
+    gv(RC_INT);
+    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+        /* signed long long to float/double/long double (unsigned case
+           is handled generically) */
+        o(0x50 + vtop->r2); /* push r2 */
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x242cdf); /* fildll (%esp) */
+        o(0x08c483); /* add $8, %esp */
+    } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
+               (VT_INT | VT_UNSIGNED)) {
+        /* unsigned int to float/double/long double */
+        o(0x6a); /* push $0 */
+        g(0x00);
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x242cdf); /* fildll (%esp) */
+        o(0x08c483); /* add $8, %esp */
+    } else {
+        /* int to float/double/long double */
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x2404db); /* fildl (%esp) */
+        o(0x04c483); /* add $4, %esp */
+    }
+    vtop->r = TREG_ST0;
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+    int r, r2, size;
+    Sym *sym;
+    CType ushort_type;
+
+    ushort_type.t = VT_SHORT | VT_UNSIGNED;
+
+    gv(RC_FLOAT);
+    if (t != VT_INT)
+        size = 8;
+    else 
+        size = 4;
+    
+    o(0x2dd9); /* ldcw xxx */
+    sym = external_global_sym(TOK___tcc_int_fpu_control, 
+                              &ushort_type, VT_LVAL);
+    greloc(cur_text_section, sym, 
+           ind, R_386_32);
+    gen_le32(0);
+    
+    oad(0xec81, size); /* sub $xxx, %esp */
+    if (size == 4)
+        o(0x1cdb); /* fistpl */
+    else
+        o(0x3cdf); /* fistpll */
+    o(0x24);
+    o(0x2dd9); /* ldcw xxx */
+    sym = external_global_sym(TOK___tcc_fpu_control, 
+                              &ushort_type, VT_LVAL);
+    greloc(cur_text_section, sym, 
+           ind, R_386_32);
+    gen_le32(0);
+
+    r = get_reg(RC_INT);
+    o(0x58 + r); /* pop r */
+    if (size == 8) {
+        if (t == VT_LLONG) {
+            vtop->r = r; /* mark reg as used */
+            r2 = get_reg(RC_INT);
+            o(0x58 + r2); /* pop r2 */
+            vtop->r2 = r2;
+        } else {
+            o(0x04c483); /* add $4, %esp */
+        }
+    }
+    vtop->r = r;
+}
+
+/* convert from one floating point type to another */
+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)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* bound check support functions */
+#ifdef CONFIG_TCC_BCHECK
+
+/* generate a bounded pointer addition */
+void gen_bounded_ptr_add(void)
+{
+    Sym *sym;
+
+    /* prepare fast i386 function call (args in eax and edx) */
+    gv2(RC_EAX, RC_EDX);
+    /* save all temporary registers */
+    vtop -= 2;
+    save_regs(0);
+    /* do a fast function call */
+    sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
+    greloc(cur_text_section, sym, 
+           ind + 1, R_386_PC32);
+    oad(0xe8, -4);
+    /* returned pointer is in eax */
+    vtop++;
+    vtop->r = TREG_EAX | VT_BOUNDED;
+    /* address of bounding function call point */
+    vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+   also tested */
+void gen_bounded_ptr_deref(void)
+{
+    int func;
+    int size, align;
+    Elf32_Rel *rel;
+    Sym *sym;
+
+    size = 0;
+    /* XXX: put that code in generic part of tcc */
+    if (!is_float(vtop->type.t)) {
+        if (vtop->r & VT_LVAL_BYTE)
+            size = 1;
+        else if (vtop->r & VT_LVAL_SHORT)
+            size = 2;
+    }
+    if (!size)
+        size = type_size(&vtop->type, &align);
+    switch(size) {
+    case  1: func = TOK___bound_ptr_indir1; break;
+    case  2: func = TOK___bound_ptr_indir2; break;
+    case  4: func = TOK___bound_ptr_indir4; break;
+    case  8: func = TOK___bound_ptr_indir8; break;
+    case 12: func = TOK___bound_ptr_indir12; break;
+    case 16: func = TOK___bound_ptr_indir16; break;
+    default:
+        error("unhandled size when derefencing bounded pointer");
+        func = 0;
+        break;
+    }
+
+    /* patch relocation */
+    /* XXX: find a better solution ? */
+    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
+    sym = external_global_sym(func, &func_old_type, 0);
+    if (!sym->c)
+        put_extern_sym(sym, NULL, 0, 0);
+    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
+}
+#endif
+
+/* end of X86 code generator */
+/*************************************************************/
+
diff --git a/tinyc/il-gen.c b/tinyc/il-gen.c
new file mode 100755
index 000000000..29f052655
--- /dev/null
+++ b/tinyc/il-gen.c
@@ -0,0 +1,667 @@
+/*
+ *  CIL code generator for TCC
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* number of available registers */
+#define NB_REGS             3
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_ST      0x0001  /* any stack entry */
+#define RC_ST0     0x0002  /* top of stack */
+#define RC_ST1     0x0004  /* top - 1 */
+
+#define RC_INT     RC_ST
+#define RC_FLOAT   RC_ST
+#define RC_IRET    RC_ST0 /* function return: integer register */
+#define RC_LRET    RC_ST0 /* function return: second integer register */
+#define RC_FRET    RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    REG_ST0 = 0,
+    REG_ST1,
+    REG_ST2,
+};
+
+int reg_classes[NB_REGS] = {
+    /* ST0 */ RC_ST | RC_ST0,
+    /* ST1 */ RC_ST | RC_ST1,
+    /* ST2 */ RC_ST,
+};
+
+/* return registers for function */
+#define REG_IRET REG_ST0 /* single word int return register */
+#define REG_LRET REG_ST0 /* second word return register (for long long) */
+#define REG_FRET REG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+//#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+//#define FUNC_STRUCT_PARAM_AS_PTR
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  8
+#define LDOUBLE_ALIGN 8
+
+/* function call context */
+typedef struct GFuncContext {
+    int func_call; /* func call type (FUNC_STDCALL or FUNC_CDECL) */
+} GFuncContext;
+
+/******************************************************/
+/* opcode definitions */
+
+#define IL_OP_PREFIX 0xFE
+
+enum ILOPCodes {
+#define OP(name, str, n) IL_OP_ ## name = n,
+#include "il-opcodes.h"
+#undef OP
+};
+
+char *il_opcodes_str[] = {
+#define OP(name, str, n) [n] = str,
+#include "il-opcodes.h"
+#undef OP
+};
+
+/******************************************************/
+
+/* arguments variable numbers start from there */
+#define ARG_BASE 0x70000000
+
+static FILE *il_outfile;
+
+static void out_byte(int c)
+{
+    *(char *)ind++ = c;
+}
+
+static void out_le32(int c)
+{
+    out_byte(c);
+    out_byte(c >> 8);
+    out_byte(c >> 16);
+    out_byte(c >> 24);
+}
+
+static void init_outfile(void)
+{
+    if (!il_outfile) {
+        il_outfile = stdout;
+        fprintf(il_outfile, 
+                ".assembly extern mscorlib\n"
+                "{\n"
+                ".ver 1:0:2411:0\n"
+                "}\n\n");
+    }
+}
+
+static void out_op1(int op)
+{
+    if (op & 0x100)
+        out_byte(IL_OP_PREFIX);
+    out_byte(op & 0xff);
+}
+
+/* output an opcode with prefix */
+static void out_op(int op)
+{
+    out_op1(op);
+    fprintf(il_outfile, " %s\n", il_opcodes_str[op]);
+}
+
+static void out_opb(int op, int c)
+{
+    out_op1(op);
+    out_byte(c);
+    fprintf(il_outfile, " %s %d\n", il_opcodes_str[op], c);
+}
+
+static void out_opi(int op, int c)
+{
+    out_op1(op);
+    out_le32(c);
+    fprintf(il_outfile, " %s 0x%x\n", il_opcodes_str[op], c);
+}
+
+/* XXX: not complete */
+static void il_type_to_str(char *buf, int buf_size, 
+                           int t, const char *varstr)
+{
+    int bt;
+    Sym *s, *sa;
+    char buf1[256];
+    const char *tstr;
+
+    t = t & VT_TYPE;
+    bt = t & VT_BTYPE;
+    buf[0] = '\0';
+    if (t & VT_UNSIGNED)
+        pstrcat(buf, buf_size, "unsigned ");
+    switch(bt) {
+    case VT_VOID:
+        tstr = "void";
+        goto add_tstr;
+    case VT_BOOL:
+        tstr = "bool";
+        goto add_tstr;
+    case VT_BYTE:
+        tstr = "int8";
+        goto add_tstr;
+    case VT_SHORT:
+        tstr = "int16";
+        goto add_tstr;
+    case VT_ENUM:
+    case VT_INT:
+    case VT_LONG:
+        tstr = "int32";
+        goto add_tstr;
+    case VT_LLONG:
+        tstr = "int64";
+        goto add_tstr;
+    case VT_FLOAT:
+        tstr = "float32";
+        goto add_tstr;
+    case VT_DOUBLE:
+    case VT_LDOUBLE:
+        tstr = "float64";
+    add_tstr:
+        pstrcat(buf, buf_size, tstr);
+        break;
+    case VT_STRUCT:
+        error("structures not handled yet");
+        break;
+    case VT_FUNC:
+        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+        il_type_to_str(buf, buf_size, s->t, varstr);
+        pstrcat(buf, buf_size, "(");
+        sa = s->next;
+        while (sa != NULL) {
+            il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
+            pstrcat(buf, buf_size, buf1);
+            sa = sa->next;
+            if (sa)
+                pstrcat(buf, buf_size, ", ");
+        }
+        pstrcat(buf, buf_size, ")");
+        goto no_var;
+    case VT_PTR:
+        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+        pstrcpy(buf1, sizeof(buf1), "*");
+        if (varstr)
+            pstrcat(buf1, sizeof(buf1), varstr);
+        il_type_to_str(buf, buf_size, s->t, buf1);
+        goto no_var;
+    }
+    if (varstr) {
+        pstrcat(buf, buf_size, " ");
+        pstrcat(buf, buf_size, varstr);
+    }
+ no_var: ;
+}
+
+
+/* patch relocation entry with value 'val' */
+void greloc_patch1(Reloc *p, int val)
+{
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(t, a)
+{
+}
+
+/* output jump and return symbol */
+static int out_opj(int op, int c)
+{
+    out_op1(op);
+    out_le32(0);
+    if (c == 0) {
+        c = ind - (int)cur_text_section->data;
+    }
+    fprintf(il_outfile, " %s L%d\n", il_opcodes_str[op], c);
+    return c;
+}
+
+void gsym(int t)
+{
+    fprintf(il_outfile, "L%d:\n", t);
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+    int v, fc, ft;
+
+    v = sv->r & VT_VALMASK;
+    fc = sv->c.i;
+    ft = sv->t;
+
+    if (sv->r & VT_LVAL) {
+        if (v == VT_LOCAL) {
+            if (fc >= ARG_BASE) {
+                fc -= ARG_BASE;
+                if (fc >= 0 && fc <= 4) {
+                    out_op(IL_OP_LDARG_0 + fc);
+                } else if (fc <= 0xff) {
+                    out_opb(IL_OP_LDARG_S, fc);
+                } else {
+                    out_opi(IL_OP_LDARG, fc);
+                }
+            } else {
+                if (fc >= 0 && fc <= 4) {
+                    out_op(IL_OP_LDLOC_0 + fc);
+                } else if (fc <= 0xff) {
+                    out_opb(IL_OP_LDLOC_S, fc);
+                } else {
+                    out_opi(IL_OP_LDLOC, fc);
+                }
+            }
+        } else if (v == VT_CONST) {
+                /* XXX: handle globals */
+                out_opi(IL_OP_LDSFLD, 0);
+        } else {
+            if ((ft & VT_BTYPE) == VT_FLOAT) {
+                out_op(IL_OP_LDIND_R4);
+            } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                out_op(IL_OP_LDIND_R8);
+            } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+                out_op(IL_OP_LDIND_R8);
+            } else if ((ft & VT_TYPE) == VT_BYTE)
+                out_op(IL_OP_LDIND_I1);
+            else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED))
+                out_op(IL_OP_LDIND_U1);
+            else if ((ft & VT_TYPE) == VT_SHORT)
+                out_op(IL_OP_LDIND_I2);
+            else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
+                out_op(IL_OP_LDIND_U2);
+            else
+                out_op(IL_OP_LDIND_I4);
+        } 
+    } else {
+        if (v == VT_CONST) {
+            /* XXX: handle globals */
+            if (fc >= -1 && fc <= 8) {
+                out_op(IL_OP_LDC_I4_M1 + fc + 1); 
+            } else {
+                out_opi(IL_OP_LDC_I4, fc);
+            }
+        } else if (v == VT_LOCAL) {
+            if (fc >= ARG_BASE) {
+                fc -= ARG_BASE;
+                if (fc <= 0xff) {
+                    out_opb(IL_OP_LDARGA_S, fc);
+                } else {
+                    out_opi(IL_OP_LDARGA, fc);
+                }
+            } else {
+                if (fc <= 0xff) {
+                    out_opb(IL_OP_LDLOCA_S, fc);
+                } else {
+                    out_opi(IL_OP_LDLOCA, fc);
+                }
+            }
+        } else {
+            /* XXX: do it */
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+    int v, fc, ft;
+
+    v = sv->r & VT_VALMASK;
+    fc = sv->c.i;
+    ft = sv->t;
+    if (v == VT_LOCAL) {
+        if (fc >= ARG_BASE) {
+            fc -= ARG_BASE;
+            /* XXX: check IL arg store semantics */
+            if (fc <= 0xff) {
+                out_opb(IL_OP_STARG_S, fc);
+            } else {
+                out_opi(IL_OP_STARG, fc);
+            }
+        } else {
+            if (fc >= 0 && fc <= 4) {
+                out_op(IL_OP_STLOC_0 + fc);
+            } else if (fc <= 0xff) {
+                out_opb(IL_OP_STLOC_S, fc);
+            } else {
+                out_opi(IL_OP_STLOC, fc);
+            }
+        }
+    } else if (v == VT_CONST) {
+        /* XXX: handle globals */
+        out_opi(IL_OP_STSFLD, 0);
+    } else {
+        if ((ft & VT_BTYPE) == VT_FLOAT)
+            out_op(IL_OP_STIND_R4);
+        else if ((ft & VT_BTYPE) == VT_DOUBLE)
+            out_op(IL_OP_STIND_R8);
+        else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+            out_op(IL_OP_STIND_R8);
+        else if ((ft & VT_BTYPE) == VT_BYTE)
+            out_op(IL_OP_STIND_I1);
+        else if ((ft & VT_BTYPE) == VT_SHORT)
+            out_op(IL_OP_STIND_I2);
+        else
+            out_op(IL_OP_STIND_I4);
+    }
+}
+
+/* start function call and return function call context */
+void gfunc_start(GFuncContext *c, int func_call)
+{
+    c->func_call = func_call;
+}
+
+/* push function parameter which is in (vtop->t, vtop->c). Stack entry
+   is then popped. */
+void gfunc_param(GFuncContext *c)
+{
+    if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
+        error("structures passed as value not handled yet");
+    } else {
+        /* simply push on stack */
+        gv(RC_ST0);
+    }
+    vtop--;
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+   context. Stack entry is popped */
+void gfunc_call(GFuncContext *c)
+{
+    char buf[1024];
+
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        /* XXX: more info needed from tcc */
+        il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
+        fprintf(il_outfile, " call %s\n", buf);
+    } else {
+        /* indirect call */
+        gv(RC_INT);
+        il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
+        fprintf(il_outfile, " calli %s\n", buf);
+    }
+    vtop--;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(int t)
+{
+    int addr, u, func_call;
+    Sym *sym;
+    char buf[1024];
+
+    init_outfile();
+
+    /* XXX: pass function name to gfunc_prolog */
+    il_type_to_str(buf, sizeof(buf), t, funcname);
+    fprintf(il_outfile, ".method static %s il managed\n", buf);
+    fprintf(il_outfile, "{\n");
+    /* XXX: cannot do better now */
+    fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
+    fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
+    
+    if (!strcmp(funcname, "main"))
+        fprintf(il_outfile, " .entrypoint\n");
+        
+    sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+    func_call = sym->r;
+
+    addr = ARG_BASE;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->t;
+    if ((func_vt & VT_BTYPE) == VT_STRUCT) {
+        func_vc = addr;
+        addr++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        u = sym->t;
+        sym_push(sym->v & ~SYM_FIELD, u,
+                 VT_LOCAL | lvalue_type(sym->type.t), addr);
+        addr++;
+    }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    out_op(IL_OP_RET);
+    fprintf(il_outfile, "}\n\n");
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    return out_opj(IL_OP_BR, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    /* XXX: handle syms */
+    out_opi(IL_OP_BR, a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int v, *p, c;
+
+    v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+        c = vtop->c.i ^ inv;
+        switch(c) {
+        case TOK_EQ:
+            c = IL_OP_BEQ;
+            break;
+        case TOK_NE:
+            c = IL_OP_BNE_UN;
+            break;
+        case TOK_LT:
+            c = IL_OP_BLT;
+            break;
+        case TOK_LE:
+            c = IL_OP_BLE;
+            break;
+        case TOK_GT:
+            c = IL_OP_BGT;
+            break;
+        case TOK_GE:
+            c = IL_OP_BGE;
+            break;
+        case TOK_ULT:
+            c = IL_OP_BLT_UN;
+            break;
+        case TOK_ULE:
+            c = IL_OP_BLE_UN;
+            break;
+        case TOK_UGT:
+            c = IL_OP_BGT_UN;
+            break;
+        case TOK_UGE:
+            c = IL_OP_BGE_UN;
+            break;
+        }
+        t = out_opj(c, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            p = &vtop->c.i;
+            while (*p != 0)
+                p = (int *)*p;
+            *p = t;
+            t = vtop->c.i;
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    } else {
+        if (is_float(vtop->t)) {
+            vpushi(0);
+            gen_op(TOK_NE);
+        }
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
+            /* constant jmp optimization */
+            if ((vtop->c.i != 0) != inv) 
+                t = gjmp(t);
+        } else {
+            v = gv(RC_INT);
+            t = out_opj(IL_OP_BRTRUE - inv, t);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    gv2(RC_ST1, RC_ST0);
+    switch(op) {
+    case '+':
+        out_op(IL_OP_ADD);
+        goto std_op;
+    case '-':
+        out_op(IL_OP_SUB);
+        goto std_op;
+    case '&':
+        out_op(IL_OP_AND);
+        goto std_op;
+    case '^':
+        out_op(IL_OP_XOR);
+        goto std_op;
+    case '|':
+        out_op(IL_OP_OR);
+        goto std_op;
+    case '*':
+        out_op(IL_OP_MUL);
+        goto std_op;
+    case TOK_SHL:
+        out_op(IL_OP_SHL);
+        goto std_op;
+    case TOK_SHR:
+        out_op(IL_OP_SHR_UN);
+        goto std_op;
+    case TOK_SAR:
+        out_op(IL_OP_SHR);
+        goto std_op;
+    case '/':
+    case TOK_PDIV:
+        out_op(IL_OP_DIV);
+        goto std_op;
+    case TOK_UDIV:
+        out_op(IL_OP_DIV_UN);
+        goto std_op;
+    case '%':
+        out_op(IL_OP_REM);
+        goto std_op;
+    case TOK_UMOD:
+        out_op(IL_OP_REM_UN);
+    std_op:
+        vtop--;
+        vtop[0].r = REG_ST0;
+        break;
+    case TOK_EQ:
+    case TOK_NE:
+    case TOK_LT:
+    case TOK_LE:
+    case TOK_GT:
+    case TOK_GE:
+    case TOK_ULT:
+    case TOK_ULE:
+    case TOK_UGT:
+    case TOK_UGE:
+        vtop--;
+        vtop[0].r = VT_CMP;
+        vtop[0].c.i = op;
+        break;
+    }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranted to have the same floating point type */
+void gen_opf(int op)
+{
+    /* same as integer */
+    gen_opi(op);
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    gv(RC_ST0);
+    if (t == VT_FLOAT)
+        out_op(IL_OP_CONV_R4);
+    else
+        out_op(IL_OP_CONV_R8);
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+    gv(RC_ST0);
+    switch(t) {
+    case VT_INT | VT_UNSIGNED:
+        out_op(IL_OP_CONV_U4);
+        break;
+    case VT_LLONG:
+        out_op(IL_OP_CONV_I8);
+        break;
+    case VT_LLONG | VT_UNSIGNED:
+        out_op(IL_OP_CONV_U8);
+        break;
+    default:
+        out_op(IL_OP_CONV_I4);
+        break;
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    gv(RC_ST0);
+    if (t == VT_FLOAT) {
+        out_op(IL_OP_CONV_R4);
+    } else {
+        out_op(IL_OP_CONV_R8);
+    }
+}
+
+/* end of CIL code generator */
+/*************************************************************/
+
diff --git a/tinyc/il-opcodes.h b/tinyc/il-opcodes.h
new file mode 100755
index 000000000..d53ffb2c5
--- /dev/null
+++ b/tinyc/il-opcodes.h
@@ -0,0 +1,251 @@
+/*
+ *  CIL opcode definition
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+OP(NOP, "nop", 0x00)
+OP(BREAK, "break", 0x01)
+OP(LDARG_0, "ldarg.0", 0x02)
+OP(LDARG_1, "ldarg.1", 0x03)
+OP(LDARG_2, "ldarg.2", 0x04)
+OP(LDARG_3, "ldarg.3", 0x05)
+OP(LDLOC_0, "ldloc.0", 0x06)
+OP(LDLOC_1, "ldloc.1", 0x07)
+OP(LDLOC_2, "ldloc.2", 0x08)
+OP(LDLOC_3, "ldloc.3", 0x09)
+OP(STLOC_0, "stloc.0", 0x0a)
+OP(STLOC_1, "stloc.1", 0x0b)
+OP(STLOC_2, "stloc.2", 0x0c)
+OP(STLOC_3, "stloc.3", 0x0d)
+OP(LDARG_S, "ldarg.s", 0x0e)
+OP(LDARGA_S, "ldarga.s", 0x0f)
+OP(STARG_S, "starg.s", 0x10)
+OP(LDLOC_S, "ldloc.s", 0x11)
+OP(LDLOCA_S, "ldloca.s", 0x12)
+OP(STLOC_S, "stloc.s", 0x13)
+OP(LDNULL, "ldnull", 0x14)
+OP(LDC_I4_M1, "ldc.i4.m1", 0x15)
+OP(LDC_I4_0, "ldc.i4.0", 0x16)
+OP(LDC_I4_1, "ldc.i4.1", 0x17)
+OP(LDC_I4_2, "ldc.i4.2", 0x18)
+OP(LDC_I4_3, "ldc.i4.3", 0x19)
+OP(LDC_I4_4, "ldc.i4.4", 0x1a)
+OP(LDC_I4_5, "ldc.i4.5", 0x1b)
+OP(LDC_I4_6, "ldc.i4.6", 0x1c)
+OP(LDC_I4_7, "ldc.i4.7", 0x1d)
+OP(LDC_I4_8, "ldc.i4.8", 0x1e)
+OP(LDC_I4_S, "ldc.i4.s", 0x1f)
+OP(LDC_I4, "ldc.i4", 0x20)
+OP(LDC_I8, "ldc.i8", 0x21)
+OP(LDC_R4, "ldc.r4", 0x22)
+OP(LDC_R8, "ldc.r8", 0x23)
+OP(LDPTR, "ldptr", 0x24)
+OP(DUP, "dup", 0x25)
+OP(POP, "pop", 0x26)
+OP(JMP, "jmp", 0x27)
+OP(CALL, "call", 0x28)
+OP(CALLI, "calli", 0x29)
+OP(RET, "ret", 0x2a)
+OP(BR_S, "br.s", 0x2b)
+OP(BRFALSE_S, "brfalse.s", 0x2c)
+OP(BRTRUE_S, "brtrue.s", 0x2d)
+OP(BEQ_S, "beq.s", 0x2e)
+OP(BGE_S, "bge.s", 0x2f)
+OP(BGT_S, "bgt.s", 0x30)
+OP(BLE_S, "ble.s", 0x31)
+OP(BLT_S, "blt.s", 0x32)
+OP(BNE_UN_S, "bne.un.s", 0x33)
+OP(BGE_UN_S, "bge.un.s", 0x34)
+OP(BGT_UN_S, "bgt.un.s", 0x35)
+OP(BLE_UN_S, "ble.un.s", 0x36)
+OP(BLT_UN_S, "blt.un.s", 0x37)
+OP(BR, "br", 0x38)
+OP(BRFALSE, "brfalse", 0x39)
+OP(BRTRUE, "brtrue", 0x3a)
+OP(BEQ, "beq", 0x3b)
+OP(BGE, "bge", 0x3c)
+OP(BGT, "bgt", 0x3d)
+OP(BLE, "ble", 0x3e)
+OP(BLT, "blt", 0x3f)
+OP(BNE_UN, "bne.un", 0x40)
+OP(BGE_UN, "bge.un", 0x41)
+OP(BGT_UN, "bgt.un", 0x42)
+OP(BLE_UN, "ble.un", 0x43)
+OP(BLT_UN, "blt.un", 0x44)
+OP(SWITCH, "switch", 0x45)
+OP(LDIND_I1, "ldind.i1", 0x46)
+OP(LDIND_U1, "ldind.u1", 0x47)
+OP(LDIND_I2, "ldind.i2", 0x48)
+OP(LDIND_U2, "ldind.u2", 0x49)
+OP(LDIND_I4, "ldind.i4", 0x4a)
+OP(LDIND_U4, "ldind.u4", 0x4b)
+OP(LDIND_I8, "ldind.i8", 0x4c)
+OP(LDIND_I, "ldind.i", 0x4d)
+OP(LDIND_R4, "ldind.r4", 0x4e)
+OP(LDIND_R8, "ldind.r8", 0x4f)
+OP(LDIND_REF, "ldind.ref", 0x50)
+OP(STIND_REF, "stind.ref", 0x51)
+OP(STIND_I1, "stind.i1", 0x52)
+OP(STIND_I2, "stind.i2", 0x53)
+OP(STIND_I4, "stind.i4", 0x54)
+OP(STIND_I8, "stind.i8", 0x55)
+OP(STIND_R4, "stind.r4", 0x56)
+OP(STIND_R8, "stind.r8", 0x57)
+OP(ADD, "add", 0x58)
+OP(SUB, "sub", 0x59)
+OP(MUL, "mul", 0x5a)
+OP(DIV, "div", 0x5b)
+OP(DIV_UN, "div.un", 0x5c)
+OP(REM, "rem", 0x5d)
+OP(REM_UN, "rem.un", 0x5e)
+OP(AND, "and", 0x5f)
+OP(OR, "or", 0x60)
+OP(XOR, "xor", 0x61)
+OP(SHL, "shl", 0x62)
+OP(SHR, "shr", 0x63)
+OP(SHR_UN, "shr.un", 0x64)
+OP(NEG, "neg", 0x65)
+OP(NOT, "not", 0x66)
+OP(CONV_I1, "conv.i1", 0x67)
+OP(CONV_I2, "conv.i2", 0x68)
+OP(CONV_I4, "conv.i4", 0x69)
+OP(CONV_I8, "conv.i8", 0x6a)
+OP(CONV_R4, "conv.r4", 0x6b)
+OP(CONV_R8, "conv.r8", 0x6c)
+OP(CONV_U4, "conv.u4", 0x6d)
+OP(CONV_U8, "conv.u8", 0x6e)
+OP(CALLVIRT, "callvirt", 0x6f)
+OP(CPOBJ, "cpobj", 0x70)
+OP(LDOBJ, "ldobj", 0x71)
+OP(LDSTR, "ldstr", 0x72)
+OP(NEWOBJ, "newobj", 0x73)
+OP(CASTCLASS, "castclass", 0x74)
+OP(ISINST, "isinst", 0x75)
+OP(CONV_R_UN, "conv.r.un", 0x76)
+OP(ANN_DATA_S, "ann.data.s", 0x77)
+OP(UNBOX, "unbox", 0x79)
+OP(THROW, "throw", 0x7a)
+OP(LDFLD, "ldfld", 0x7b)
+OP(LDFLDA, "ldflda", 0x7c)
+OP(STFLD, "stfld", 0x7d)
+OP(LDSFLD, "ldsfld", 0x7e)
+OP(LDSFLDA, "ldsflda", 0x7f)
+OP(STSFLD, "stsfld", 0x80)
+OP(STOBJ, "stobj", 0x81)
+OP(CONV_OVF_I1_UN, "conv.ovf.i1.un", 0x82)
+OP(CONV_OVF_I2_UN, "conv.ovf.i2.un", 0x83)
+OP(CONV_OVF_I4_UN, "conv.ovf.i4.un", 0x84)
+OP(CONV_OVF_I8_UN, "conv.ovf.i8.un", 0x85)
+OP(CONV_OVF_U1_UN, "conv.ovf.u1.un", 0x86)
+OP(CONV_OVF_U2_UN, "conv.ovf.u2.un", 0x87)
+OP(CONV_OVF_U4_UN, "conv.ovf.u4.un", 0x88)
+OP(CONV_OVF_U8_UN, "conv.ovf.u8.un", 0x89)
+OP(CONV_OVF_I_UN, "conv.ovf.i.un", 0x8a)
+OP(CONV_OVF_U_UN, "conv.ovf.u.un", 0x8b)
+OP(BOX, "box", 0x8c)
+OP(NEWARR, "newarr", 0x8d)
+OP(LDLEN, "ldlen", 0x8e)
+OP(LDELEMA, "ldelema", 0x8f)
+OP(LDELEM_I1, "ldelem.i1", 0x90)
+OP(LDELEM_U1, "ldelem.u1", 0x91)
+OP(LDELEM_I2, "ldelem.i2", 0x92)
+OP(LDELEM_U2, "ldelem.u2", 0x93)
+OP(LDELEM_I4, "ldelem.i4", 0x94)
+OP(LDELEM_U4, "ldelem.u4", 0x95)
+OP(LDELEM_I8, "ldelem.i8", 0x96)
+OP(LDELEM_I, "ldelem.i", 0x97)
+OP(LDELEM_R4, "ldelem.r4", 0x98)
+OP(LDELEM_R8, "ldelem.r8", 0x99)
+OP(LDELEM_REF, "ldelem.ref", 0x9a)
+OP(STELEM_I, "stelem.i", 0x9b)
+OP(STELEM_I1, "stelem.i1", 0x9c)
+OP(STELEM_I2, "stelem.i2", 0x9d)
+OP(STELEM_I4, "stelem.i4", 0x9e)
+OP(STELEM_I8, "stelem.i8", 0x9f)
+OP(STELEM_R4, "stelem.r4", 0xa0)
+OP(STELEM_R8, "stelem.r8", 0xa1)
+OP(STELEM_REF, "stelem.ref", 0xa2)
+OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
+OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
+OP(CONV_OVF_I2, "conv.ovf.i2", 0xb5)
+OP(CONV_OVF_U2, "conv.ovf.u2", 0xb6)
+OP(CONV_OVF_I4, "conv.ovf.i4", 0xb7)
+OP(CONV_OVF_U4, "conv.ovf.u4", 0xb8)
+OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
+OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
+OP(REFANYVAL, "refanyval", 0xc2)
+OP(CKFINITE, "ckfinite", 0xc3)
+OP(MKREFANY, "mkrefany", 0xc6)
+OP(ANN_CALL, "ann.call", 0xc7)
+OP(ANN_CATCH, "ann.catch", 0xc8)
+OP(ANN_DEAD, "ann.dead", 0xc9)
+OP(ANN_HOISTED, "ann.hoisted", 0xca)
+OP(ANN_HOISTED_CALL, "ann.hoisted.call", 0xcb)
+OP(ANN_LAB, "ann.lab", 0xcc)
+OP(ANN_DEF, "ann.def", 0xcd)
+OP(ANN_REF_S, "ann.ref.s", 0xce)
+OP(ANN_PHI, "ann.phi", 0xcf)
+OP(LDTOKEN, "ldtoken", 0xd0)
+OP(CONV_U2, "conv.u2", 0xd1)
+OP(CONV_U1, "conv.u1", 0xd2)
+OP(CONV_I, "conv.i", 0xd3)
+OP(CONV_OVF_I, "conv.ovf.i", 0xd4)
+OP(CONV_OVF_U, "conv.ovf.u", 0xd5)
+OP(ADD_OVF, "add.ovf", 0xd6)
+OP(ADD_OVF_UN, "add.ovf.un", 0xd7)
+OP(MUL_OVF, "mul.ovf", 0xd8)
+OP(MUL_OVF_UN, "mul.ovf.un", 0xd9)
+OP(SUB_OVF, "sub.ovf", 0xda)
+OP(SUB_OVF_UN, "sub.ovf.un", 0xdb)
+OP(ENDFINALLY, "endfinally", 0xdc)
+OP(LEAVE, "leave", 0xdd)
+OP(LEAVE_S, "leave.s", 0xde)
+OP(STIND_I, "stind.i", 0xdf)
+OP(CONV_U, "conv.u", 0xe0)
+
+/* prefix instructions. we use an opcode >= 256 to ease coding */
+
+OP(ARGLIST, "arglist", 0x100)
+OP(CEQ, "ceq", 0x101)
+OP(CGT, "cgt", 0x102)
+OP(CGT_UN, "cgt.un", 0x103)
+OP(CLT, "clt", 0x104)
+OP(CLT_UN, "clt.un", 0x105)
+OP(LDFTN, "ldftn", 0x106)
+OP(LDVIRTFTN, "ldvirtftn", 0x107)
+OP(JMPI, "jmpi", 0x108)
+OP(LDARG, "ldarg", 0x109)
+OP(LDARGA, "ldarga", 0x10a)
+OP(STARG, "starg", 0x10b)
+OP(LDLOC, "ldloc", 0x10c)
+OP(LDLOCA, "ldloca", 0x10d)
+OP(STLOC, "stloc", 0x10e)
+OP(LOCALLOC, "localloc", 0x10f)
+OP(ENDFILTER, "endfilter", 0x111)
+OP(UNALIGNED, "unaligned", 0x112)
+OP(VOLATILE, "volatile", 0x113)
+OP(TAIL, "tail", 0x114)
+OP(INITOBJ, "initobj", 0x115)
+OP(ANN_LIVE, "ann.live", 0x116)
+OP(CPBLK, "cpblk", 0x117)
+OP(INITBLK, "initblk", 0x118)
+OP(ANN_REF, "ann.ref", 0x119)
+OP(RETHROW, "rethrow", 0x11a)
+OP(SIZEOF, "sizeof", 0x11c)
+OP(REFANYTYPE, "refanytype", 0x11d)
+OP(ANN_DATA, "ann.data", 0x122)
+OP(ANN_ARG, "ann.arg", 0x123)
diff --git a/tinyc/include/float.h b/tinyc/include/float.h
new file mode 100755
index 000000000..5f1c6f73c
--- /dev/null
+++ b/tinyc/include/float.h
@@ -0,0 +1,57 @@
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+#define FLT_RADIX 2
+
+/* IEEE float */
+#define FLT_MANT_DIG 24
+#define FLT_DIG 6
+#define FLT_ROUNDS 1
+#define FLT_EPSILON 1.19209290e-07F
+#define FLT_MIN_EXP (-125)
+#define FLT_MIN 1.17549435e-38F
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_EXP 128
+#define FLT_MAX 3.40282347e+38F
+#define FLT_MAX_10_EXP 38
+
+/* IEEE double */
+#define DBL_MANT_DIG 53
+#define DBL_DIG 15
+#define DBL_EPSILON 2.2204460492503131e-16
+#define DBL_MIN_EXP (-1021)
+#define DBL_MIN 2.2250738585072014e-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157e+308
+#define DBL_MAX_10_EXP 308
+
+/* horrible intel long double */
+#ifdef __i386__
+
+#define LDBL_MANT_DIG 64
+#define LDBL_DIG 18
+#define LDBL_EPSILON 1.08420217248550443401e-19L
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
+
+#else
+
+/* same as IEEE double */
+#define LDBL_MANT_DIG 53
+#define LDBL_DIG 15
+#define LDBL_EPSILON 2.2204460492503131e-16
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MIN 2.2250738585072014e-308
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_EXP 1024
+#define LDBL_MAX 1.7976931348623157e+308
+#define LDBL_MAX_10_EXP 308
+
+#endif
+
+#endif /* _FLOAT_H_ */
diff --git a/tinyc/include/stdarg.h b/tinyc/include/stdarg.h
new file mode 100755
index 000000000..86e556ca3
--- /dev/null
+++ b/tinyc/include/stdarg.h
@@ -0,0 +1,67 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __x86_64__
+#include <stdlib.h>
+
+/* GCC compatible definition of va_list. */
+struct __va_list_struct {
+    unsigned int gp_offset;
+    unsigned int fp_offset;
+    union {
+        unsigned int overflow_offset;
+        char *overflow_arg_area;
+    };
+    char *reg_save_area;
+};
+
+typedef struct __va_list_struct *va_list;
+
+/* we use __builtin_(malloc|free) to avoid #define malloc tcc_malloc */
+/* XXX: this lacks the support of aggregated types. */
+#define va_start(ap, last)                                              \
+    (ap = (va_list)__builtin_malloc(sizeof(struct __va_list_struct)),   \
+     *ap = *(struct __va_list_struct*)(                                 \
+         (char*)__builtin_frame_address(0) - 16),                       \
+     ap->overflow_arg_area = ((char *)__builtin_frame_address(0) +      \
+                              ap->overflow_offset),                     \
+     ap->reg_save_area = (char *)__builtin_frame_address(0) - 176 - 16  \
+        )
+#define va_arg(ap, type)                                        \
+    (*(type*)(__builtin_types_compatible_p(type, long double)   \
+              ? (ap->overflow_arg_area += 16,                   \
+                 ap->overflow_arg_area - 16)                    \
+              : __builtin_types_compatible_p(type, double)      \
+              ? (ap->fp_offset < 128 + 48                       \
+                 ? (ap->fp_offset += 16,                        \
+                    ap->reg_save_area + ap->fp_offset - 16)     \
+                 : (ap->overflow_arg_area += 8,                 \
+                    ap->overflow_arg_area - 8))                 \
+              : (ap->gp_offset < 48                             \
+                 ? (ap->gp_offset += 8,                         \
+                    ap->reg_save_area + ap->gp_offset - 8)      \
+                 : (ap->overflow_arg_area += 8,                 \
+                    ap->overflow_arg_area - 8))                 \
+        ))
+#define va_copy(dest, src)                                      \
+    ((dest) = (va_list)malloc(sizeof(struct __va_list_struct)), \
+     *(dest) = *(src))
+#define va_end(ap) __builtin_free(ap)
+
+#else
+
+typedef char *va_list;
+
+/* only correct for i386 */
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+
+#endif
+
+/* fix a buggy dependency on GCC in libio.h */
+typedef va_list __gnuc_va_list;
+#define _VA_LIST_DEFINED
+
+#endif /* _STDARG_H */
diff --git a/tinyc/include/stdbool.h b/tinyc/include/stdbool.h
new file mode 100755
index 000000000..6ed13a611
--- /dev/null
+++ b/tinyc/include/stdbool.h
@@ -0,0 +1,10 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+/* ISOC99 boolean */
+
+#define bool	_Bool
+#define true	1
+#define false	0
+
+#endif /* _STDBOOL_H */
diff --git a/tinyc/include/stddef.h b/tinyc/include/stddef.h
new file mode 100755
index 000000000..aef5b3923
--- /dev/null
+++ b/tinyc/include/stddef.h
@@ -0,0 +1,20 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#define NULL ((void *)0)
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+#endif
+
+void *alloca(size_t size);
+
+#endif
diff --git a/tinyc/include/tcclib.h b/tinyc/include/tcclib.h
new file mode 100755
index 000000000..42f8f3f57
--- /dev/null
+++ b/tinyc/include/tcclib.h
@@ -0,0 +1,78 @@
+/* Simple libc header for TCC 
+ * 
+ * Add any function you want from the libc there. This file is here
+ * only for your convenience so that you do not need to put the whole
+ * glibc include files on your floppy disk 
+ */
+#ifndef _TCCLIB_H
+#define _TCCLIB_H
+
+#include <stddef.h>
+#include <stdarg.h>
+
+/* stdlib.h */
+void *calloc(size_t nmemb, size_t size);
+void *malloc(size_t size);
+void free(void *ptr);
+void *realloc(void *ptr, size_t size);
+int atoi(const char *nptr);
+long int strtol(const char *nptr, char **endptr, int base);
+unsigned long int strtoul(const char *nptr, char **endptr, int base);
+void exit(int);
+
+/* stdio.h */
+typedef struct __FILE FILE;
+#define EOF (-1)
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+FILE *fopen(const char *path, const char *mode);
+FILE *fdopen(int fildes, const char *mode);
+FILE *freopen(const  char *path, const char *mode, FILE *stream);
+int fclose(FILE *stream);
+size_t  fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t  fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
+int fgetc(FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+int getc(FILE *stream);
+int getchar(void);
+char *gets(char *s);
+int ungetc(int c, FILE *stream);
+int fflush(FILE *stream);
+
+int printf(const char *format, ...);
+int fprintf(FILE *stream, const char *format, ...);
+int sprintf(char *str, const char *format, ...);
+int snprintf(char *str, size_t size, const  char  *format, ...);
+int asprintf(char **strp, const char *format, ...);
+int dprintf(int fd, const char *format, ...);
+int vprintf(const char *format, va_list ap);
+int vfprintf(FILE  *stream,  const  char *format, va_list ap);
+int vsprintf(char *str, const char *format, va_list ap);
+int vsnprintf(char *str, size_t size, const char  *format, va_list ap);
+int vasprintf(char  **strp,  const  char *format, va_list ap);
+int vdprintf(int fd, const char *format, va_list ap);
+
+void perror(const char *s);
+
+/* string.h */
+char *strcat(char *dest, const char *src);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strcpy(char *dest, const char *src);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+char *strdup(const char *s);
+
+/* dlfcn.h */
+#define RTLD_LAZY       0x001
+#define RTLD_NOW        0x002
+#define RTLD_GLOBAL     0x100
+
+void *dlopen(const char *filename, int flag);
+const char *dlerror(void);
+void *dlsym(void *handle, char *symbol);
+int dlclose(void *handle);
+
+#endif /* _TCCLIB_H */
diff --git a/tinyc/include/varargs.h b/tinyc/include/varargs.h
new file mode 100755
index 000000000..daee29e87
--- /dev/null
+++ b/tinyc/include/varargs.h
@@ -0,0 +1,11 @@
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#include <stdarg.h>
+
+#define va_dcl
+#define va_alist __va_alist
+#undef va_start
+#define va_start(ap) ap = __builtin_varargs_start
+
+#endif
diff --git a/tinyc/lib/alloca86-bt.S b/tinyc/lib/alloca86-bt.S
new file mode 100755
index 000000000..994da2042
--- /dev/null
+++ b/tinyc/lib/alloca86-bt.S
@@ -0,0 +1,45 @@
+/* ---------------------------------------------- */
+/* alloca86b.S */
+
+#include "../config.h"
+
+.globl __bound_alloca
+
+__bound_alloca:
+    pop     %edx
+    pop     %eax
+    mov     %eax, %ecx
+    add     $3,%eax
+    and     $-4,%eax
+    jz      p6
+
+#ifdef TCC_TARGET_PE
+p4:
+    cmp     $4096,%eax
+    jle     p5
+    sub     $4096,%esp
+    sub     $4096,%eax
+    test    %eax,(%esp)
+    jmp p4
+
+p5:
+#endif
+
+    sub     %eax,%esp
+    mov     %esp,%eax
+
+    push    %edx
+    push    %eax
+    push    %ecx
+    push    %eax
+    call   __bound_new_region
+    add    $8, %esp
+    pop     %eax
+    pop     %edx
+
+p6:
+    push    %edx
+    push    %edx
+    ret
+
+/* ---------------------------------------------- */
diff --git a/tinyc/lib/alloca86.S b/tinyc/lib/alloca86.S
new file mode 100755
index 000000000..fb208a0ba
--- /dev/null
+++ b/tinyc/lib/alloca86.S
@@ -0,0 +1,33 @@
+/* ---------------------------------------------- */
+/* alloca86.S */
+
+#include "../config.h"
+
+.globl alloca
+
+alloca:
+    pop     %edx
+    pop     %eax
+    add     $3,%eax
+    and     $-4,%eax
+    jz      p3
+
+#ifdef TCC_TARGET_PE
+p1:
+    cmp     $4096,%eax
+    jle     p2
+    sub     $4096,%esp
+    sub     $4096,%eax
+    test    %eax,(%esp)
+    jmp p1
+p2:
+#endif
+
+    sub     %eax,%esp
+    mov     %esp,%eax
+p3:
+    push    %edx
+    push    %edx
+    ret
+
+/* ---------------------------------------------- */
diff --git a/tinyc/lib/bcheck.c b/tinyc/lib/bcheck.c
new file mode 100755
index 000000000..0ec2a4b47
--- /dev/null
+++ b/tinyc/lib/bcheck.c
@@ -0,0 +1,868 @@
+/*
+ *  Tiny C Memory and bounds checker
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#if !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
+#include <malloc.h>
+#endif
+
+//#define BOUND_DEBUG
+
+/* define so that bound array is static (faster, but use memory if
+   bound checking not used) */
+//#define BOUND_STATIC
+
+/* use malloc hooks. Currently the code cannot be reliable if no hooks */
+#define CONFIG_TCC_MALLOC_HOOKS
+
+#define HAVE_MEMALIGN
+
+#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__dietlibc__) \
+    || defined(__UCLIBC__) || defined(__OpenBSD__)
+#warning Bound checking not fully supported in this environment.
+#undef CONFIG_TCC_MALLOC_HOOKS
+#undef HAVE_MEMALIGN
+#endif
+
+#define BOUND_T1_BITS 13
+#define BOUND_T2_BITS 11
+#define BOUND_T3_BITS (32 - BOUND_T1_BITS - BOUND_T2_BITS)
+
+#define BOUND_T1_SIZE (1 << BOUND_T1_BITS)
+#define BOUND_T2_SIZE (1 << BOUND_T2_BITS)
+#define BOUND_T3_SIZE (1 << BOUND_T3_BITS)
+#define BOUND_E_BITS  4
+
+#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
+#define BOUND_T23_SIZE (1 << BOUND_T23_BITS)
+
+
+/* this pointer is generated when bound check is incorrect */
+#define INVALID_POINTER ((void *)(-2))
+/* size of an empty region */
+#define EMPTY_SIZE        0xffffffff
+/* size of an invalid region */
+#define INVALID_SIZE      0
+
+typedef struct BoundEntry {
+    unsigned long start;
+    unsigned long size;
+    struct BoundEntry *next;
+    unsigned long is_invalid; /* true if pointers outside region are invalid */
+} BoundEntry;
+
+/* external interface */
+void __bound_init(void);
+void __bound_new_region(void *p, unsigned long size);
+int __bound_delete_region(void *p);
+
+#define FASTCALL __attribute__((regparm(3)))
+
+void *__bound_malloc(size_t size, const void *caller);
+void *__bound_memalign(size_t size, size_t align, const void *caller);
+void __bound_free(void *ptr, const void *caller);
+void *__bound_realloc(void *ptr, size_t size, const void *caller);
+static void *libc_malloc(size_t size);
+static void libc_free(void *ptr);
+static void install_malloc_hooks(void);
+static void restore_malloc_hooks(void);
+
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+static void *saved_malloc_hook;
+static void *saved_free_hook;
+static void *saved_realloc_hook;
+static void *saved_memalign_hook;
+#endif
+
+/* linker definitions */
+extern char _end;
+
+/* TCC definitions */
+extern char __bounds_start; /* start of static bounds table */
+/* error message, just for TCC */
+const char *__bound_error_msg;
+
+/* runtime error output */
+extern void rt_error(unsigned long pc, const char *fmt, ...);
+
+#ifdef BOUND_STATIC
+static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
+#else
+static BoundEntry **__bound_t1; /* page table */
+#endif
+static BoundEntry *__bound_empty_t2;   /* empty page, for unused pages */
+static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
+
+static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
+{
+    unsigned long addr, tmp;
+    BoundEntry *e;
+
+    e = e1;
+    while (e != NULL) {
+        addr = (unsigned long)p;
+        addr -= e->start;
+        if (addr <= e->size) {
+            /* put region at the head */
+            tmp = e1->start;
+            e1->start = e->start;
+            e->start = tmp;
+            tmp = e1->size;
+            e1->size = e->size;
+            e->size = tmp;
+            return e1;
+        }
+        e = e->next;
+    }
+    /* no entry found: return empty entry or invalid entry */
+    if (e1->is_invalid)
+        return __bound_invalid_t2;
+    else
+        return __bound_empty_t2;
+}
+
+/* print a bound error message */
+static void bound_error(const char *fmt, ...)
+{
+    __bound_error_msg = fmt;
+    *(int *)0 = 0; /* force a runtime error */
+}
+
+static void bound_alloc_error(void)
+{
+    bound_error("not enough memory for bound checking code");
+}
+
+/* currently, tcc cannot compile that because we use GNUC extensions */
+#if !defined(__TINYC__)
+
+/* return '(p + offset)' for pointer arithmetic (a pointer can reach
+   the end of a region in this case */
+void * FASTCALL __bound_ptr_add(void *p, int offset)
+{
+    unsigned long addr = (unsigned long)p;
+    BoundEntry *e;
+#if defined(BOUND_DEBUG)
+    printf("add: 0x%x %d\n", (int)p, offset);
+#endif
+
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+    e = (BoundEntry *)((char *)e + 
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+    addr -= e->start;
+    if (addr > e->size) {
+        e = __bound_find_region(e, p);
+        addr = (unsigned long)p - e->start;
+    }
+    addr += offset;
+    if (addr > e->size)
+        return INVALID_POINTER; /* return an invalid pointer */
+    return p + offset;
+}
+
+/* return '(p + offset)' for pointer indirection (the resulting must
+   be strictly inside the region */
+#define BOUND_PTR_INDIR(dsize)                                          \
+void * FASTCALL __bound_ptr_indir ## dsize (void *p, int offset)        \
+{                                                                       \
+    unsigned long addr = (unsigned long)p;                              \
+    BoundEntry *e;                                                      \
+                                                                        \
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];            \
+    e = (BoundEntry *)((char *)e +                                      \
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &      \
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));        \
+    addr -= e->start;                                                   \
+    if (addr > e->size) {                                               \
+        e = __bound_find_region(e, p);                                  \
+        addr = (unsigned long)p - e->start;                             \
+    }                                                                   \
+    addr += offset + dsize;                                             \
+    if (addr > e->size)                                                 \
+        return INVALID_POINTER; /* return an invalid pointer */         \
+    return p + offset;                                                  \
+}
+
+#ifdef __i386__
+/* return the frame pointer of the caller */
+#define GET_CALLER_FP(fp)\
+{\
+    unsigned long *fp1;\
+    __asm__ __volatile__ ("movl %%ebp,%0" :"=g" (fp1));\
+    fp = fp1[0];\
+}
+#else
+#error put code to extract the calling frame pointer
+#endif
+
+/* called when entering a function to add all the local regions */
+void FASTCALL __bound_local_new(void *p1) 
+{
+    unsigned long addr, size, fp, *p = p1;
+    GET_CALLER_FP(fp);
+    for(;;) {
+        addr = p[0];
+        if (addr == 0)
+            break;
+        addr += fp;
+        size = p[1];
+        p += 2;
+        __bound_new_region((void *)addr, size);
+    }
+}
+
+/* called when leaving a function to delete all the local regions */
+void FASTCALL __bound_local_delete(void *p1) 
+{
+    unsigned long addr, fp, *p = p1;
+    GET_CALLER_FP(fp);
+    for(;;) {
+        addr = p[0];
+        if (addr == 0)
+            break;
+        addr += fp;
+        p += 2;
+        __bound_delete_region((void *)addr);
+    }
+}
+
+#else
+
+void __bound_local_new(void *p) 
+{
+}
+void __bound_local_delete(void *p) 
+{
+}
+
+void *__bound_ptr_add(void *p, int offset)
+{
+    return p + offset;
+}
+
+#define BOUND_PTR_INDIR(dsize)                               \
+void *__bound_ptr_indir ## dsize (void *p, int offset)       \
+{                                                            \
+    return p + offset;                                       \
+}
+#endif
+
+BOUND_PTR_INDIR(1)
+BOUND_PTR_INDIR(2)
+BOUND_PTR_INDIR(4)
+BOUND_PTR_INDIR(8)
+BOUND_PTR_INDIR(12)
+BOUND_PTR_INDIR(16)
+
+static BoundEntry *__bound_new_page(void)
+{
+    BoundEntry *page;
+    int i;
+
+    page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
+    if (!page)
+        bound_alloc_error();
+    for(i=0;i<BOUND_T2_SIZE;i++) {
+        /* put empty entries */
+        page[i].start = 0;
+        page[i].size = EMPTY_SIZE;
+        page[i].next = NULL;
+        page[i].is_invalid = 0;
+    }
+    return page;
+}
+
+/* currently we use malloc(). Should use bound_new_page() */
+static BoundEntry *bound_new_entry(void)
+{
+    BoundEntry *e;
+    e = libc_malloc(sizeof(BoundEntry));
+    return e;
+}
+
+static void bound_free_entry(BoundEntry *e)
+{
+    libc_free(e);
+}
+
+static inline BoundEntry *get_page(int index)
+{
+    BoundEntry *page;
+    page = __bound_t1[index];
+    if (page == __bound_empty_t2 || page == __bound_invalid_t2) {
+        /* create a new page if necessary */
+        page = __bound_new_page();
+        __bound_t1[index] = page;
+    }
+    return page;
+}
+
+/* mark a region as being invalid (can only be used during init) */
+static void mark_invalid(unsigned long addr, unsigned long size)
+{
+    unsigned long start, end;
+    BoundEntry *page;
+    int t1_start, t1_end, i, j, t2_start, t2_end;
+
+    start = addr;
+    end = addr + size;
+
+    t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
+    if (end != 0)
+        t2_end = end >> BOUND_T3_BITS;
+    else
+        t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
+
+#if 0
+    printf("mark_invalid: start = %x %x\n", t2_start, t2_end);
+#endif
+    
+    /* first we handle full pages */
+    t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
+    t1_end = t2_end >> BOUND_T2_BITS;
+
+    i = t2_start & (BOUND_T2_SIZE - 1);
+    j = t2_end & (BOUND_T2_SIZE - 1);
+    
+    if (t1_start == t1_end) {
+        page = get_page(t2_start >> BOUND_T2_BITS);
+        for(; i < j; i++) {
+            page[i].size = INVALID_SIZE;
+            page[i].is_invalid = 1;
+        }
+    } else {
+        if (i > 0) {
+            page = get_page(t2_start >> BOUND_T2_BITS);
+            for(; i < BOUND_T2_SIZE; i++) {
+                page[i].size = INVALID_SIZE;
+                page[i].is_invalid = 1;
+            }
+        }
+        for(i = t1_start; i < t1_end; i++) {
+            __bound_t1[i] = __bound_invalid_t2;
+        }
+        if (j != 0) {
+            page = get_page(t1_end);
+            for(i = 0; i < j; i++) {
+                page[i].size = INVALID_SIZE;
+                page[i].is_invalid = 1;
+            }
+        }
+    }
+}
+
+void __bound_init(void)
+{
+    int i;
+    BoundEntry *page;
+    unsigned long start, size;
+    int *p;
+
+    /* save malloc hooks and install bound check hooks */
+    install_malloc_hooks();
+
+#ifndef BOUND_STATIC
+    __bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
+    if (!__bound_t1)
+        bound_alloc_error();
+#endif
+    __bound_empty_t2 = __bound_new_page();
+    for(i=0;i<BOUND_T1_SIZE;i++) {
+        __bound_t1[i] = __bound_empty_t2;
+    }
+
+    page = __bound_new_page();
+    for(i=0;i<BOUND_T2_SIZE;i++) {
+        /* put invalid entries */
+        page[i].start = 0;
+        page[i].size = INVALID_SIZE;
+        page[i].next = NULL;
+        page[i].is_invalid = 1;
+    }
+    __bound_invalid_t2 = page;
+
+    /* invalid pointer zone */
+    start = (unsigned long)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
+    size = BOUND_T23_SIZE;
+    mark_invalid(start, size);
+
+#if !defined(__TINYC__) && defined(CONFIG_TCC_MALLOC_HOOKS)
+    /* malloc zone is also marked invalid. can only use that with
+       hooks because all libs should use the same malloc. The solution
+       would be to build a new malloc for tcc. */
+    start = (unsigned long)&_end;
+    size = 128 * 0x100000;
+    mark_invalid(start, size);
+#endif
+
+    /* add all static bound check values */
+    p = (int *)&__bounds_start;
+    while (p[0] != 0) {
+        __bound_new_region((void *)p[0], p[1]);
+        p += 2;
+    }
+}
+
+static inline void add_region(BoundEntry *e, 
+                              unsigned long start, unsigned long size)
+{
+    BoundEntry *e1;
+    if (e->start == 0) {
+        /* no region : add it */
+        e->start = start;
+        e->size = size;
+    } else {
+        /* already regions in the list: add it at the head */
+        e1 = bound_new_entry();
+        e1->start = e->start;
+        e1->size = e->size;
+        e1->next = e->next;
+        e->start = start;
+        e->size = size;
+        e->next = e1;
+    }
+}
+
+/* create a new region. It should not already exist in the region list */
+void __bound_new_region(void *p, unsigned long size)
+{
+    unsigned long start, end;
+    BoundEntry *page, *e, *e2;
+    int t1_start, t1_end, i, t2_start, t2_end;
+
+    start = (unsigned long)p;
+    end = start + size;
+    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+
+    /* start */
+    page = get_page(t1_start);
+    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+#ifdef BOUND_DEBUG
+    printf("new %lx %lx %x %x %x %x\n", 
+           start, end, t1_start, t1_end, t2_start, t2_end);
+#endif
+
+    e = (BoundEntry *)((char *)page + t2_start);
+    add_region(e, start, size);
+
+    if (t1_end == t1_start) {
+        /* same ending page */
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        if (e2 > e) {
+            e++;
+            for(;e<e2;e++) {
+                e->start = start;
+                e->size = size;
+            }
+            add_region(e, start, size);
+        }
+    } else {
+        /* mark until end of page */
+        e2 = page + BOUND_T2_SIZE;
+        e++;
+        for(;e<e2;e++) {
+            e->start = start;
+            e->size = size;
+        }
+        /* mark intermediate pages, if any */
+        for(i=t1_start+1;i<t1_end;i++) {
+            page = get_page(i);
+            e2 = page + BOUND_T2_SIZE;
+            for(e=page;e<e2;e++) {
+                e->start = start;
+                e->size = size;
+            }
+        }
+        /* last page */
+        page = get_page(t1_end);
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        for(e=page;e<e2;e++) {
+            e->start = start;
+            e->size = size;
+        }
+        add_region(e, start, size);
+    }
+}
+
+/* delete a region */
+static inline void delete_region(BoundEntry *e, 
+                                 void *p, unsigned long empty_size)
+{
+    unsigned long addr;
+    BoundEntry *e1;
+
+    addr = (unsigned long)p;
+    addr -= e->start;
+    if (addr <= e->size) {
+        /* region found is first one */
+        e1 = e->next;
+        if (e1 == NULL) {
+            /* no more region: mark it empty */
+            e->start = 0;
+            e->size = empty_size;
+        } else {
+            /* copy next region in head */
+            e->start = e1->start;
+            e->size = e1->size;
+            e->next = e1->next;
+            bound_free_entry(e1);
+        }
+    } else {
+        /* find the matching region */
+        for(;;) {
+            e1 = e;
+            e = e->next;
+            /* region not found: do nothing */
+            if (e == NULL)
+                break;
+            addr = (unsigned long)p - e->start;
+            if (addr <= e->size) {
+                /* found: remove entry */
+                e1->next = e->next;
+                bound_free_entry(e);
+                break;
+            }
+        }
+    }
+}
+
+/* WARNING: 'p' must be the starting point of the region. */
+/* return non zero if error */
+int __bound_delete_region(void *p)
+{
+    unsigned long start, end, addr, size, empty_size;
+    BoundEntry *page, *e, *e2;
+    int t1_start, t1_end, t2_start, t2_end, i;
+
+    start = (unsigned long)p;
+    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+    
+    /* find region size */
+    page = __bound_t1[t1_start];
+    e = (BoundEntry *)((char *)page + t2_start);
+    addr = start - e->start;
+    if (addr > e->size)
+        e = __bound_find_region(e, p);
+    /* test if invalid region */
+    if (e->size == EMPTY_SIZE || (unsigned long)p != e->start) 
+        return -1;
+    /* compute the size we put in invalid regions */
+    if (e->is_invalid)
+        empty_size = INVALID_SIZE;
+    else
+        empty_size = EMPTY_SIZE;
+    size = e->size;
+    end = start + size;
+
+    /* now we can free each entry */
+    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+    delete_region(e, p, empty_size);
+    if (t1_end == t1_start) {
+        /* same ending page */
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        if (e2 > e) {
+            e++;
+            for(;e<e2;e++) {
+                e->start = 0;
+                e->size = empty_size;
+            }
+            delete_region(e, p, empty_size);
+        }
+    } else {
+        /* mark until end of page */
+        e2 = page + BOUND_T2_SIZE;
+        e++;
+        for(;e<e2;e++) {
+            e->start = 0;
+            e->size = empty_size;
+        }
+        /* mark intermediate pages, if any */
+        /* XXX: should free them */
+        for(i=t1_start+1;i<t1_end;i++) {
+            page = get_page(i);
+            e2 = page + BOUND_T2_SIZE;
+            for(e=page;e<e2;e++) {
+                e->start = 0;
+                e->size = empty_size;
+            }
+        }
+        /* last page */
+        page = get_page(t2_end);
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        for(e=page;e<e2;e++) {
+            e->start = 0;
+            e->size = empty_size;
+        }
+        delete_region(e, p, empty_size);
+    }
+    return 0;
+}
+
+/* return the size of the region starting at p, or EMPTY_SIZE if non
+   existant region. */
+static unsigned long get_region_size(void *p)
+{
+    unsigned long addr = (unsigned long)p;
+    BoundEntry *e;
+
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+    e = (BoundEntry *)((char *)e + 
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+    addr -= e->start;
+    if (addr > e->size)
+        e = __bound_find_region(e, p);
+    if (e->start != (unsigned long)p)
+        return EMPTY_SIZE;
+    return e->size;
+}
+
+/* patched memory functions */
+
+static void install_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+    saved_malloc_hook = __malloc_hook;
+    saved_free_hook = __free_hook;
+    saved_realloc_hook = __realloc_hook;
+    saved_memalign_hook = __memalign_hook;
+    __malloc_hook = __bound_malloc;
+    __free_hook = __bound_free;
+    __realloc_hook = __bound_realloc;
+    __memalign_hook = __bound_memalign;
+#endif
+}
+
+static void restore_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+    __malloc_hook = saved_malloc_hook;
+    __free_hook = saved_free_hook;
+    __realloc_hook = saved_realloc_hook;
+    __memalign_hook = saved_memalign_hook;
+#endif
+}
+
+static void *libc_malloc(size_t size)
+{
+    void *ptr;
+    restore_malloc_hooks();
+    ptr = malloc(size);
+    install_malloc_hooks();
+    return ptr;
+}
+
+static void libc_free(void *ptr)
+{
+    restore_malloc_hooks();
+    free(ptr);
+    install_malloc_hooks();
+}
+
+/* XXX: we should use a malloc which ensure that it is unlikely that
+   two malloc'ed data have the same address if 'free' are made in
+   between. */
+void *__bound_malloc(size_t size, const void *caller)
+{
+    void *ptr;
+    
+    /* we allocate one more byte to ensure the regions will be
+       separated by at least one byte. With the glibc malloc, it may
+       be in fact not necessary */
+    ptr = libc_malloc(size + 1);
+    
+    if (!ptr)
+        return NULL;
+    __bound_new_region(ptr, size);
+    return ptr;
+}
+
+void *__bound_memalign(size_t size, size_t align, const void *caller)
+{
+    void *ptr;
+
+    restore_malloc_hooks();
+
+#ifndef HAVE_MEMALIGN
+    if (align > 4) {
+        /* XXX: handle it ? */
+        ptr = NULL;
+    } else {
+        /* we suppose that malloc aligns to at least four bytes */
+        ptr = malloc(size + 1);
+    }
+#else
+    /* we allocate one more byte to ensure the regions will be
+       separated by at least one byte. With the glibc malloc, it may
+       be in fact not necessary */
+    ptr = memalign(size + 1, align);
+#endif
+    
+    install_malloc_hooks();
+    
+    if (!ptr)
+        return NULL;
+    __bound_new_region(ptr, size);
+    return ptr;
+}
+
+void __bound_free(void *ptr, const void *caller)
+{
+    if (ptr == NULL)
+        return;
+    if (__bound_delete_region(ptr) != 0)
+        bound_error("freeing invalid region");
+
+    libc_free(ptr);
+}
+
+void *__bound_realloc(void *ptr, size_t size, const void *caller)
+{
+    void *ptr1;
+    int old_size;
+
+    if (size == 0) {
+        __bound_free(ptr, caller);
+        return NULL;
+    } else {
+        ptr1 = __bound_malloc(size, caller);
+        if (ptr == NULL || ptr1 == NULL)
+            return ptr1;
+        old_size = get_region_size(ptr);
+        if (old_size == EMPTY_SIZE)
+            bound_error("realloc'ing invalid pointer");
+        memcpy(ptr1, ptr, old_size);
+        __bound_free(ptr, caller);
+        return ptr1;
+    }
+}
+
+#ifndef CONFIG_TCC_MALLOC_HOOKS
+void *__bound_calloc(size_t nmemb, size_t size)
+{
+    void *ptr;
+    size = size * nmemb;
+    ptr = __bound_malloc(size, NULL);
+    if (!ptr)
+        return NULL;
+    memset(ptr, 0, size);
+    return ptr;
+}
+#endif
+
+#if 0
+static void bound_dump(void)
+{
+    BoundEntry *page, *e;
+    int i, j;
+
+    printf("region dump:\n");
+    for(i=0;i<BOUND_T1_SIZE;i++) {
+        page = __bound_t1[i];
+        for(j=0;j<BOUND_T2_SIZE;j++) {
+            e = page + j;
+            /* do not print invalid or empty entries */
+            if (e->size != EMPTY_SIZE && e->start != 0) {
+                printf("%08x:", 
+                       (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + 
+                       (j << BOUND_T3_BITS));
+                do {
+                    printf(" %08lx:%08lx", e->start, e->start + e->size);
+                    e = e->next;
+                } while (e != NULL);
+                printf("\n");
+            }
+        }
+    }
+}
+#endif
+
+/* some useful checked functions */
+
+/* check that (p ... p + size - 1) lies inside 'p' region, if any */
+static void __bound_check(const void *p, size_t size)
+{
+    if (size == 0)
+        return;
+    p = __bound_ptr_add((void *)p, size);
+    if (p == INVALID_POINTER)
+        bound_error("invalid pointer");
+}
+
+void *__bound_memcpy(void *dst, const void *src, size_t size)
+{
+    __bound_check(dst, size);
+    __bound_check(src, size);
+    /* check also region overlap */
+    if (src >= dst && src < dst + size)
+        bound_error("overlapping regions in memcpy()");
+    return memcpy(dst, src, size);
+}
+
+void *__bound_memmove(void *dst, const void *src, size_t size)
+{
+    __bound_check(dst, size);
+    __bound_check(src, size);
+    return memmove(dst, src, size);
+}
+
+void *__bound_memset(void *dst, int c, size_t size)
+{
+    __bound_check(dst, size);
+    return memset(dst, c, size);
+}
+
+/* XXX: could be optimized */
+int __bound_strlen(const char *s)
+{
+    const char *p;
+    int len;
+
+    len = 0;
+    for(;;) {
+        p = __bound_ptr_indir1((char *)s, len);
+        if (p == INVALID_POINTER)
+            bound_error("bad pointer in strlen()");
+        if (*p == '\0')
+            break;
+        len++;
+    }
+    return len;
+}
+
+char *__bound_strcpy(char *dst, const char *src)
+{
+    int len;
+    len = __bound_strlen(src);
+    return __bound_memcpy(dst, src, len + 1);
+}
+
diff --git a/tinyc/lib/libtcc1.c b/tinyc/lib/libtcc1.c
new file mode 100755
index 000000000..b079477e4
--- /dev/null
+++ b/tinyc/lib/libtcc1.c
@@ -0,0 +1,607 @@
+/* TCC runtime library. 
+   Parts of this code are (c) 2002 Fabrice Bellard 
+
+   Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  
+*/
+
+#define W_TYPE_SIZE   32
+#define BITS_PER_UNIT 8
+
+typedef int Wtype;
+typedef unsigned int UWtype;
+typedef unsigned int USItype;
+typedef long long DWtype;
+typedef unsigned long long UDWtype;
+
+struct DWstruct {
+    Wtype low, high;
+};
+
+typedef union
+{
+  struct DWstruct s;
+  DWtype ll;
+} DWunion;
+
+typedef long double XFtype;
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
+
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS		126
+#define SIGNBIT		0x80000000
+#define HIDDEN		(1 << 23)
+#define SIGN(fp)	((fp) & SIGNBIT)
+#define EXP(fp)		(((fp) >> 23) & 0xFF)
+#define MANT(fp)	(((fp) & 0x7FFFFF) | HIDDEN)
+#define PACK(s,e,m)	((s) | ((e) << 23) | (m))
+
+/* the following deal with IEEE double-precision numbers */
+#define EXCESSD		1022
+#define HIDDEND		(1 << 20)
+#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
+#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
+#define MANTD(fp)	(((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
+				(fp.l.lower >> 22))
+#define HIDDEND_LL	((long long)1 << 52)
+#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m)	(((long long)((s)+((e)<<20))<<32)|(m))
+
+/* the following deal with x86 long double-precision numbers */
+#define EXCESSLD	16382
+#define EXPLD(fp)	(fp.l.upper & 0x7fff)
+#define SIGNLD(fp)	((fp.l.upper) & 0x8000)
+
+/* only for x86 */
+union ldouble_long {
+    long double ld;
+    struct {
+        unsigned long long lower;
+        unsigned short upper;
+    } l;
+};
+
+union double_long {
+    double d;
+#if 1
+    struct {
+        unsigned int lower;
+        int upper;
+    } l;
+#else
+    struct {
+        int upper;
+        unsigned int lower;
+    } l;
+#endif
+    long long ll;
+};
+
+union float_long {
+    float f;
+    long l;
+};
+
+/* XXX: we don't support several builtin supports for now */
+#ifndef __x86_64__
+
+/* XXX: use gcc/tcc intrinsic ? */
+#if defined(__i386__)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subl %5,%1\n\tsbbl %3,%0"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mull %3"							\
+	   : "=a" ((USItype) (w0)),					\
+	     "=d" ((USItype) (w1))					\
+	   : "%0" ((USItype) (u)),					\
+	     "rm" ((USItype) (v)))
+#define udiv_qrnnd(q, r, n1, n0, dv) \
+  __asm__ ("divl %4"							\
+	   : "=a" ((USItype) (q)),					\
+	     "=d" ((USItype) (r))					\
+	   : "0" ((USItype) (n0)),					\
+	     "1" ((USItype) (n1)),					\
+	     "rm" ((USItype) (dv)))
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __cbtmp;							\
+    __asm__ ("bsrl %1,%0"						\
+	     : "=r" (__cbtmp) : "rm" ((USItype) (x)));			\
+    (count) = __cbtmp ^ 31;						\
+  } while (0)
+#else
+#error unsupported CPU type
+#endif
+
+/* most of this code is taken from libgcc2.c from gcc */
+
+static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+  DWunion ww;
+  DWunion nn, dd;
+  DWunion rr;
+  UWtype d0, d1, n0, n1, n2;
+  UWtype q0, q1;
+  UWtype b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      UWtype m1, m0;
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+#define __negdi2(a) (-(a))
+
+long long __divdi3(long long u, long long v)
+{
+    int c = 0;
+    DWunion uu, vv;
+    DWtype w;
+    
+    uu.ll = u;
+    vv.ll = v;
+    
+    if (uu.s.high < 0) {
+        c = ~c;
+        uu.ll = __negdi2 (uu.ll);
+    }
+    if (vv.s.high < 0) {
+        c = ~c;
+        vv.ll = __negdi2 (vv.ll);
+    }
+    w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+    if (c)
+        w = __negdi2 (w);
+    return w;
+}
+
+long long __moddi3(long long u, long long v)
+{
+    int c = 0;
+    DWunion uu, vv;
+    DWtype w;
+    
+    uu.ll = u;
+    vv.ll = v;
+    
+    if (uu.s.high < 0) {
+        c = ~c;
+        uu.ll = __negdi2 (uu.ll);
+    }
+    if (vv.s.high < 0)
+        vv.ll = __negdi2 (vv.ll);
+    
+    __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
+    if (c)
+        w = __negdi2 (w);
+    return w;
+}
+
+unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
+{
+    return __udivmoddi4 (u, v, (UDWtype *) 0);
+}
+
+unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
+{
+    UDWtype w;
+    
+    __udivmoddi4 (u, v, &w);
+    return w;
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashrdi3(long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.low = u.s.high >> (b - 32);
+        u.s.high = u.s.high >> 31;
+    } else if (b != 0) {
+        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+        u.s.high = u.s.high >> b;
+    }
+    return u.ll;
+#else
+    return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+unsigned long long __lshrdi3(unsigned long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.low = (unsigned)u.s.high >> (b - 32);
+        u.s.high = 0;
+    } else if (b != 0) {
+        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+        u.s.high = (unsigned)u.s.high >> b;
+    }
+    return u.ll;
+#else
+    return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashldi3(long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.high = (unsigned)u.s.low << (b - 32);
+        u.s.low = 0;
+    } else if (b != 0) {
+        u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
+        u.s.low = (unsigned)u.s.low << b;
+    }
+    return u.ll;
+#else
+    return a << b;
+#endif
+}
+
+#if defined(__i386__)
+/* FPU control word for rounding to nearest mode */
+unsigned short __tcc_fpu_control = 0x137f;
+/* FPU control word for round to zero mode for int conversion */
+unsigned short __tcc_int_fpu_control = 0x137f | 0x0c00;
+#endif
+
+#endif /* !__x86_64__ */
+
+/* XXX: fix tcc's code generator to do this instead */
+float __floatundisf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (float)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (float)r;
+    }
+}
+
+double __floatundidf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (double)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (double)r;
+    }
+}
+
+long double __floatundixf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (long double)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (long double)r;
+    }
+}
+
+unsigned long long __fixunssfdi (float a1)
+{
+    register union float_long fl1;
+    register int exp;
+    register unsigned long l;
+
+    fl1.f = a1;
+
+    if (fl1.l == 0)
+	return (0);
+
+    exp = EXP (fl1.l) - EXCESS - 24;
+
+    l = MANT(fl1.l);
+    if (exp >= 41)
+	return (unsigned long long)-1;
+    else if (exp >= 0)
+        return (unsigned long long)l << exp;
+    else if (exp >= -23)
+        return l >> -exp;
+    else
+        return 0;
+}
+
+unsigned long long __fixunsdfdi (double a1)
+{
+    register union double_long dl1;
+    register int exp;
+    register unsigned long long l;
+
+    dl1.d = a1;
+
+    if (dl1.ll == 0)
+	return (0);
+
+    exp = EXPD (dl1) - EXCESSD - 53;
+
+    l = MANTD_LL(dl1);
+
+    if (exp >= 12)
+	return (unsigned long long)-1;
+    else if (exp >= 0)
+        return l << exp;
+    else if (exp >= -52)
+        return l >> -exp;
+    else
+        return 0;
+}
+
+unsigned long long __fixunsxfdi (long double a1)
+{
+    register union ldouble_long dl1;
+    register int exp;
+    register unsigned long long l;
+
+    dl1.ld = a1;
+
+    if (dl1.l.lower == 0 && dl1.l.upper == 0)
+	return (0);
+
+    exp = EXPLD (dl1) - EXCESSLD - 64;
+
+    l = dl1.l.lower;
+
+    if (exp > 0)
+	return (unsigned long long)-1;
+    else if (exp >= -63) 
+        return l >> -exp;
+    else
+        return 0;
+}
+
diff --git a/tinyc/libtcc.c b/tinyc/libtcc.c
new file mode 100755
index 000000000..ade77c0dc
--- /dev/null
+++ b/tinyc/libtcc.c
@@ -0,0 +1,2259 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* 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
+/* bound check related sections */
+static Section *bounds_section; /* contains global data bound description */
+static Section *lbounds_section; /* contains local data bound description */
+/* 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;
+
+/* use Tiny C extensions */
+static int tcc_ext = 1;
+
+/* max number of callers shown if error */
+#ifdef CONFIG_TCC_BACKTRACE
+int num_callers = 6;
+const char **rt_bound_error_msg;
+#endif
+
+/* XXX: get rid of this ASAP */
+static 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, unsigned long 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 */
+void *resolve_sym(TCCState *s1, const char *sym, int type);
+int pe_load_def_file(struct TCCState *s1, int fd);
+int pe_test_res_file(void *v, int size);
+int pe_load_res_file(struct TCCState *s1, int fd);
+void pe_add_runtime(struct TCCState *s1);
+void pe_guess_outfile(char *objfilename, int output_type);
+int pe_output_file(struct TCCState *s1, const char *filename);
+
+/* 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);
+#endif
+
+static void asm_instr(void);
+static void asm_global_instr(void);
+
+/********************************************************/
+/* global variables */
+
+#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
+
+#ifdef CONFIG_TCC_STATIC
+
+#define RTLD_LAZY       0x001
+#define RTLD_NOW        0x002
+#define RTLD_GLOBAL     0x100
+#define RTLD_DEFAULT    NULL
+
+/* dummy function for profiling */
+void *dlopen(const char *filename, int flag)
+{
+    return NULL;
+}
+
+void dlclose(void *p)
+{
+}
+
+const char *dlerror(void)
+{
+    return "error";
+}
+
+typedef struct TCCSyms {
+    char *str;
+    void *ptr;
+} TCCSyms;
+
+#define TCCSYM(a) { #a, &a, },
+
+/* add the symbol you want here if no dynamic linking is done */
+static TCCSyms tcc_syms[] = {
+#if !defined(CONFIG_TCCBOOT)
+    TCCSYM(printf)
+    TCCSYM(fprintf)
+    TCCSYM(fopen)
+    TCCSYM(fclose)
+#endif
+    { NULL, NULL },
+};
+
+void *resolve_sym(TCCState *s1, const char *symbol, int type)
+{
+    TCCSyms *p;
+    p = tcc_syms;
+    while (p->str != NULL) {
+        if (!strcmp(p->str, symbol))
+            return p->ptr;
+        p++;
+    }
+    return NULL;
+}
+
+#elif !defined(_WIN32)
+
+#include <dlfcn.h>
+
+void *resolve_sym(TCCState *s1, const char *sym, int type)
+{
+    return dlsym(RTLD_DEFAULT, sym);
+}
+
+#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)
+{
+    char *q, *q_end;
+    int c;
+
+    if (buf_size > 0) {
+        q = buf;
+        q_end = buf + buf_size - 1;
+        while (q < q_end) {
+            c = *s++;
+            if (c == '\0')
+                break;
+            *q++ = c;
+        }
+        *q = '\0';
+    }
+    return buf;
+}
+
+/* strcat and truncate. */
+char *pstrcat(char *buf, int buf_size, const char *s)
+{
+    int len;
+    len = strlen(buf);
+    if (len < buf_size) 
+        pstrcpy(buf + len, buf_size - len, s);
+    return buf;
+}
+
+/* extract the basename of a file */
+char *tcc_basename(const char *name)
+{
+    char *p = strchr(name, 0);
+    while (p > name && !IS_PATHSEP(p[-1]))
+        --p;
+    return p;
+}
+
+char *tcc_fileextension (const char *name)
+{
+    char *b = tcc_basename(name);
+    char *e = strrchr(b, '.');
+    return e ? e : strchr(b, 0);
+}
+
+#ifdef _WIN32
+char *normalize_slashes(char *path)
+{
+    char *p;
+    for (p = path; *p; ++p)
+        if (*p == '\\')
+            *p = '/';
+    return path;
+}
+
+void tcc_set_lib_path_w32(TCCState *s)
+{
+    /* on win32, we suppose the lib and includes are at the location
+       of 'tcc.exe' */
+    char path[1024], *p;
+    GetModuleFileNameA(NULL, path, sizeof path);
+    p = tcc_basename(normalize_slashes(strlwr(path)));
+    if (p - 5 > path && 0 == strncmp(p - 5, "/bin/", 5))
+        p -= 5;
+    else if (p > path)
+        p--;
+    *p = 0;
+    tcc_set_lib_path(s, path);
+}
+#endif
+
+void set_pages_executable(void *ptr, unsigned long length)
+{
+#ifdef _WIN32
+    unsigned long old_protect;
+    VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
+#else
+    unsigned long start, end;
+    start = (unsigned long)ptr & ~(PAGESIZE - 1);
+    end = (unsigned long)ptr + length;
+    end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
+    mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
+#endif            
+}
+
+/* memory management */
+#ifdef MEM_DEBUG
+int mem_cur_size;
+int mem_max_size;
+unsigned malloc_usable_size(void*);
+#endif
+
+void tcc_free(void *ptr)
+{
+#ifdef MEM_DEBUG
+    mem_cur_size -= malloc_usable_size(ptr);
+#endif
+    free(ptr);
+}
+
+void *tcc_malloc(unsigned long size)
+{
+    void *ptr;
+    ptr = malloc(size);
+    if (!ptr && size)
+        error("memory full");
+#ifdef MEM_DEBUG
+    mem_cur_size += malloc_usable_size(ptr);
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+#endif
+    return ptr;
+}
+
+void *tcc_mallocz(unsigned long size)
+{
+    void *ptr;
+    ptr = tcc_malloc(size);
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+void *tcc_realloc(void *ptr, unsigned long size)
+{
+    void *ptr1;
+#ifdef MEM_DEBUG
+    mem_cur_size -= malloc_usable_size(ptr);
+#endif
+    ptr1 = realloc(ptr, size);
+#ifdef MEM_DEBUG
+    /* NOTE: count not correct if alloc error, but not critical */
+    mem_cur_size += malloc_usable_size(ptr1);
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+#endif
+    return ptr1;
+}
+
+char *tcc_strdup(const char *str)
+{
+    char *ptr;
+    ptr = tcc_malloc(strlen(str) + 1);
+    strcpy(ptr, str);
+    return ptr;
+}
+
+#define free(p) use_tcc_free(p)
+#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)
+{
+    int nb, nb_alloc;
+    void **pp;
+    
+    nb = *nb_ptr;
+    pp = *ptab;
+    /* every power of two we double array size */
+    if ((nb & (nb - 1)) == 0) {
+        if (!nb)
+            nb_alloc = 1;
+        else
+            nb_alloc = nb * 2;
+        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
+        if (!pp)
+            error("memory full");
+        *ptab = pp;
+    }
+    pp[nb++] = data;
+    *nb_ptr = nb;
+}
+
+void dynarray_reset(void *pp, int *n)
+{
+    void **p;
+    for (p = *(void***)pp; *n; ++p, --*n)
+        if (*p)
+            tcc_free(*p);
+    tcc_free(*(void**)pp);
+    *(void**)pp = NULL;
+}
+
+/* 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;
+}
+
+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)
+{
+    Section *sec;
+
+    sec = tcc_mallocz(sizeof(Section) + strlen(name));
+    strcpy(sec->name, name);
+    sec->sh_type = sh_type;
+    sec->sh_flags = sh_flags;
+    switch(sh_type) {
+    case SHT_HASH:
+    case SHT_REL:
+    case SHT_RELA:
+    case SHT_DYNSYM:
+    case SHT_SYMTAB:
+    case SHT_DYNAMIC:
+        sec->sh_addralign = 4;
+        break;
+    case SHT_STRTAB:
+        sec->sh_addralign = 1;
+        break;
+    default:
+        sec->sh_addralign = 32; /* default conservative alignment */
+        break;
+    }
+
+    if (sh_flags & SHF_PRIVATE) {
+        dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
+    } else {
+        sec->sh_num = s1->nb_sections;
+        dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
+    }
+
+    return sec;
+}
+
+static void free_section(Section *s)
+{
+    tcc_free(s->data);
+}
+
+/* realloc section and set its content to zero */
+static void section_realloc(Section *sec, unsigned long new_size)
+{
+    unsigned long size;
+    unsigned char *data;
+    
+    size = sec->data_allocated;
+    if (size == 0)
+        size = 1;
+    while (size < new_size)
+        size = size * 2;
+    data = tcc_realloc(sec->data, size);
+    if (!data)
+        error("memory full");
+    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
+    sec->data = data;
+    sec->data_allocated = size;
+}
+
+/* reserve at least 'size' bytes in section 'sec' from
+   sec->data_offset. */
+static void *section_ptr_add(Section *sec, unsigned long size)
+{
+    unsigned long offset, offset1;
+
+    offset = sec->data_offset;
+    offset1 = offset + size;
+    if (offset1 > sec->data_allocated)
+        section_realloc(sec, offset1);
+    sec->data_offset = offset1;
+    return sec->data + offset;
+}
+
+/* return a reference to a section, and create it if it does not
+   exists */
+Section *find_section(TCCState *s1, const char *name)
+{
+    Section *sec;
+    int i;
+    for(i = 1; i < s1->nb_sections; i++) {
+        sec = s1->sections[i];
+        if (!strcmp(name, sec->name)) 
+            return sec;
+    }
+    /* sections are created as PROGBITS */
+    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
+}
+
+/* update sym->c so that it points to an external symbol in section
+   'section' with value 'value' */
+static void put_extern_sym2(Sym *sym, Section *section, 
+                            unsigned long value, unsigned long size,
+                            int can_add_underscore)
+{
+    int sym_type, sym_bind, sh_num, info, other, attr;
+    ElfW(Sym) *esym;
+    const char *name;
+    char buf1[256];
+
+    if (section == NULL)
+        sh_num = SHN_UNDEF;
+    else if (section == SECTION_ABS) 
+        sh_num = SHN_ABS;
+    else
+        sh_num = section->sh_num;
+
+    other = attr = 0;
+
+    if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
+        sym_type = STT_FUNC;
+#ifdef TCC_TARGET_PE
+        if (sym->type.ref)
+            attr = sym->type.ref->r;
+        if (FUNC_EXPORT(attr))
+            other |= 1;
+        if (FUNC_CALL(attr) == FUNC_STDCALL)
+            other |= 2;
+#endif
+    } else {
+        sym_type = STT_OBJECT;
+    }
+
+    if (sym->type.t & VT_STATIC)
+        sym_bind = STB_LOCAL;
+    else
+        sym_bind = STB_GLOBAL;
+
+    if (!sym->c) {
+        name = get_tok_str(sym->v, NULL);
+#ifdef CONFIG_TCC_BCHECK
+        if (tcc_state->do_bounds_check) {
+            char buf[32];
+
+            /* XXX: avoid doing that for statics ? */
+            /* if bound checking is activated, we change some function
+               names by adding the "__bound" prefix */
+            switch(sym->v) {
+#if 0
+            /* XXX: we rely only on malloc hooks */
+            case TOK_malloc: 
+            case TOK_free: 
+            case TOK_realloc: 
+            case TOK_memalign: 
+            case TOK_calloc: 
+#endif
+            case TOK_memcpy: 
+            case TOK_memmove:
+            case TOK_memset:
+            case TOK_strlen:
+            case TOK_strcpy:
+            case TOK_alloca:
+                strcpy(buf, "__bound_");
+                strcat(buf, name);
+                name = buf;
+                break;
+            }
+        }
+#endif
+
+#ifdef TCC_TARGET_PE
+        if ((other & 2) && can_add_underscore) {
+            sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr));
+            name = buf1;
+        } else
+#endif
+        if (tcc_state->leading_underscore && can_add_underscore) {
+            buf1[0] = '_';
+            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
+            name = buf1;
+        }
+        info = ELFW(ST_INFO)(sym_bind, sym_type);
+        sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
+    } else {
+        esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
+        esym->st_value = value;
+        esym->st_size = size;
+        esym->st_shndx = sh_num;
+        esym->st_other |= other;
+    }
+}
+
+static 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)
+{
+    if (!sym->c) 
+        put_extern_sym(sym, NULL, 0, 0);
+    /* now we can add ELF relocation info */
+    put_elf_reloc(symtab_section, s, offset, type, sym->c);
+}
+
+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;
+}
+
+static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
+{
+    int len;
+    len = strlen(buf);
+    vsnprintf(buf + len, buf_size - len, fmt, ap);
+}
+
+static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    strcat_vprintf(buf, buf_size, fmt, ap);
+    va_end(ap);
+}
+
+void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
+{
+    char buf[2048];
+    BufferedFile **f;
+    
+    buf[0] = '\0';
+    if (file) {
+        for(f = s1->include_stack; f < s1->include_stack_ptr; f++)
+            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n", 
+                          (*f)->filename, (*f)->line_num);
+        if (file->line_num > 0) {
+            strcat_printf(buf, sizeof(buf), 
+                          "%s:%d: ", file->filename, file->line_num);
+        } else {
+            strcat_printf(buf, sizeof(buf),
+                          "%s: ", file->filename);
+        }
+    } else {
+        strcat_printf(buf, sizeof(buf),
+                      "tcc: ");
+    }
+    if (is_warning)
+        strcat_printf(buf, sizeof(buf), "warning: ");
+    strcat_vprintf(buf, sizeof(buf), fmt, ap);
+
+    if (!s1->error_func) {
+        /* default case: stderr */
+        fprintf(stderr, "%s\n", buf);
+    } else {
+        s1->error_func(s1->error_opaque, buf);
+    }
+    if (!is_warning || s1->warn_error)
+        s1->nb_errors++;
+}
+
+void tcc_set_error_func(TCCState *s, void *error_opaque,
+                        void (*error_func)(void *opaque, const char *msg))
+{
+    s->error_opaque = error_opaque;
+    s->error_func = error_func;
+}
+
+/* error without aborting current compilation */
+void error_noabort(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    va_start(ap, fmt);
+    error1(s1, 0, fmt, ap);
+    va_end(ap);
+}
+
+void error(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    va_start(ap, fmt);
+    error1(s1, 0, fmt, ap);
+    va_end(ap);
+    /* better than nothing: in some cases, we accept to handle errors */
+    if (s1->error_set_jmp_enabled) {
+        longjmp(s1->error_jmp_buf, 1);
+    } else {
+        /* XXX: eliminate this someday */
+        exit(1);
+    }
+}
+
+void expect(const char *msg)
+{
+    error("%s expected", msg);
+}
+
+void warning(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    if (s1->warn_none)
+        return;
+
+    va_start(ap, fmt);
+    error1(s1, 1, fmt, ap);
+    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->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)
+{
+    int fd;
+    BufferedFile *bf;
+
+    if (strcmp(filename, "-") == 0)
+        fd = 0, filename = "stdin";
+    else
+        fd = open(filename, O_RDONLY | O_BINARY);
+    if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
+        printf("%s %*s%s\n", fd < 0 ? "nf":"->",
+               (s1->include_stack_ptr - s1->include_stack), "", filename);
+    if (fd < 0)
+        return NULL;
+    bf = tcc_malloc(sizeof(BufferedFile));
+    bf->fd = fd;
+    bf->buf_ptr = bf->buffer;
+    bf->buf_end = bf->buffer;
+    bf->buffer[0] = CH_EOB; /* put eob symbol */
+    pstrcpy(bf->filename, sizeof(bf->filename), filename);
+#ifdef _WIN32
+    normalize_slashes(bf->filename);
+#endif
+    bf->line_num = 1;
+    bf->ifndef_macro = 0;
+    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+    //    printf("opening '%s'\n", filename);
+    return bf;
+}
+
+void tcc_close(BufferedFile *bf)
+{
+    total_lines += bf->line_num;
+    close(bf->fd);
+    tcc_free(bf);
+}
+
+#include "tccpp.c"
+#include "tccgen.c"
+
+
+/* compile the C file opened in 'file'. Return non zero if errors. */
+static int tcc_compile(TCCState *s1)
+{
+    Sym *define_start;
+    char buf[512];
+    volatile int section_sym;
+
+#ifdef INC_DEBUG
+    printf("%s: **** new file\n", file->filename);
+#endif
+    preprocess_init(s1);
+
+    cur_text_section = NULL;
+    funcname = "";
+    anon_sym = SYM_FIRST_ANOM; 
+
+    /* file info: full path + filename */
+    section_sym = 0; /* avoid warning */
+    if (s1->do_debug) {
+        section_sym = put_elf_sym(symtab_section, 0, 0, 
+                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0, 
+                                  text_section->sh_num, NULL);
+        getcwd(buf, sizeof(buf));
+#ifdef _WIN32
+        normalize_slashes(buf);
+#endif
+        pstrcat(buf, sizeof(buf), "/");
+        put_stabs_r(buf, N_SO, 0, 0, 
+                    text_section->data_offset, text_section, section_sym);
+        put_stabs_r(file->filename, N_SO, 0, 0, 
+                    text_section->data_offset, text_section, section_sym);
+    }
+    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
+       symbols can be safely used */
+    put_elf_sym(symtab_section, 0, 0, 
+                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0, 
+                SHN_ABS, file->filename);
+
+    /* define some often used types */
+    int_type.t = VT_INT;
+
+    char_pointer_type.t = VT_BYTE;
+    mk_pointer(&char_pointer_type);
+
+    func_old_type.t = VT_FUNC;
+    func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
+
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+    float_type.t = VT_FLOAT;
+    double_type.t = VT_DOUBLE;
+
+    func_float_type.t = VT_FUNC;
+    func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
+    func_double_type.t = VT_FUNC;
+    func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
+#endif
+
+#if 0
+    /* define 'void *alloca(unsigned int)' builtin function */
+    {
+        Sym *s1;
+
+        p = anon_sym++;
+        sym = sym_push(p, mk_pointer(VT_VOID), FUNC_CDECL, FUNC_NEW);
+        s1 = sym_push(SYM_FIELD, VT_UNSIGNED | VT_INT, 0, 0);
+        s1->next = NULL;
+        sym->next = s1;
+        sym_push(TOK_alloca, VT_FUNC | (p << VT_STRUCT_SHIFT), VT_CONST, 0);
+    }
+#endif
+
+    define_start = define_stack;
+    nocode_wanted = 1;
+
+    if (setjmp(s1->error_jmp_buf) == 0) {
+        s1->nb_errors = 0;
+        s1->error_set_jmp_enabled = 1;
+
+        ch = file->buf_ptr[0];
+        tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+        parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM;
+        next();
+        decl(VT_CONST);
+        if (tok != TOK_EOF)
+            expect("declaration");
+
+        /* end of translation unit info */
+        if (s1->do_debug) {
+            put_stabs_r(NULL, N_SO, 0, 0, 
+                        text_section->data_offset, text_section, section_sym);
+        }
+    }
+    s1->error_set_jmp_enabled = 0;
+
+    /* reset define stack, but leave -Dsymbols (may be incorrect if
+       they are undefined) */
+    free_defines(define_start); 
+
+    gen_inline_functions();
+
+    sym_pop(&global_stack, NULL);
+    sym_pop(&local_stack, NULL);
+
+    return s1->nb_errors != 0 ? -1 : 0;
+}
+
+int tcc_compile_string(TCCState *s, const char *str)
+{
+    BufferedFile bf1, *bf = &bf1;
+    int ret, len;
+    char *buf;
+
+    /* init file structure */
+    bf->fd = -1;
+    /* XXX: avoid copying */
+    len = strlen(str);
+    buf = tcc_malloc(len + 1);
+    if (!buf)
+        return -1;
+    memcpy(buf, str, len);
+    buf[len] = CH_EOB;
+    bf->buf_ptr = buf;
+    bf->buf_end = buf + len;
+    pstrcpy(bf->filename, sizeof(bf->filename), "<string>");
+    bf->line_num = 1;
+    file = bf;
+    ret = tcc_compile(s);
+    file = NULL;
+    tcc_free(buf);
+
+    /* currently, no need to close */
+    return ret;
+}
+
+/* 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)
+{
+    BufferedFile bf1, *bf = &bf1;
+
+    pstrcpy(bf->buffer, IO_BUF_SIZE, sym);
+    pstrcat(bf->buffer, IO_BUF_SIZE, " ");
+    /* default value */
+    if (!value) 
+        value = "1";
+    pstrcat(bf->buffer, IO_BUF_SIZE, value);
+    
+    /* init file structure */
+    bf->fd = -1;
+    bf->buf_ptr = bf->buffer;
+    bf->buf_end = bf->buffer + strlen(bf->buffer);
+    *bf->buf_end = CH_EOB;
+    bf->filename[0] = '\0';
+    bf->line_num = 1;
+    file = bf;
+    
+    s1->include_stack_ptr = s1->include_stack;
+
+    /* parse with define parser */
+    ch = file->buf_ptr[0];
+    next_nomacro();
+    parse_define();
+    file = NULL;
+}
+
+/* undefine a preprocessor symbol */
+void tcc_undefine_symbol(TCCState *s1, const char *sym)
+{
+    TokenSym *ts;
+    Sym *s;
+    ts = tok_alloc(sym, strlen(sym));
+    s = define_find(ts->tok);
+    /* undefine symbol by putting an invalid name */
+    if (s)
+        define_undef(s);
+}
+
+#ifdef CONFIG_TCC_ASM
+
+#ifdef TCC_TARGET_I386
+#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
+
+#ifdef CONFIG_TCC_BACKTRACE
+/* print the position in the source file of PC value 'pc' by reading
+   the stabs debug information */
+static void rt_printline(unsigned long wanted_pc)
+{
+    Stab_Sym *sym, *sym_end;
+    char func_name[128], last_func_name[128];
+    unsigned long func_addr, last_pc, pc;
+    const char *incl_files[INCLUDE_STACK_SIZE];
+    int incl_index, len, last_line_num, i;
+    const char *str, *p;
+
+    fprintf(stderr, "0x%08lx:", wanted_pc);
+
+    func_name[0] = '\0';
+    func_addr = 0;
+    incl_index = 0;
+    last_func_name[0] = '\0';
+    last_pc = 0xffffffff;
+    last_line_num = 1;
+    sym = (Stab_Sym *)stab_section->data + 1;
+    sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset);
+    while (sym < sym_end) {
+        switch(sym->n_type) {
+            /* function start or end */
+        case N_FUN:
+            if (sym->n_strx == 0) {
+                /* we test if between last line and end of function */
+                pc = sym->n_value + func_addr;
+                if (wanted_pc >= last_pc && wanted_pc < pc)
+                    goto found;
+                func_name[0] = '\0';
+                func_addr = 0;
+            } else {
+                str = stabstr_section->data + sym->n_strx;
+                p = strchr(str, ':');
+                if (!p) {
+                    pstrcpy(func_name, sizeof(func_name), str);
+                } else {
+                    len = p - str;
+                    if (len > sizeof(func_name) - 1)
+                        len = sizeof(func_name) - 1;
+                    memcpy(func_name, str, len);
+                    func_name[len] = '\0';
+                }
+                func_addr = sym->n_value;
+            }
+            break;
+            /* line number info */
+        case N_SLINE:
+            pc = sym->n_value + func_addr;
+            if (wanted_pc >= last_pc && wanted_pc < pc)
+                goto found;
+            last_pc = pc;
+            last_line_num = sym->n_desc;
+            /* XXX: slow! */
+            strcpy(last_func_name, func_name);
+            break;
+            /* include files */
+        case N_BINCL:
+            str = stabstr_section->data + sym->n_strx;
+        add_incl:
+            if (incl_index < INCLUDE_STACK_SIZE) {
+                incl_files[incl_index++] = str;
+            }
+            break;
+        case N_EINCL:
+            if (incl_index > 1)
+                incl_index--;
+            break;
+        case N_SO:
+            if (sym->n_strx == 0) {
+                incl_index = 0; /* end of translation unit */
+            } else {
+                str = stabstr_section->data + sym->n_strx;
+                /* do not add path */
+                len = strlen(str);
+                if (len > 0 && str[len - 1] != '/')
+                    goto add_incl;
+            }
+            break;
+        }
+        sym++;
+    }
+
+    /* second pass: we try symtab symbols (no line number info) */
+    incl_index = 0;
+    {
+        ElfW(Sym) *sym, *sym_end;
+        int type;
+
+        sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
+        for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
+            sym < sym_end;
+            sym++) {
+            type = ELFW(ST_TYPE)(sym->st_info);
+            if (type == STT_FUNC) {
+                if (wanted_pc >= sym->st_value &&
+                    wanted_pc < sym->st_value + sym->st_size) {
+                    pstrcpy(last_func_name, sizeof(last_func_name),
+                            strtab_section->data + sym->st_name);
+                    goto found;
+                }
+            }
+        }
+    }
+    /* did not find any info: */
+    fprintf(stderr, " ???\n");
+    return;
+ found:
+    if (last_func_name[0] != '\0') {
+        fprintf(stderr, " %s()", last_func_name);
+    }
+    if (incl_index > 0) {
+        fprintf(stderr, " (%s:%d", 
+                incl_files[incl_index - 1], last_line_num);
+        for(i = incl_index - 2; i >= 0; i--)
+            fprintf(stderr, ", included from %s", incl_files[i]);
+        fprintf(stderr, ")");
+    }
+    fprintf(stderr, "\n");
+}
+
+#ifdef __i386__
+/* fix for glibc 2.1 */
+#ifndef REG_EIP
+#define REG_EIP EIP
+#define REG_EBP EBP
+#endif
+
+/* return the PC at frame level 'level'. Return non zero if not found */
+static int rt_get_caller_pc(unsigned long *paddr, 
+                            ucontext_t *uc, int level)
+{
+    unsigned long fp;
+    int i;
+
+    if (level == 0) {
+#if defined(__FreeBSD__)
+        *paddr = uc->uc_mcontext.mc_eip;
+#elif defined(__dietlibc__)
+        *paddr = uc->uc_mcontext.eip;
+#else
+        *paddr = uc->uc_mcontext.gregs[REG_EIP];
+#endif
+        return 0;
+    } else {
+#if defined(__FreeBSD__) 
+        fp = uc->uc_mcontext.mc_ebp;
+#elif defined(__dietlibc__)
+        fp = uc->uc_mcontext.ebp;
+#else
+        fp = uc->uc_mcontext.gregs[REG_EBP];
+#endif
+        for(i=1;i<level;i++) {
+            /* XXX: check address validity with program info */
+            if (fp <= 0x1000 || fp >= 0xc0000000)
+                return -1;
+            fp = ((unsigned long *)fp)[0];
+        }
+        *paddr = ((unsigned long *)fp)[1];
+        return 0;
+    }
+}
+#elif defined(__x86_64__)
+/* return the PC at frame level 'level'. Return non zero if not found */
+static int rt_get_caller_pc(unsigned long *paddr,
+                            ucontext_t *uc, int level)
+{
+    unsigned long fp;
+    int i;
+
+    if (level == 0) {
+        /* XXX: only support linux */
+        *paddr = uc->uc_mcontext.gregs[REG_RIP];
+        return 0;
+    } else {
+        fp = uc->uc_mcontext.gregs[REG_RBP];
+        for(i=1;i<level;i++) {
+            /* XXX: check address validity with program info */
+            if (fp <= 0x1000)
+                return -1;
+            fp = ((unsigned long *)fp)[0];
+        }
+        *paddr = ((unsigned long *)fp)[1];
+        return 0;
+    }
+}
+#else
+#warning add arch specific rt_get_caller_pc()
+static int rt_get_caller_pc(unsigned long *paddr,
+                            ucontext_t *uc, int level)
+{
+    return -1;
+}
+#endif
+
+/* emit a run time error at position 'pc' */
+void rt_error(ucontext_t *uc, const char *fmt, ...)
+{
+    va_list ap;
+    unsigned long pc;
+    int i;
+
+    va_start(ap, fmt);
+    fprintf(stderr, "Runtime error: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    for(i=0;i<num_callers;i++) {
+        if (rt_get_caller_pc(&pc, uc, i) < 0)
+            break;
+        if (i == 0)
+            fprintf(stderr, "at ");
+        else
+            fprintf(stderr, "by ");
+        rt_printline(pc);
+    }
+    exit(255);
+    va_end(ap);
+}
+
+/* signal handler for fatal errors */
+static void sig_error(int signum, siginfo_t *siginf, void *puc)
+{
+    ucontext_t *uc = puc;
+
+    switch(signum) {
+    case SIGFPE:
+        switch(siginf->si_code) {
+        case FPE_INTDIV:
+        case FPE_FLTDIV:
+            rt_error(uc, "division by zero");
+            break;
+        default:
+            rt_error(uc, "floating point exception");
+            break;
+        }
+        break;
+    case SIGBUS:
+    case SIGSEGV:
+        if (rt_bound_error_msg && *rt_bound_error_msg)
+            rt_error(uc, *rt_bound_error_msg);
+        else
+            rt_error(uc, "dereferencing invalid pointer");
+        break;
+    case SIGILL:
+        rt_error(uc, "illegal instruction");
+        break;
+    case SIGABRT:
+        rt_error(uc, "abort() called");
+        break;
+    default:
+        rt_error(uc, "caught signal %d", signum);
+        break;
+    }
+    exit(255);
+}
+
+#endif
+
+/* copy code into memory passed in by the caller and do all relocations
+   (needed before using tcc_get_symbol()).
+   returns -1 on error and required size if ptr is NULL */
+int tcc_relocate(TCCState *s1, void *ptr)
+{
+    Section *s;
+    unsigned long offset, length, mem;
+    int i;
+
+    if (0 == s1->runtime_added) {
+        s1->runtime_added = 1;
+        s1->nb_errors = 0;
+#ifdef TCC_TARGET_PE
+        pe_add_runtime(s1);
+        relocate_common_syms();
+        tcc_add_linker_symbols(s1);
+#else
+        tcc_add_runtime(s1);
+        relocate_common_syms();
+        tcc_add_linker_symbols(s1);
+        build_got_entries(s1);
+#endif
+    }
+
+    offset = 0, mem = (unsigned long)ptr;
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (0 == (s->sh_flags & SHF_ALLOC))
+            continue;
+        length = s->data_offset;
+        s->sh_addr = mem ? (mem + offset + 15) & ~15 : 0;
+        offset = (offset + length + 15) & ~15;
+    }
+
+    /* relocate symbols */
+    relocate_syms(s1, 1);
+    if (s1->nb_errors)
+        return -1;
+
+#ifdef TCC_TARGET_X86_64
+    s1->runtime_plt_and_got_offset = 0;
+    s1->runtime_plt_and_got = (char *)(mem + offset);
+    /* double the size of the buffer for got and plt entries
+       XXX: calculate exact size for them? */
+    offset *= 2;
+#endif
+
+    if (0 == mem)
+        return offset + 15;
+
+    /* relocate each section */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->reloc)
+            relocate_section(s1, s);
+    }
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (0 == (s->sh_flags & SHF_ALLOC))
+            continue;
+        length = s->data_offset;
+        // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
+        ptr = (void*)s->sh_addr;
+        if (NULL == s->data || s->sh_type == SHT_NOBITS)
+            memset(ptr, 0, length);
+        else
+            memcpy(ptr, s->data, length);
+        /* mark executable sections as executable in memory */
+        if (s->sh_flags & SHF_EXECINSTR)
+            set_pages_executable(ptr, length);
+    }
+#ifdef TCC_TARGET_X86_64
+    set_pages_executable(s1->runtime_plt_and_got,
+                         s1->runtime_plt_and_got_offset);
+#endif
+    return 0;
+}
+
+/* launch the compiled program with the given arguments */
+int tcc_run(TCCState *s1, int argc, char **argv)
+{
+    int (*prog_main)(int, char **);
+    void *ptr;
+    int ret;
+
+    ret = tcc_relocate(s1, NULL);
+    if (ret < 0)
+        return -1;
+    ptr = tcc_malloc(ret);
+    tcc_relocate(s1, ptr);
+
+    prog_main = tcc_get_symbol_err(s1, "main");
+    
+    if (s1->do_debug) {
+#ifdef CONFIG_TCC_BACKTRACE
+        struct sigaction sigact;
+        /* install TCC signal handlers to print debug info on fatal
+           runtime errors */
+        sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
+        sigact.sa_sigaction = sig_error;
+        sigemptyset(&sigact.sa_mask);
+        sigaction(SIGFPE, &sigact, NULL);
+        sigaction(SIGILL, &sigact, NULL);
+        sigaction(SIGSEGV, &sigact, NULL);
+        sigaction(SIGBUS, &sigact, NULL);
+        sigaction(SIGABRT, &sigact, NULL);
+#else        
+        error("debug mode not available");
+#endif
+    }
+
+#ifdef CONFIG_TCC_BCHECK
+    if (s1->do_bounds_check) {
+        void (*bound_init)(void);
+
+        /* set error function */
+        rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
+
+        /* XXX: use .init section so that it also work in binary ? */
+        bound_init = (void *)tcc_get_symbol_err(s1, "__bound_init");
+        bound_init();
+    }
+#endif
+    ret = (*prog_main)(argc, argv);
+    tcc_free(ptr);
+    return ret;
+}
+
+void tcc_memstats(void)
+{
+#ifdef MEM_DEBUG
+    printf("memory in use: %d\n", mem_cur_size);
+#endif
+}
+
+static void tcc_cleanup(void)
+{
+    int i, n;
+
+    if (NULL == tcc_state)
+        return;
+    tcc_state = NULL;
+
+    /* free -D defines */
+    free_defines(NULL);
+
+    /* free tokens */
+    n = tok_ident - TOK_IDENT;
+    for(i = 0; i < n; i++)
+        tcc_free(table_ident[i]);
+    tcc_free(table_ident);
+
+    /* free sym_pools */
+    dynarray_reset(&sym_pools, &nb_sym_pools);
+    /* string buffer */
+    cstr_free(&tokcstr);
+    /* reset symbol stack */
+    sym_free_first = NULL;
+    /* cleanup from error/setjmp */
+    macro_ptr = NULL;
+}
+
+TCCState *tcc_new(void)
+{
+    TCCState *s;
+
+    tcc_cleanup();
+
+    s = tcc_mallocz(sizeof(TCCState));
+    if (!s)
+        return NULL;
+    tcc_state = s;
+    s->output_type = TCC_OUTPUT_MEMORY;
+    s->tcc_lib_path = CONFIG_TCCDIR;
+
+    preprocess_new();
+
+    /* we add dummy defines for some special macros to speed up tests
+       and to have working defined() */
+    define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
+
+    /* standard defines */
+    tcc_define_symbol(s, "__STDC__", NULL);
+    tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
+#if defined(TCC_TARGET_I386)
+    tcc_define_symbol(s, "__i386__", NULL);
+#endif
+#if defined(TCC_TARGET_X86_64)
+    tcc_define_symbol(s, "__x86_64__", NULL);
+#endif
+#if defined(TCC_TARGET_ARM)
+    tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
+    tcc_define_symbol(s, "__arm_elf__", NULL);
+    tcc_define_symbol(s, "__arm_elf", NULL);
+    tcc_define_symbol(s, "arm_elf", NULL);
+    tcc_define_symbol(s, "__arm__", NULL);
+    tcc_define_symbol(s, "__arm", NULL);
+    tcc_define_symbol(s, "arm", NULL);
+    tcc_define_symbol(s, "__APCS_32__", NULL);
+#endif
+#ifdef TCC_TARGET_PE
+    tcc_define_symbol(s, "_WIN32", NULL);
+#else
+    tcc_define_symbol(s, "__unix__", NULL);
+    tcc_define_symbol(s, "__unix", NULL);
+#if defined(__linux)
+    tcc_define_symbol(s, "__linux__", NULL);
+    tcc_define_symbol(s, "__linux", NULL);
+#endif
+#endif
+    /* tiny C specific defines */
+    tcc_define_symbol(s, "__TINYC__", NULL);
+
+    /* tiny C & gcc defines */
+    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
+    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
+#ifdef TCC_TARGET_PE
+    tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
+#else
+    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
+#endif
+    
+#ifndef TCC_TARGET_PE
+    /* default library paths */
+    tcc_add_library_path(s, CONFIG_SYSROOT "/usr/local/lib");
+    tcc_add_library_path(s, CONFIG_SYSROOT "/usr/lib");
+    tcc_add_library_path(s, CONFIG_SYSROOT "/lib");
+#endif
+
+    /* no section zero */
+    dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
+
+    /* create standard sections */
+    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
+    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+
+    /* symbols are always generated for linking stage */
+    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
+                                ".strtab",
+                                ".hashtab", SHF_PRIVATE); 
+    strtab_section = symtab_section->link;
+    
+    /* private symbol table for dynamic symbols */
+    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
+                                      ".dynstrtab", 
+                                      ".dynhashtab", SHF_PRIVATE);
+    s->alacarte_link = 1;
+
+#ifdef CHAR_IS_UNSIGNED
+    s->char_is_unsigned = 1;
+#endif
+#if defined(TCC_TARGET_PE) && 0
+    /* XXX: currently the PE linker is not ready to support that */
+    s->leading_underscore = 1;
+#endif
+    return s;
+}
+
+void tcc_delete(TCCState *s1)
+{
+    int i;
+
+    tcc_cleanup();
+
+    /* free all sections */
+    for(i = 1; i < s1->nb_sections; i++)
+        free_section(s1->sections[i]);
+    dynarray_reset(&s1->sections, &s1->nb_sections);
+
+    for(i = 0; i < s1->nb_priv_sections; i++)
+        free_section(s1->priv_sections[i]);
+    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
+        
+    /* free any loaded DLLs */
+    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
+        DLLReference *ref = s1->loaded_dlls[i];
+        if ( ref->handle )
+            dlclose(ref->handle);
+    }
+    
+    /* free loaded dlls array */
+    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
+
+    /* free library paths */
+    dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
+
+    /* free include paths */
+    dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
+    dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
+    dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
+
+    tcc_free(s1);
+}
+
+int tcc_add_include_path(TCCState *s1, const char *pathname)
+{
+    char *pathname1;
+    
+    pathname1 = tcc_strdup(pathname);
+    dynarray_add((void ***)&s1->include_paths, &s1->nb_include_paths, pathname1);
+    return 0;
+}
+
+int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
+{
+    char *pathname1;
+    
+    pathname1 = tcc_strdup(pathname);
+    dynarray_add((void ***)&s1->sysinclude_paths, &s1->nb_sysinclude_paths, pathname1);
+    return 0;
+}
+
+static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
+{
+    const char *ext;
+    ElfW(Ehdr) ehdr;
+    int fd, ret;
+    BufferedFile *saved_file;
+
+    /* find source file type with extension */
+    ext = tcc_fileextension(filename);
+    if (ext[0])
+        ext++;
+
+    /* open the file */
+    saved_file = file;
+    file = tcc_open(s1, filename);
+    if (!file) {
+        if (flags & AFF_PRINT_ERROR) {
+            error_noabort("file '%s' not found", filename);
+        }
+        ret = -1;
+        goto fail1;
+    }
+
+    if (flags & AFF_PREPROCESS) {
+        ret = tcc_preprocess(s1);
+    } else if (!ext[0] || !PATHCMP(ext, "c")) {
+        /* C file assumed */
+        ret = tcc_compile(s1);
+    } else 
+#ifdef CONFIG_TCC_ASM
+    if (!strcmp(ext, "S")) {
+        /* preprocessed assembler */
+        ret = tcc_assemble(s1, 1);
+    } else if (!strcmp(ext, "s")) {
+        /* non preprocessed assembler */
+        ret = tcc_assemble(s1, 0);
+    } else 
+#endif
+#ifdef TCC_TARGET_PE
+    if (!PATHCMP(ext, "def")) {
+        ret = pe_load_def_file(s1, file->fd);
+    } else
+#endif
+    {
+        fd = file->fd;
+        /* assume executable format: auto guess file type */
+        ret = read(fd, &ehdr, sizeof(ehdr));
+        lseek(fd, 0, SEEK_SET);
+        if (ret <= 0) {
+            error_noabort("could not read header");
+            goto fail;
+        } else if (ret != sizeof(ehdr)) {
+            goto try_load_script;
+        }
+
+        if (ehdr.e_ident[0] == ELFMAG0 &&
+            ehdr.e_ident[1] == ELFMAG1 &&
+            ehdr.e_ident[2] == ELFMAG2 &&
+            ehdr.e_ident[3] == ELFMAG3) {
+            file->line_num = 0; /* do not display line number if error */
+            if (ehdr.e_type == ET_REL) {
+                ret = tcc_load_object_file(s1, fd, 0);
+            } else if (ehdr.e_type == ET_DYN) {
+                if (s1->output_type == TCC_OUTPUT_MEMORY) {
+#ifdef TCC_TARGET_PE
+                    ret = -1;
+#else
+                    void *h;
+                    h = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
+                    if (h)
+                        ret = 0;
+                    else
+                        ret = -1;
+#endif
+                } else {
+                    ret = tcc_load_dll(s1, fd, filename, 
+                                       (flags & AFF_REFERENCED_DLL) != 0);
+                }
+            } else {
+                error_noabort("unrecognized ELF file");
+                goto fail;
+            }
+        } else if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
+            file->line_num = 0; /* do not display line number if error */
+            ret = tcc_load_archive(s1, fd);
+        } else 
+#ifdef TCC_TARGET_COFF
+        if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
+            ret = tcc_load_coff(s1, fd);
+        } else
+#endif
+#ifdef TCC_TARGET_PE
+        if (pe_test_res_file(&ehdr, ret)) {
+            ret = pe_load_res_file(s1, fd);
+        } else
+#endif
+        {
+            /* as GNU ld, consider it is an ld script if not recognized */
+        try_load_script:
+            ret = tcc_load_ldscript(s1);
+            if (ret < 0) {
+                error_noabort("unrecognized file type");
+                goto fail;
+            }
+        }
+    }
+ the_end:
+    tcc_close(file);
+ fail1:
+    file = saved_file;
+    return ret;
+ fail:
+    ret = -1;
+    goto the_end;
+}
+
+int tcc_add_file(TCCState *s, const char *filename)
+{
+    if (s->output_type == TCC_OUTPUT_PREPROCESS)
+        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS);
+    else
+        return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
+}
+
+int tcc_add_library_path(TCCState *s, const char *pathname)
+{
+    char *pathname1;
+    
+    pathname1 = tcc_strdup(pathname);
+    dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, pathname1);
+    return 0;
+}
+
+/* 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)
+{
+    char buf[1024];
+    int i;
+
+    for(i = 0; i < s->nb_library_paths; i++) {
+        snprintf(buf, sizeof(buf), "%s/%s", 
+                 s->library_paths[i], filename);
+        if (tcc_add_file_internal(s, buf, flags) == 0)
+            return 0;
+    }
+    return -1;
+}
+
+/* the library name is the same as the argument of the '-l' option */
+int tcc_add_library(TCCState *s, const char *libraryname)
+{
+    char buf[1024];
+    int i;
+    
+    /* first we look for the dynamic library if not static linking */
+    if (!s->static_link) {
+#ifdef TCC_TARGET_PE
+        snprintf(buf, sizeof(buf), "%s.def", libraryname);
+#else
+        snprintf(buf, sizeof(buf), "lib%s.so", libraryname);
+#endif
+        if (tcc_add_dll(s, buf, 0) == 0)
+            return 0;
+    }
+
+    /* then we look for the static library */
+    for(i = 0; i < s->nb_library_paths; i++) {
+        snprintf(buf, sizeof(buf), "%s/lib%s.a", 
+                 s->library_paths[i], libraryname);
+        if (tcc_add_file_internal(s, buf, 0) == 0)
+            return 0;
+    }
+    return -1;
+}
+
+int tcc_add_symbol(TCCState *s, const char *name, void *val)
+{
+    add_elf_sym(symtab_section, (unsigned long)val, 0, 
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                SHN_ABS, name);
+    return 0;
+}
+
+int tcc_set_output_type(TCCState *s, int output_type)
+{
+    char buf[1024];
+
+    s->output_type = output_type;
+
+    if (!s->nostdinc) {
+        /* default include paths */
+        /* XXX: reverse order needed if -isystem support */
+#ifndef TCC_TARGET_PE
+        tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/local/include");
+        tcc_add_sysinclude_path(s, CONFIG_SYSROOT "/usr/include");
+#endif
+        snprintf(buf, sizeof(buf), "%s/include", s->tcc_lib_path);
+        tcc_add_sysinclude_path(s, buf);
+#ifdef TCC_TARGET_PE
+        snprintf(buf, sizeof(buf), "%s/include/winapi", s->tcc_lib_path);
+        tcc_add_sysinclude_path(s, buf);
+#endif
+    }
+
+    /* if bound checking, then add corresponding sections */
+#ifdef CONFIG_TCC_BCHECK
+    if (s->do_bounds_check) {
+        /* define symbol */
+        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
+        /* create bounds sections */
+        bounds_section = new_section(s, ".bounds", 
+                                     SHT_PROGBITS, SHF_ALLOC);
+        lbounds_section = new_section(s, ".lbounds", 
+                                      SHT_PROGBITS, SHF_ALLOC);
+    }
+#endif
+
+    if (s->char_is_unsigned) {
+        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
+    }
+
+    /* add debug sections */
+    if (s->do_debug) {
+        /* stab symbols */
+        stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
+        stab_section->sh_entsize = sizeof(Stab_Sym);
+        stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
+        put_elf_str(stabstr_section, "");
+        stab_section->link = stabstr_section;
+        /* put first entry */
+        put_stabs("", 0, 0, 0, 0);
+    }
+
+    /* add libc crt1/crti objects */
+#ifndef TCC_TARGET_PE
+    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
+        !s->nostdlib) {
+        if (output_type != TCC_OUTPUT_DLL)
+            tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crt1.o");
+        tcc_add_file(s, CONFIG_TCC_CRT_PREFIX "/crti.o");
+    }
+#endif
+
+#ifdef TCC_TARGET_PE
+    snprintf(buf, sizeof(buf), "%s/lib", s->tcc_lib_path);
+    tcc_add_library_path(s, buf);
+#endif
+
+    return 0;
+}
+
+#define WD_ALL    0x0001 /* warning is activated when using -Wall */
+#define FD_INVERT 0x0002 /* invert value before storing */
+
+typedef struct FlagDef {
+    uint16_t offset;
+    uint16_t flags;
+    const char *name;
+} FlagDef;
+
+static const FlagDef warning_defs[] = {
+    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
+    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
+    { offsetof(TCCState, warn_error), 0, "error" },
+    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
+      "implicit-function-declaration" },
+};
+
+static int set_flag(TCCState *s, const FlagDef *flags, int nb_flags,
+                    const char *name, int value)
+{
+    int i;
+    const FlagDef *p;
+    const char *r;
+
+    r = name;
+    if (r[0] == 'n' && r[1] == 'o' && r[2] == '-') {
+        r += 3;
+        value = !value;
+    }
+    for(i = 0, p = flags; i < nb_flags; i++, p++) {
+        if (!strcmp(r, p->name))
+            goto found;
+    }
+    return -1;
+ found:
+    if (p->flags & FD_INVERT)
+        value = !value;
+    *(int *)((uint8_t *)s + p->offset) = value;
+    return 0;
+}
+
+
+/* set/reset a warning */
+int tcc_set_warning(TCCState *s, const char *warning_name, int value)
+{
+    int i;
+    const FlagDef *p;
+
+    if (!strcmp(warning_name, "all")) {
+        for(i = 0, p = warning_defs; i < countof(warning_defs); i++, p++) {
+            if (p->flags & WD_ALL)
+                *(int *)((uint8_t *)s + p->offset) = 1;
+        }
+        return 0;
+    } else {
+        return set_flag(s, warning_defs, countof(warning_defs),
+                        warning_name, value);
+    }
+}
+
+static const FlagDef flag_defs[] = {
+    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
+    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
+    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
+    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
+};
+
+/* set/reset a flag */
+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)
+{
+    s->tcc_lib_path = tcc_strdup(path);
+}
+
+void tcc_print_stats(TCCState *s, int64_t total_time)
+{
+    double tt;
+    tt = (double)total_time / 1000000.0;
+    if (tt < 0.001)
+        tt = 0.001;
+    if (total_bytes < 1)
+        total_bytes = 1;
+    printf("%d idents, %d lines, %d bytes, %0.3f s, %d lines/s, %0.1f MB/s\n", 
+           tok_ident - TOK_IDENT, total_lines, total_bytes,
+           tt, (int)(total_lines / tt),
+           total_bytes / tt / 1000000.0);
+}
diff --git a/tinyc/libtcc.h b/tinyc/libtcc.h
new file mode 100755
index 000000000..96070e299
--- /dev/null
+++ b/tinyc/libtcc.h
@@ -0,0 +1,108 @@
+#ifndef LIBTCC_H
+#define LIBTCC_H
+
+#ifdef LIBTCC_AS_DLL
+#define LIBTCCAPI __declspec(dllexport)
+#else
+#define LIBTCCAPI
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct TCCState;
+
+typedef struct TCCState TCCState;
+
+/* create a new TCC compilation context */
+LIBTCCAPI TCCState *tcc_new(void);
+
+/* free a TCC compilation context */
+LIBTCCAPI void tcc_delete(TCCState *s);
+
+/* add debug information in the generated code */
+LIBTCCAPI void tcc_enable_debug(TCCState *s);
+
+/* set error/warning display callback */
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+                        void (*error_func)(void *opaque, const char *msg));
+
+/* set/reset a warning */
+LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value);
+
+/*****************************/
+/* preprocessor */
+
+/* add include path */
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
+
+/* add in system include path */
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
+
+/* define preprocessor symbol 'sym'. Can put optional value */
+LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
+
+/* undefine preprocess symbol 'sym' */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
+
+/*****************************/
+/* compiling */
+
+/* add a file (either a C file, dll, an object, a library or an ld
+   script). Return -1 if error. */
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
+
+/* compile a string containing a C source. Return non zero if
+   error. */
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
+
+/*****************************/
+/* linking commands */
+
+/* set output type. MUST BE CALLED before any compilation */
+#define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
+                                 output file) (default) */
+#define TCC_OUTPUT_EXE      1 /* executable file */
+#define TCC_OUTPUT_DLL      2 /* dynamic library */
+#define TCC_OUTPUT_OBJ      3 /* object file */
+#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
+
+#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
+#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
+#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
+
+/* equivalent to -Lpath option */
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
+
+/* add a symbol to the compiled program */
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val);
+
+/* output an executable, library or object file. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
+
+/* link and run main() function and return its value. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
+
+/* copy code into memory passed in by the caller and do all relocations
+   (needed before using tcc_get_symbol()).
+   returns -1 on error and required size if ptr is NULL */
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
+
+/* return symbol value or NULL if not found */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tinyc/stab.def b/tinyc/stab.def
new file mode 100755
index 000000000..48ea231e6
--- /dev/null
+++ b/tinyc/stab.def
@@ -0,0 +1,234 @@
+/* Table of DBX symbol codes for the GNU system.
+   Copyright (C) 1988, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This contains contribution from Cygnus Support.  */
+
+/* Global variable.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C.  Value is its address.
+   Desc is supposedly starting line number, but GCC doesn't set it
+   and DBX seems not to miss it.  */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage.  Value is its address.
+   "Static Sym".  */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage.  Value is its address.  */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine.  Only the name is significant.
+   This is not used in C.  */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Global symbol in Pascal.
+   Supposedly the value is its line number; I'm skeptical.  */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris.  I don't know what it means, but it
+   don't seem to contain useful information.  */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris.  I don't know what it means, but it
+   don't seem to contain useful information.  Possibly related to the
+   optimization flags used in this module.  */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable.  Value is number of register.  */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit.  Can someone say what info it contains?  */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment.  Desc is the line number;
+   value is corresponding address.  */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment.  */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment.  */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs.  ?? Don't know what the fields are.
+   Supposedly the field is "path to associated .cb file".  THIS VALUE
+   OVERLAPS WITH N_BSLINE!  */
+__define_stab (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency.  Value is the modification time
+   of the definition file.  Other is non-zero if it is imported with the
+   GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
+   are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
+   and one is for C++.   Still,... */
+/* GNU C++ exception variable.  Name is variable name.  */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
+__define_stab (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
+   this entry is immediately followed by a CAUGHT stab saying what exception
+   was caught.  Multiple CAUGHT stabs means that multiple exceptions
+   can be caught here.  If Desc is 0, it means all exceptions are caught
+   here.  */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element.  Value is offset in the structure.  */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Name of main source file.
+   Value is starting text address of the compilation.  */
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack.  Value is offset from frame pointer.
+   Also used for type descriptions.  */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file.  Only Sun uses this.
+   In an object file, only the name is significant.
+   The Sun linker puts data into some of the other fields.  */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+   Value is starting text address of the compilation.  */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable.  Value is offset from argument pointer.
+   (On most machines the argument pointer is the same as the frame pointer.  */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file.  No name.
+   This and N_BINCL act as brackets around the file's output.
+   In an object file, there is no significant data in this entry.
+   The Sun linker puts data into some of the fields.  */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point.  Value is its address.  */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+   The desc is the nesting level in lexical blocks.
+   The value is the address of the start of the text for the block.
+   The variables declared inside the block *precede* the N_LBRAC symbol.  */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file.  Replaces a N_BINCL and everything
+   up to the corresponding N_EINCL.  The Sun linker generates these when
+   it finds multiple identical copies of the symbols from an include file.
+   This appears only in output from the Sun linker.  */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information.  Can someone say what info it contains?  */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block.  Desc matches the N_LBRAC's desc.
+   The value is the address of the end of the text for the block.  */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block.  Only the name is significant.  */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block.  Only the name is significant
+   (and it should match the N_BCOMM).  */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* End common (local name): value is address.
+   I'm not sure how this is used.  */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+   or something like that.  FIXME.  I have assigned the values at random
+   since I don't have a Gould here.  Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS,  0xF4, "NBBSS")
+__define_stab (N_NBSTS,  0xF6, "NBSTS")
+__define_stab (N_NBLCS,  0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+   The value is the length.  */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+/* The above information, in matrix format.
+
+			STAB MATRIX
+	_________________________________________________
+	| 00 - 1F are not dbx stab symbols		|
+	| In most cases, the low bit is the EXTernal bit|
+
+	| 00 UNDEF  | 02 ABS	| 04 TEXT   | 06 DATA	|
+	| 01  |EXT  | 03  |EXT	| 05  |EXT  | 07  |EXT	|
+
+	| 08 BSS    | 0A INDR	| 0C FN_SEQ | 0E   	|
+	| 09  |EXT  | 0B 	| 0D	    | 0F	|
+
+	| 10 	    | 12 COMM	| 14 SETA   | 16 SETT	|
+	| 11	    | 13	| 15 	    | 17	|
+
+	| 18 SETD   | 1A SETB	| 1C SETV   | 1E WARNING|
+	| 19	    | 1B	| 1D 	    | 1F FN	|
+
+	|_______________________________________________|
+	| Debug entries with bit 01 set are unused.	|
+	| 20 GSYM   | 22 FNAME	| 24 FUN    | 26 STSYM	|
+	| 28 LCSYM  | 2A MAIN	| 2C	    | 2E	|
+	| 30 PC	    | 32 NSYMS	| 34 NOMAP  | 36	|
+	| 38 OBJ    | 3A	| 3C OPT    | 3E	|
+	| 40 RSYM   | 42 M2C	| 44 SLINE  | 46 DSLINE |
+	| 48 BSLINE*| 4A DEFD	| 4C        | 4E	|
+	| 50 EHDECL*| 52	| 54 CATCH  | 56        |
+	| 58        | 5A        | 5C        | 5E	|
+	| 60 SSYM   | 62	| 64 SO	    | 66 	|
+	| 68 	    | 6A	| 6C	    | 6E	|
+	| 70	    | 72	| 74	    | 76	|
+	| 78	    | 7A	| 7C	    | 7E	|
+	| 80 LSYM   | 82 BINCL	| 84 SOL    | 86	|
+	| 88	    | 8A	| 8C	    | 8E	|
+	| 90	    | 92	| 94	    | 96	|
+	| 98	    | 9A	| 9C	    | 9E	|
+	| A0 PSYM   | A2 EINCL	| A4 ENTRY  | A6	|
+	| A8	    | AA	| AC	    | AE	|
+	| B0	    | B2	| B4	    | B6	|
+	| B8	    | BA	| BC	    | BE	|
+	| C0 LBRAC  | C2 EXCL	| C4 SCOPE  | C6	|
+	| C8	    | CA	| CC	    | CE	|
+	| D0	    | D2	| D4	    | D6	|
+	| D8	    | DA	| DC	    | DE	|
+	| E0 RBRAC  | E2 BCOMM	| E4 ECOMM  | E6	|
+	| E8 ECOML  | EA	| EC	    | EE	|
+	| F0	    | F2	| F4	    | F6	|
+	| F8	    | FA	| FC	    | FE LENG	|
+	+-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
diff --git a/tinyc/stab.h b/tinyc/stab.h
new file mode 100755
index 000000000..80bd594a3
--- /dev/null
+++ b/tinyc/stab.h
@@ -0,0 +1,17 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use.  */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+#endif /* __GNU_STAB_ */
diff --git a/tinyc/tcc-doc.html b/tinyc/tcc-doc.html
new file mode 100755
index 000000000..e40532ed0
--- /dev/null
+++ b/tinyc/tcc-doc.html
@@ -0,0 +1,2241 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
+<html>
+<!-- Created on May, 18 2009 by texi2html 1.78 -->
+<!--
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+            Karl Berry  <karl@freefriends.org>
+            Olaf Bachmann <obachman@mathematik.uni-kl.de>
+            and many others.
+Maintained by: Many creative people.
+Send bugs and suggestions to <texi2html-bug@nongnu.org>
+
+-->
+<head>
+<title>Tiny C Compiler Reference Documentation</title>
+
+<meta name="description" content="Tiny C Compiler Reference Documentation">
+<meta name="keywords" content="Tiny C Compiler Reference Documentation">
+<meta name="resource-type" content="document">
+<meta name="distribution" content="global">
+<meta name="Generator" content="texi2html 1.78">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<style type="text/css">
+<!--
+a.summary-letter {text-decoration: none}
+pre.display {font-family: serif}
+pre.format {font-family: serif}
+pre.menu-comment {font-family: serif}
+pre.menu-preformatted {font-family: serif}
+pre.smalldisplay {font-family: serif; font-size: smaller}
+pre.smallexample {font-size: smaller}
+pre.smallformat {font-family: serif; font-size: smaller}
+pre.smalllisp {font-size: smaller}
+span.roman {font-family:serif; font-weight:normal;}
+span.sansserif {font-family:sans-serif; font-weight:normal;}
+ul.toc {list-style: none}
+-->
+</style>
+
+
+</head>
+
+<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
+
+<a name="Top"></a>
+<a name="SEC_Top"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="settitle">Tiny C Compiler Reference Documentation</h1>
+
+<p>This manual documents version  of the Tiny C Compiler.
+</p>
+<table class="menu" border="0" cellspacing="0">
+<tr><td align="left" valign="top"><a href="#SEC1">1. Introduction</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                Introduction to tcc.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC2">2. Command line invocation</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Invocation of tcc (command line, options).
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC5">3. C language support</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       ANSI C and extensions.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC10">4. TinyCC Assembler</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                         Assembler syntax.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC16">5. TinyCC Linker</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Output file generation and supported targets.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      Automatic bounds-checking of C code.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC22">7. The <code>libtcc</code> library</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      The libtcc library.
+</td></tr>
+<tr><td align="left" valign="top"><a href="#SEC23">8. Developer's guide</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                       Guide for Developers.
+</td></tr>
+</table>
+
+
+<hr size="1">
+<a name="Introduction"></a>
+<a name="SEC1"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[ &lt;&lt; ]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 1. Introduction </h1>
+
+<p>TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+</p>
+<p>TCC compiles so <em>fast</em> that even for big projects <code>Makefile</code>s may
+not be necessary.
+</p>
+<p>TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+</p>
+<p>TCC can also be used to make <em>C scripts</em>, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+</p>
+<p>TCC can also automatically generate memory and bound checks
+(see section <a href="#SEC21">TinyCC Memory and Bound checks</a>) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+</p>
+<p>With <code>libtcc</code>, you can use TCC as a backend for dynamic code
+generation (see section <a href="#SEC22">The <code>libtcc</code> library</a>).
+</p>
+<p>TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (<code>arm-tcc</code>) and the TMS320C67xx targets
+(<code>c67-tcc</code>). More information about the ARM port is available at
+<a href="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</a>.
+</p>
+<p>For usage on Windows, see also tcc-win32.txt.
+</p>
+<hr size="6">
+<a name="Invoke"></a>
+<a name="SEC2"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC1" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC3" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC1" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 2. Command line invocation </h1>
+
+<hr size="6">
+<a name="SEC3"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC2" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC4" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 2.1 Quick start </h2>
+
+<table><tr><td>&nbsp;</td><td><pre class="example">usage: tcc [options] [<var>infile1</var> <var>infile2</var>&hellip;] [&lsquo;<samp>-run</samp>&rsquo; <var>infile</var> <var>args</var>&hellip;]
+</pre></td></tr></table>
+
+<p>TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+</p>
+<p>Here are some examples to understand the logic:
+</p>
+<dl compact="compact">
+<dt> <code>&lsquo;<samp>tcc -run a.c</samp>&rsquo;</code></dt>
+<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and execute it directly
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -run a.c arg1</samp>&rsquo;</code></dt>
+<dd><p>Compile a.c and execute it directly. arg1 is given as first argument to
+the <code>main()</code> of a.c.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc a.c -run b.c arg1</samp>&rsquo;</code></dt>
+<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and execute them. arg1 is given
+as first argument to the <code>main()</code> of the resulting program. 
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -o myprog a.c b.c</samp>&rsquo;</code></dt>
+<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -o myprog a.o b.o</samp>&rsquo;</code></dt>
+<dd><p>link &lsquo;<tt>a.o</tt>&rsquo; and &lsquo;<tt>b.o</tt>&rsquo; together and generate the executable &lsquo;<tt>myprog</tt>&rsquo;.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -c a.c</samp>&rsquo;</code></dt>
+<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and generate object file &lsquo;<tt>a.o</tt>&rsquo;.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -c asmfile.S</samp>&rsquo;</code></dt>
+<dd><p>Preprocess with C preprocess and assemble &lsquo;<tt>asmfile.S</tt>&rsquo; and generate
+object file &lsquo;<tt>asmfile.o</tt>&rsquo;.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -c asmfile.s</samp>&rsquo;</code></dt>
+<dd><p>Assemble (but not preprocess) &lsquo;<tt>asmfile.s</tt>&rsquo; and generate object file
+&lsquo;<tt>asmfile.o</tt>&rsquo;.
+</p>
+</dd>
+<dt> <code>&lsquo;<samp>tcc -r -o ab.o a.c b.c</samp>&rsquo;</code></dt>
+<dd><p>Compile &lsquo;<tt>a.c</tt>&rsquo; and &lsquo;<tt>b.c</tt>&rsquo;, link them together and generate the object file &lsquo;<tt>ab.o</tt>&rsquo;.
+</p>
+</dd>
+</dl>
+
+<p>Scripting:
+</p>
+<p>TCC can be invoked from <em>scripts</em>, just as shell scripts. You just
+need to add <code>#!/usr/local/bin/tcc -run</code> at the start of your C source:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run
+#include &lt;stdio.h&gt;
+
+int main() 
+{
+    printf(&quot;Hello World\n&quot;);
+    return 0;
+}
+</pre></td></tr></table>
+
+<p>TCC can read C source code from <em>standard input</em> when &lsquo;<samp>-</samp>&rsquo; is used in 
+place of &lsquo;<samp>infile</samp>&rsquo;. Example:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">echo 'main(){puts(&quot;hello&quot;);}' | tcc -run -
+</pre></td></tr></table>
+
+<hr size="6">
+<a name="SEC4"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC3" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 2.2 Option summary </h2>
+
+<p>General Options:
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-v</samp>&rsquo;</dt>
+<dd><p>Display current TCC version, increase verbosity.
+</p>
+</dd>
+<dt> &lsquo;<samp>-c</samp>&rsquo;</dt>
+<dd><p>Generate an object file (&lsquo;<samp>-o</samp>&rsquo; option must also be given).
+</p>
+</dd>
+<dt> &lsquo;<samp>-o outfile</samp>&rsquo;</dt>
+<dd><p>Put object file, executable, or dll into output file &lsquo;<tt>outfile</tt>&rsquo;.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Bdir</samp>&rsquo;</dt>
+<dd><p>Set the path where the tcc internal libraries can be found (default is
+&lsquo;<tt>PREFIX/lib/tcc</tt>&rsquo;).
+</p>
+</dd>
+<dt> &lsquo;<samp>-bench</samp>&rsquo;</dt>
+<dd><p>Output compilation statistics.
+</p>
+</dd>
+<dt> &lsquo;<samp>-run source [args...]</samp>&rsquo;</dt>
+<dd><p>Compile file <var>source</var> and run it with the command line arguments
+<var>args</var>. In order to be able to give more than one argument to a
+script, several TCC options can be given <em>after</em> the
+&lsquo;<samp>-run</samp>&rsquo; option, separated by spaces. Example:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">tcc &quot;-run -L/usr/X11R6/lib -lX11&quot; ex4.c
+</pre></td></tr></table>
+
+<p>In a script, it gives the following header:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+#include &lt;stdlib.h&gt;
+int main(int argc, char **argv)
+{
+    ...
+}
+</pre></td></tr></table>
+
+</dd>
+</dl>
+
+<p>Preprocessor options:
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-Idir</samp>&rsquo;</dt>
+<dd><p>Specify an additional include path. Include paths are searched in the
+order they are specified.
+</p>
+<p>System include paths are always searched after. The default system
+include paths are: &lsquo;<tt>/usr/local/include</tt>&rsquo;, &lsquo;<tt>/usr/include</tt>&rsquo;
+and &lsquo;<tt>PREFIX/lib/tcc/include</tt>&rsquo;. (&lsquo;<tt>PREFIX</tt>&rsquo; is usually
+&lsquo;<tt>/usr</tt>&rsquo; or &lsquo;<tt>/usr/local</tt>&rsquo;).
+</p>
+</dd>
+<dt> &lsquo;<samp>-Dsym[=val]</samp>&rsquo;</dt>
+<dd><p>Define preprocessor symbol &lsquo;<samp>sym</samp>&rsquo; to
+val. If val is not present, its value is &lsquo;<samp>1</samp>&rsquo;. Function-like macros can
+also be defined: &lsquo;<samp>-DF(a)=a+1</samp>&rsquo;
+</p>
+</dd>
+<dt> &lsquo;<samp>-Usym</samp>&rsquo;</dt>
+<dd><p>Undefine preprocessor symbol &lsquo;<samp>sym</samp>&rsquo;.
+</p></dd>
+</dl>
+
+<p>Compilation flags:
+</p>
+<p>Note: each of the following warning options has a negative form beginning with
+&lsquo;<samp>-fno-</samp>&rsquo;.
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-funsigned-char</samp>&rsquo;</dt>
+<dd><p>Let the <code>char</code> type be unsigned.
+</p>
+</dd>
+<dt> &lsquo;<samp>-fsigned-char</samp>&rsquo;</dt>
+<dd><p>Let the <code>char</code> type be signed.
+</p>
+</dd>
+<dt> &lsquo;<samp>-fno-common</samp>&rsquo;</dt>
+<dd><p>Do not generate common symbols for uninitialized data.
+</p>
+</dd>
+<dt> &lsquo;<samp>-fleading-underscore</samp>&rsquo;</dt>
+<dd><p>Add a leading underscore at the beginning of each C symbol.
+</p>
+</dd>
+</dl>
+
+<p>Warning options:
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-w</samp>&rsquo;</dt>
+<dd><p>Disable all warnings.
+</p>
+</dd>
+</dl>
+
+<p>Note: each of the following warning options has a negative form beginning with
+&lsquo;<samp>-Wno-</samp>&rsquo;.
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-Wimplicit-function-declaration</samp>&rsquo;</dt>
+<dd><p>Warn about implicit function declaration.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Wunsupported</samp>&rsquo;</dt>
+<dd><p>Warn about unsupported GCC features that are ignored by TCC.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Wwrite-strings</samp>&rsquo;</dt>
+<dd><p>Make string constants be of type <code>const char *</code> instead of <code>char
+*</code>.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Werror</samp>&rsquo;</dt>
+<dd><p>Abort compilation if warnings are issued.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Wall</samp>&rsquo; </dt>
+<dd><p>Activate all warnings, except &lsquo;<samp>-Werror</samp>&rsquo;, &lsquo;<samp>-Wunusupported</samp>&rsquo; and
+&lsquo;<samp>-Wwrite-strings</samp>&rsquo;.
+</p>
+</dd>
+</dl>
+
+<p>Linker options:
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-Ldir</samp>&rsquo;</dt>
+<dd><p>Specify an additional static library path for the &lsquo;<samp>-l</samp>&rsquo; option. The
+default library paths are &lsquo;<tt>/usr/local/lib</tt>&rsquo;, &lsquo;<tt>/usr/lib</tt>&rsquo; and &lsquo;<tt>/lib</tt>&rsquo;.
+</p>
+</dd>
+<dt> &lsquo;<samp>-lxxx</samp>&rsquo;</dt>
+<dd><p>Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+&lsquo;<samp>-L</samp>&rsquo; option.
+</p>
+</dd>
+<dt> &lsquo;<samp>-shared</samp>&rsquo;</dt>
+<dd><p>Generate a shared library instead of an executable (&lsquo;<samp>-o</samp>&rsquo; option
+must also be given).
+</p>
+</dd>
+<dt> &lsquo;<samp>-static</samp>&rsquo;</dt>
+<dd><p>Generate a statically linked executable (default is a shared linked
+executable) (&lsquo;<samp>-o</samp>&rsquo; option must also be given).
+</p>
+</dd>
+<dt> &lsquo;<samp>-rdynamic</samp>&rsquo;</dt>
+<dd><p>Export global symbols to the dynamic linker. It is useful when a library
+opened with <code>dlopen()</code> needs to access executable symbols.
+</p>
+</dd>
+<dt> &lsquo;<samp>-r</samp>&rsquo;</dt>
+<dd><p>Generate an object file combining all input files (&lsquo;<samp>-o</samp>&rsquo; option must
+also be given).
+</p>
+</dd>
+<dt> &lsquo;<samp>-Wl,-Ttext,address</samp>&rsquo;</dt>
+<dd><p>Set the start of the .text section to <var>address</var>.
+</p>
+</dd>
+<dt> &lsquo;<samp>-Wl,--oformat,fmt</samp>&rsquo;</dt>
+<dd><p>Use <var>fmt</var> as output format. The supported output formats are:
+</p><dl compact="compact">
+<dt> <code>elf32-i386</code></dt>
+<dd><p>ELF output format (default)
+</p></dd>
+<dt> <code>binary</code></dt>
+<dd><p>Binary image (only for executable output)
+</p></dd>
+<dt> <code>coff</code></dt>
+<dd><p>COFF output format (only for executable output for TMS320C67xx target)
+</p></dd>
+</dl>
+
+</dd>
+</dl>
+
+<p>Debugger options:
+</p>
+<dl compact="compact">
+<dt> &lsquo;<samp>-g</samp>&rsquo;</dt>
+<dd><p>Generate run time debug information so that you get clear run time
+error messages: <code> test.c:68: in function 'test5()': dereferencing
+invalid pointer</code> instead of the laconic <code>Segmentation
+fault</code>.
+</p>
+</dd>
+<dt> &lsquo;<samp>-b</samp>&rsquo;</dt>
+<dd><p>Generate additional support code to check
+memory allocations and array/pointer bounds. &lsquo;<samp>-g</samp>&rsquo; is implied. Note
+that the generated code is slower and bigger in this case.
+</p>
+</dd>
+<dt> &lsquo;<samp>-bt N</samp>&rsquo;</dt>
+<dd><p>Display N callers in stack traces. This is useful with &lsquo;<samp>-g</samp>&rsquo; or
+&lsquo;<samp>-b</samp>&rsquo;.
+</p>
+</dd>
+</dl>
+
+<p>Note: GCC options &lsquo;<samp>-Ox</samp>&rsquo;, &lsquo;<samp>-fx</samp>&rsquo; and &lsquo;<samp>-mx</samp>&rsquo; are
+ignored.
+</p>
+
+<hr size="6">
+<a name="Clang"></a>
+<a name="SEC5"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC4" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC6" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC2" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 3. C language support </h1>
+
+<hr size="6">
+<a name="SEC6"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC5" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC7" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 3.1 ANSI C </h2>
+
+<p>TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (<code>long double</code>, <code>double</code>, and
+<code>float</code> fully supported).
+</p>
+<hr size="6">
+<a name="SEC7"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC6" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC8" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 3.2 ISOC99 extensions </h2>
+
+<p>TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers and variable length
+arrays.
+</p>
+<p>Currently implemented ISOC99 features:
+</p>
+<ul class="toc">
+<li> 64 bit <code>long long</code> types are fully supported.
+
+</li><li> The boolean type <code>_Bool</code> is supported.
+
+</li><li> <code>__func__</code> is a string variable containing the current
+function name.
+
+</li><li> Variadic macros: <code>__VA_ARGS__</code> can be used for
+   function-like macros:
+<table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+</pre></td></tr></table>
+
+<p><code>dprintf</code> can then be used with a variable number of parameters.
+</p>
+</li><li> Declarations can appear anywhere in a block (as in C++).
+
+</li><li> Array and struct/union elements can be initialized in any order by
+  using designators:
+<table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
+
+    int tab[10] = { 1, 2, [5] = 5, [9] = 9};
+</pre></td></tr></table>
+    
+</li><li> Compound initializers are supported:
+<table><tr><td>&nbsp;</td><td><pre class="example">    int *p = (int []){ 1, 2, 3 };
+</pre></td></tr></table>
+<p>to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+</p>
+</li><li> Hexadecimal floating point constants are supported:
+<table><tr><td>&nbsp;</td><td><pre class="example">          double d = 0x1234p10;
+</pre></td></tr></table>
+
+<p>is the same as writing 
+</p><table><tr><td>&nbsp;</td><td><pre class="example">          double d = 4771840.0;
+</pre></td></tr></table>
+
+</li><li> <code>inline</code> keyword is ignored.
+
+</li><li> <code>restrict</code> keyword is ignored.
+</li></ul>
+
+<hr size="6">
+<a name="SEC8"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC7" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC9" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 3.3 GNU C extensions </h2>
+
+<p>TCC implements some GNU C extensions:
+</p>
+<ul class="toc">
+<li> array designators can be used without '=': 
+<table><tr><td>&nbsp;</td><td><pre class="example">    int a[10] = { [0] 1, [5] 2, 3, 4 };
+</pre></td></tr></table>
+
+</li><li> Structure field designators can be a label: 
+<table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { x: 1, y: 1};
+</pre></td></tr></table>
+<p>instead of
+</p><table><tr><td>&nbsp;</td><td><pre class="example">    struct { int x, y; } st = { .x = 1, .y = 1};
+</pre></td></tr></table>
+
+</li><li> <code>\e</code> is ASCII character 27.
+
+</li><li> case ranges : ranges can be used in <code>case</code>s:
+<table><tr><td>&nbsp;</td><td><pre class="example">    switch(a) {
+    case 1 &hellip; 9:
+          printf(&quot;range 1 to 9\n&quot;);
+          break;
+    default:
+          printf(&quot;unexpected\n&quot;);
+          break;
+    }
+</pre></td></tr></table>
+
+<a name="IDX1"></a>
+<a name="IDX2"></a>
+<a name="IDX3"></a>
+<a name="IDX4"></a>
+<a name="IDX5"></a>
+<a name="IDX6"></a>
+<a name="IDX7"></a>
+<a name="IDX8"></a>
+
+</li><li> The keyword <code>__attribute__</code> is handled to specify variable or
+function attributes. The following attributes are supported:
+  
+<ul class="toc">
+<li> <code>aligned(n)</code>: align a variable or a structure field to n bytes
+(must be a power of two).
+
+  </li><li> <code>packed</code>: force alignment of a variable or a structure field to
+  1.
+
+  </li><li> <code>section(name)</code>: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+
+  </li><li> <code>unused</code>: specify that the variable or the function is unused.
+
+  </li><li> <code>cdecl</code>: use standard C calling convention (default).
+
+  </li><li> <code>stdcall</code>: use Pascal-like calling convention.
+
+  </li><li> <code>regparm(n)</code>: use fast i386 calling convention. <var>n</var> must be
+between 1 and 3. The first <var>n</var> function parameters are respectively put in
+registers <code>%eax</code>, <code>%edx</code> and <code>%ecx</code>.
+
+  </li><li> <code>dllexport</code>: export function from dll/executable (win32 only)
+
+</li></ul>
+
+<p>Here are some examples:
+</p><table><tr><td>&nbsp;</td><td><pre class="example">    int a __attribute__ ((aligned(8), section(&quot;.mysection&quot;)));
+</pre></td></tr></table>
+
+<p>align variable <code>a</code> to 8 bytes and put it in section <code>.mysection</code>.
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">    int my_add(int a, int b) __attribute__ ((section(&quot;.mycodesection&quot;))) 
+    {
+        return a + b;
+    }
+</pre></td></tr></table>
+
+<p>generate function <code>my_add</code> in section <code>.mycodesection</code>.
+</p>
+</li><li> GNU style variadic macros:
+<table><tr><td>&nbsp;</td><td><pre class="example">    #define dprintf(fmt, args&hellip;) printf(fmt, ## args)
+
+    dprintf(&quot;no arg\n&quot;);
+    dprintf(&quot;one arg %d\n&quot;, 1);
+</pre></td></tr></table>
+
+</li><li> <code>__FUNCTION__</code> is interpreted as C99 <code>__func__</code> 
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+
+</li><li> The <code>__alignof__</code> keyword can be used as <code>sizeof</code> 
+to get the alignment of a type or an expression.
+
+</li><li> The <code>typeof(x)</code> returns the type of <code>x</code>. 
+<code>x</code> is an expression or a type.
+
+</li><li> Computed gotos: <code>&amp;&amp;label</code> returns a pointer of type 
+<code>void *</code> on the goto label <code>label</code>. <code>goto *expr</code> can be
+used to jump on the pointer resulting from <code>expr</code>.
+
+</li><li> Inline assembly with asm instruction:
+<a name="IDX9"></a>
+<a name="IDX10"></a>
+<a name="IDX11"></a>
+<table><tr><td>&nbsp;</td><td><pre class="example">static inline void * my_memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+        &quot;rep ; movsl\n\t&quot;
+        &quot;testb $2,%b4\n\t&quot;
+        &quot;je 1f\n\t&quot;
+        &quot;movsw\n&quot;
+        &quot;1:\ttestb $1,%b4\n\t&quot;
+        &quot;je 2f\n\t&quot;
+        &quot;movsb\n&quot;
+        &quot;2:&quot;
+        : &quot;=&amp;c&quot; (d0), &quot;=&amp;D&quot; (d1), &quot;=&amp;S&quot; (d2)
+        :&quot;0&quot; (n/4), &quot;q&quot; (n),&quot;1&quot; ((long) to),&quot;2&quot; ((long) from)
+        : &quot;memory&quot;);
+return (to);
+}
+</pre></td></tr></table>
+
+<a name="IDX12"></a>
+<p>TCC includes its own x86 inline assembler with a <code>gas</code>-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+</p>
+</li><li> <code>__builtin_types_compatible_p()</code> and <code>__builtin_constant_p()</code> 
+are supported.
+
+</li><li> <code>#pragma pack</code> is supported for win32 compatibility.
+
+</li></ul>
+
+<hr size="6">
+<a name="SEC9"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC8" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 3.4 TinyCC extensions </h2>
+
+<ul class="toc">
+<li> <code>__TINYC__</code> is a predefined macro to <code>1</code> to
+indicate that you use TCC.
+
+</li><li> <code>#!</code> at the start of a line is ignored to allow scripting.
+
+</li><li> Binary digits can be entered (<code>0b101</code> instead of
+<code>5</code>).
+
+</li><li> <code>__BOUNDS_CHECKING_ON</code> is defined if bound checking is activated.
+
+</li></ul>
+
+<hr size="6">
+<a name="asm"></a>
+<a name="SEC10"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC9" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC11" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC5" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 4. TinyCC Assembler </h1>
+
+<p>Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+desactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+</p>
+<p>TinyCC Assembler is used to handle files with &lsquo;<tt>.S</tt>&rsquo; (C
+preprocessed assembler) and &lsquo;<tt>.s</tt>&rsquo; extensions. It is also used to
+handle the GNU inline assembler with the <code>asm</code> keyword.
+</p>
+<hr size="6">
+<a name="SEC11"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC10" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC12" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 4.1 Syntax </h2>
+
+<p>TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+</p>
+<ul class="toc">
+<li> C and C++ comments are supported.
+
+</li><li> Identifiers are the same as C, so you cannot use '.' or '$'.
+
+</li><li> Only 32 bit integer numbers are supported.
+
+</li></ul>
+
+<hr size="6">
+<a name="SEC12"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC11" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC13" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 4.2 Expressions </h2>
+
+<ul class="toc">
+<li> Integers in decimal, octal and hexa are supported.
+
+</li><li> Unary operators: +, -, ~.
+
+</li><li> Binary operators in decreasing priority order:
+
+<ol>
+<li> *, /, %
+</li><li> &amp;, |, ^
+</li><li> +, -
+</li></ol>
+
+</li><li> A value is either an absolute number or a label plus an offset. 
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+
+</li></ul>
+
+<hr size="6">
+<a name="SEC13"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC12" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC14" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 4.3 Labels </h2>
+
+<ul class="toc">
+<li> All labels are considered as local, except undefined ones.
+
+</li><li> Numeric labels can be used as local <code>gas</code>-like labels. 
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+
+<table><tr><td>&nbsp;</td><td><pre class="example"> 1:
+      jmp 1b /* jump to '1' label before */
+      jmp 1f /* jump to '1' label after */
+ 1:
+</pre></td></tr></table>
+
+</li></ul>
+
+<hr size="6">
+<a name="SEC14"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC13" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC15" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 4.4 Directives </h2>
+
+<p>All directives are preceeded by a '.'. The following directives are
+supported:
+</p>
+<ul class="toc">
+<li> .align n[,value]
+</li><li> .skip n[,value]
+</li><li> .space n[,value]
+</li><li> .byte value1[,...]
+</li><li> .word value1[,...]
+</li><li> .short value1[,...]
+</li><li> .int value1[,...]
+</li><li> .long value1[,...]
+</li><li> .quad immediate_value1[,...]
+</li><li> .globl symbol
+</li><li> .global symbol
+</li><li> .section section
+</li><li> .text
+</li><li> .data
+</li><li> .bss
+</li><li> .fill repeat[,size[,value]]
+</li><li> .org n
+</li><li> .previous
+</li><li> .string string[,...]
+</li><li> .asciz string[,...]
+</li><li> .ascii string[,...]
+</li></ul>
+
+<hr size="6">
+<a name="SEC15"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC14" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 4.5 X86 Assembler </h2>
+
+<p>All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+</p>
+<p>Currently, MMX opcodes are supported but not SSE ones.
+</p>
+<hr size="6">
+<a name="linker"></a>
+<a name="SEC16"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC15" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC17" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC10" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 5. TinyCC Linker </h1>
+
+<hr size="6">
+<a name="SEC17"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC16" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC18" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 5.1 ELF file generation </h2>
+
+<p>TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+</p>
+<p>Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+</p>
+<p>TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (&lsquo;<samp>--start-group</samp>&rsquo; and &lsquo;<samp>--end-group</samp>&rsquo;) are supported.
+</p>
+<hr size="6">
+<a name="SEC18"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC17" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC19" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 5.2 ELF file loader </h2>
+
+<p>TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+</p>
+<hr size="6">
+<a name="SEC19"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC18" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC20" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 5.3 PE-i386 file generation </h2>
+
+<p>TCC for Windows supports the native Win32 executable file format (PE-i386).  It
+generates EXE files (console and gui) and DLL files.
+</p>
+<p>For usage on Windows, see also tcc-win32.txt.
+</p>
+<hr size="6">
+<a name="SEC20"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC19" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 5.4 GNU Linker Scripts </h2>
+
+<p>Because on many Linux systems some dynamic libraries (such as
+&lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+</p>
+<p>The <code>GROUP</code> and <code>FILE</code> commands are supported. <code>OUTPUT_FORMAT</code>
+and <code>TARGET</code> are ignored.
+</p>
+<p>Example from &lsquo;<tt>/usr/lib/libc.so</tt>&rsquo;:
+</p><table><tr><td>&nbsp;</td><td><pre class="example">/* GNU ld script
+   Use the shared library, but some functions are only in
+   the static library, so try that secondarily.  */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+</pre></td></tr></table>
+
+<hr size="6">
+<a name="Bounds"></a>
+<a name="SEC21"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC20" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC22" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC16" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC22" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 6. TinyCC Memory and Bound checks </h1>
+
+<p>This feature is activated with the &lsquo;<samp>-b</samp>&rsquo; (see section <a href="#SEC2">Command line invocation</a>).
+</p>
+<p>Note that pointer size is <em>unchanged</em> and that code generated
+with bound checks is <em>fully compatible</em> with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+</p>
+<p>For more information about the ideas behind this method, see
+<a href="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</a>.
+</p>
+<p>Here are some examples of caught errors:
+</p>
+<dl compact="compact">
+<dt> Invalid range with standard string function:</dt>
+<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+    char tab[10];
+    memset(tab, 0, 11);
+}
+</pre></td></tr></table>
+
+</dd>
+<dt> Out of bounds-error in global or local arrays:</dt>
+<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+    int tab[10];
+    for(i=0;i&lt;11;i++) {
+        sum += tab[i];
+    }
+}
+</pre></td></tr></table>
+
+</dd>
+<dt> Out of bounds-error in malloc'ed data:</dt>
+<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    for(i=0;i&lt;21;i++) {
+        sum += tab4[i];
+    }
+    free(tab);
+}
+</pre></td></tr></table>
+
+</dd>
+<dt> Access of freed memory:</dt>
+<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    for(i=0;i&lt;20;i++) {
+        sum += tab4[i];
+    }
+}
+</pre></td></tr></table>
+
+</dd>
+<dt> Double free:</dt>
+<dd><table><tr><td>&nbsp;</td><td><pre class="example">{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    free(tab);
+}
+</pre></td></tr></table>
+
+</dd>
+</dl>
+
+<hr size="6">
+<a name="Libtcc"></a>
+<a name="SEC22"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC21" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC21" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 7. The <code>libtcc</code> library </h1>
+
+<p>The <code>libtcc</code> library enables you to use TCC as a backend for
+dynamic code generation. 
+</p>
+<p>Read the &lsquo;<tt>libtcc.h</tt>&rsquo; to have an overview of the API. Read
+&lsquo;<tt>libtcc_test.c</tt>&rsquo; to have a very simple example.
+</p>
+<p>The idea consists in giving a C string containing the program you want
+to compile directly to <code>libtcc</code>. Then you can access to any global
+symbol (function or variable) defined.
+</p>
+<hr size="6">
+<a name="devel"></a>
+<a name="SEC23"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC22" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC24" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC22" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="chapter"> 8. Developer's guide </h1>
+
+<p>This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+</p>
+<hr size="6">
+<a name="SEC24"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC23" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC25" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.1 File reading </h2>
+
+<p>The <code>BufferedFile</code> structure contains the context needed to read a
+file, including the current line number. <code>tcc_open()</code> opens a new
+file and <code>tcc_close()</code> closes it. <code>inp()</code> returns the next
+character.
+</p>
+<hr size="6">
+<a name="SEC25"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC24" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC26" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.2 Lexer </h2>
+
+<p><code>next()</code> reads the next token in the current
+file. <code>next_nomacro()</code> reads the next token without macro
+expansion.
+</p>
+<p><code>tok</code> contains the current token (see <code>TOK_xxx</code>)
+constants. Identifiers and keywords are also keywords. <code>tokc</code>
+contains additional infos about the token (for example a constant value
+if number or string token).
+</p>
+<hr size="6">
+<a name="SEC26"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC25" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC27" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.3 Parser </h2>
+
+<p>The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+</p>
+<ul class="toc">
+<li> For initialized arrays with unknown size, a first pass 
+is done to count the number of elements.
+
+</li><li> For architectures where arguments are evaluated in 
+reverse order, a first pass is done to reverse the argument order.
+
+</li></ul>
+
+<hr size="6">
+<a name="SEC27"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC26" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC28" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.4 Types </h2>
+
+<p>The types are stored in a single 'int' variable. It was choosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_INT        0  /* integer type */
+#define VT_BYTE       1  /* signed byte type */
+#define VT_SHORT      2  /* short type */
+#define VT_VOID       3  /* void type */
+#define VT_PTR        4  /* pointer */
+#define VT_ENUM       5  /* enum definition */
+#define VT_FUNC       6  /* function type */
+#define VT_STRUCT     7  /* struct/union definition */
+#define VT_FLOAT      8  /* IEEE float */
+#define VT_DOUBLE     9  /* IEEE double */
+#define VT_LDOUBLE   10  /* IEEE long double */
+#define VT_BOOL      11  /* ISOC99 boolean type */
+#define VT_LLONG     12  /* 64 bit integer */
+#define VT_LONG      13  /* long integer (NEVER USED as type, only
+                            during parsing) */
+#define VT_BTYPE      0x000f /* mask for basic type */
+#define VT_UNSIGNED   0x0010  /* unsigned type */
+#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
+#define VT_BITFIELD   0x0040  /* bitfield modifier */
+
+#define VT_STRUCT_SHIFT 16   /* structure/enum name shift (16 bits left) */
+</pre></td></tr></table>
+
+<p>When a reference to another type is needed (for pointers, functions and
+structures), the <code>32 - VT_STRUCT_SHIFT</code> high order bits are used to
+store an identifier reference.
+</p>
+<p>The <code>VT_UNSIGNED</code> flag can be set for chars, shorts, ints and long
+longs.
+</p>
+<p>Arrays are considered as pointers <code>VT_PTR</code> with the flag
+<code>VT_ARRAY</code> set.
+</p>
+<p>The <code>VT_BITFIELD</code> flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+</p>
+<p><code>VT_LONG</code> is never used except during parsing.
+</p>
+<p>During parsing, the storage of an object is also stored in the type
+integer:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_EXTERN  0x00000080  /* extern definition */
+#define VT_STATIC  0x00000100  /* static variable */
+#define VT_TYPEDEF 0x00000200  /* typedef definition */
+</pre></td></tr></table>
+
+<hr size="6">
+<a name="SEC28"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC27" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC29" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.5 Symbols </h2>
+
+<p>All symbols are stored in hashed symbol stacks. Each symbol stack
+contains <code>Sym</code> structures.
+</p>
+<p><code>Sym.v</code> contains the symbol name (remember
+an idenfier is also a token, so a string is never necessary to store
+it). <code>Sym.t</code> gives the type of the symbol. <code>Sym.r</code> is usually
+the register in which the corresponding variable is stored. <code>Sym.c</code> is
+usually a constant associated to the symbol.
+</p>
+<p>Four main symbol stacks are defined:
+</p>
+<dl compact="compact">
+<dt> <code>define_stack</code></dt>
+<dd><p>for the macros (<code>#define</code>s).
+</p>
+</dd>
+<dt> <code>global_stack</code></dt>
+<dd><p>for the global variables, functions and types.
+</p>
+</dd>
+<dt> <code>local_stack</code></dt>
+<dd><p>for the local variables, functions and types.
+</p>
+</dd>
+<dt> <code>global_label_stack</code></dt>
+<dd><p>for the local labels (for <code>goto</code>).
+</p>
+</dd>
+<dt> <code>label_stack</code></dt>
+<dd><p>for GCC block local labels (see the <code>__label__</code> keyword).
+</p>
+</dd>
+</dl>
+
+<p><code>sym_push()</code> is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+</p>
+<p><code>sym_pop(st,b)</code> pops symbols from the symbol stack <var>st</var> until
+the symbol <var>b</var> is on the top of stack. If <var>b</var> is NULL, the stack
+is emptied.
+</p>
+<p><code>sym_find(v)</code> return the symbol associated to the identifier
+<var>v</var>. The local stack is searched first from top to bottom, then the
+global stack.
+</p>
+<hr size="6">
+<a name="SEC29"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC28" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC30" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.6 Sections </h2>
+
+<p>The generated code and datas are written in sections. The structure
+<code>Section</code> contains all the necessary information for a given
+section. <code>new_section()</code> creates a new section. ELF file semantics
+is assumed for each section.
+</p>
+<p>The following sections are predefined:
+</p>
+<dl compact="compact">
+<dt> <code>text_section</code></dt>
+<dd><p>is the section containing the generated code. <var>ind</var> contains the
+current position in the code section.
+</p>
+</dd>
+<dt> <code>data_section</code></dt>
+<dd><p>contains initialized data
+</p>
+</dd>
+<dt> <code>bss_section</code></dt>
+<dd><p>contains uninitialized data
+</p>
+</dd>
+<dt> <code>bounds_section</code></dt>
+<dt> <code>lbounds_section</code></dt>
+<dd><p>are used when bound checking is activated
+</p>
+</dd>
+<dt> <code>stab_section</code></dt>
+<dt> <code>stabstr_section</code></dt>
+<dd><p>are used when debugging is actived to store debug information
+</p>
+</dd>
+<dt> <code>symtab_section</code></dt>
+<dt> <code>strtab_section</code></dt>
+<dd><p>contain the exported symbols (currently only used for debugging).
+</p>
+</dd>
+</dl>
+
+<hr size="6">
+<a name="SEC30"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC29" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC31" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.7 Code generation </h2>
+
+<hr size="6">
+<a name="SEC31"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC30" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC32" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h3 class="subsection"> 8.7.1 Introduction </h3>
+
+<p>The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+</p>
+<p>The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the <em>value stack</em>.
+</p>
+<p>On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+</p>
+<hr size="6">
+<a name="SEC32"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC31" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC33" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h3 class="subsection"> 8.7.2 The value stack </h3>
+
+<p>When an expression is parsed, its value is pushed on the value stack
+(<var>vstack</var>). The top of the value stack is <var>vtop</var>. Each value
+stack entry is the structure <code>SValue</code>.
+</p>
+<p><code>SValue.t</code> is the type. <code>SValue.r</code> indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (<code>REG_xxx</code> constants), but additional values and flags are
+defined:
+</p>
+<table><tr><td>&nbsp;</td><td><pre class="example">#define VT_CONST     0x00f0
+#define VT_LLOCAL    0x00f1
+#define VT_LOCAL     0x00f2
+#define VT_CMP       0x00f3
+#define VT_JMP       0x00f4
+#define VT_JMPI      0x00f5
+#define VT_LVAL      0x0100
+#define VT_SYM       0x0200
+#define VT_MUSTCAST  0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED   0x8000
+#define VT_LVAL_BYTE     0x1000
+#define VT_LVAL_SHORT    0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+</pre></td></tr></table>
+
+<dl compact="compact">
+<dt> <code>VT_CONST</code></dt>
+<dd><p>indicates that the value is a constant. It is stored in the union
+<code>SValue.c</code>, depending on its type.
+</p>
+</dd>
+<dt> <code>VT_LOCAL</code></dt>
+<dd><p>indicates a local variable pointer at offset <code>SValue.c.i</code> in the
+stack.
+</p>
+</dd>
+<dt> <code>VT_CMP</code></dt>
+<dd><p>indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in <code>SValue.c.i</code>. 
+</p>
+<p>If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+</p>
+</dd>
+<dt> <code>VT_JMP</code></dt>
+<dt> <code>VT_JMPI</code></dt>
+<dd><p>indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+</p>
+<p>These values are used to compile the <code>||</code> and <code>&amp;&amp;</code> logical
+operators.
+</p>
+<p>If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+</p>
+</dd>
+<dt> <code>VT_LVAL</code></dt>
+<dd><p>is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value. 
+</p>
+<p>Understanding the use <code>VT_LVAL</code> is very important if you want to
+understand how TCC works.
+</p>
+</dd>
+<dt> <code>VT_LVAL_BYTE</code></dt>
+<dt> <code>VT_LVAL_SHORT</code></dt>
+<dt> <code>VT_LVAL_UNSIGNED</code></dt>
+<dd><p>if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+</p>
+</dd>
+<dt> <code>VT_LLOCAL</code></dt>
+<dd><p>is a saved lvalue on the stack. <code>VT_LLOCAL</code> should be eliminated
+ASAP because its semantics are rather complicated.
+</p>
+</dd>
+<dt> <code>VT_MUSTCAST</code></dt>
+<dd><p>indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+</p>
+</dd>
+<dt> <code>VT_SYM</code></dt>
+<dd><p>indicates that the symbol <code>SValue.sym</code> must be added to the constant.
+</p>
+</dd>
+<dt> <code>VT_MUSTBOUND</code></dt>
+<dt> <code>VT_BOUNDED</code></dt>
+<dd><p>are only used for optional bound checking.
+</p>
+</dd>
+</dl>
+
+<hr size="6">
+<a name="SEC33"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC32" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC34" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h3 class="subsection"> 8.7.3 Manipulating the value stack </h3>
+
+<p><code>vsetc()</code> and <code>vset()</code> pushes a new value on the value
+stack. If the previous <var>vtop</var> was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous <var>vtop</var> in a safe storage.
+</p>
+<p><code>vpop()</code> pops <var>vtop</var>. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+</p>
+<p>The <code>gv(rc)</code> function generates code to evaluate <var>vtop</var> (the
+top value of the stack) into registers. <var>rc</var> selects in which
+register class the value should be put. <code>gv()</code> is the <em>most
+important function</em> of the code generator.
+</p>
+<p><code>gv2()</code> is the same as <code>gv()</code> but for the top two stack
+entries.
+</p>
+<hr size="6">
+<a name="SEC34"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC33" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC35" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC30" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h3 class="subsection"> 8.7.4 CPU dependent code generation </h3>
+<p>See the &lsquo;<tt>i386-gen.c</tt>&rsquo; file to have an example.
+</p>
+<dl compact="compact">
+<dt> <code>load()</code></dt>
+<dd><p>must generate the code needed to load a stack value into a register.
+</p>
+</dd>
+<dt> <code>store()</code></dt>
+<dd><p>must generate the code needed to store a register into a stack value
+lvalue.
+</p>
+</dd>
+<dt> <code>gfunc_start()</code></dt>
+<dt> <code>gfunc_param()</code></dt>
+<dt> <code>gfunc_call()</code></dt>
+<dd><p>should generate a function call
+</p>
+</dd>
+<dt> <code>gfunc_prolog()</code></dt>
+<dt> <code>gfunc_epilog()</code></dt>
+<dd><p>should generate a function prolog/epilog.
+</p>
+</dd>
+<dt> <code>gen_opi(op)</code></dt>
+<dd><p>must generate the binary integer operation <var>op</var> on the two top
+entries of the stack which are guaranted to contain integer types.
+</p>
+<p>The result value should be put on the stack.
+</p>
+</dd>
+<dt> <code>gen_opf(op)</code></dt>
+<dd><p>same as <code>gen_opi()</code> for floating point operations. The two top
+entries of the stack are guaranted to contain floating point values of
+same types.
+</p>
+</dd>
+<dt> <code>gen_cvt_itof()</code></dt>
+<dd><p>integer to floating point conversion.
+</p>
+</dd>
+<dt> <code>gen_cvt_ftoi()</code></dt>
+<dd><p>floating point to integer conversion.
+</p>
+</dd>
+<dt> <code>gen_cvt_ftof()</code></dt>
+<dd><p>floating point to floating point of different size conversion.
+</p>
+</dd>
+<dt> <code>gen_bounded_ptr_add()</code></dt>
+<dt> <code>gen_bounded_ptr_deref()</code></dt>
+<dd><p>are only used for bounds checking.
+</p>
+</dd>
+</dl>
+
+<hr size="6">
+<a name="SEC35"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC34" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next section in reading order"> &gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Next chapter"> &gt;&gt; </a>]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h2 class="section"> 8.8 Optimizations done </h2>
+<p>Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &amp;&amp;, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+</p>
+<hr size="6">
+<a name="SEC36"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC35" title="Previous section in reading order"> &lt; </a>]</td>
+<td valign="middle" align="left">[ &gt; ]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC23" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Up section"> Up </a>]</td>
+<td valign="middle" align="left">[ &gt;&gt; ]</td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left"> &nbsp; </td>
+<td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1 class="unnumbered"> Concept Index </h1>
+<table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#SEC36_0" class="summary-letter"><b>_</b></a>
+ &nbsp; 
+<br>
+<a href="#SEC36_1" class="summary-letter"><b>A</b></a>
+ &nbsp; 
+<a href="#SEC36_2" class="summary-letter"><b>B</b></a>
+ &nbsp; 
+<a href="#SEC36_3" class="summary-letter"><b>C</b></a>
+ &nbsp; 
+<a href="#SEC36_4" class="summary-letter"><b>D</b></a>
+ &nbsp; 
+<a href="#SEC36_5" class="summary-letter"><b>E</b></a>
+ &nbsp; 
+<a href="#SEC36_6" class="summary-letter"><b>F</b></a>
+ &nbsp; 
+<a href="#SEC36_7" class="summary-letter"><b>G</b></a>
+ &nbsp; 
+<a href="#SEC36_8" class="summary-letter"><b>I</b></a>
+ &nbsp; 
+<a href="#SEC36_9" class="summary-letter"><b>J</b></a>
+ &nbsp; 
+<a href="#SEC36_10" class="summary-letter"><b>L</b></a>
+ &nbsp; 
+<a href="#SEC36_11" class="summary-letter"><b>M</b></a>
+ &nbsp; 
+<a href="#SEC36_12" class="summary-letter"><b>O</b></a>
+ &nbsp; 
+<a href="#SEC36_13" class="summary-letter"><b>P</b></a>
+ &nbsp; 
+<a href="#SEC36_14" class="summary-letter"><b>Q</b></a>
+ &nbsp; 
+<a href="#SEC36_15" class="summary-letter"><b>R</b></a>
+ &nbsp; 
+<a href="#SEC36_16" class="summary-letter"><b>S</b></a>
+ &nbsp; 
+<a href="#SEC36_17" class="summary-letter"><b>T</b></a>
+ &nbsp; 
+<a href="#SEC36_18" class="summary-letter"><b>U</b></a>
+ &nbsp; 
+<a href="#SEC36_19" class="summary-letter"><b>V</b></a>
+ &nbsp; 
+<a href="#SEC36_20" class="summary-letter"><b>W</b></a>
+ &nbsp; 
+</td></tr></table>
+<table border="0" class="index-cp">
+<tr><td></td><th align="left">Index Entry</th><th align="left"> Section</th></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_0">_</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX11">__asm__</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_1">A</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">align directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX1">aligned attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">ascii directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">asciz directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC15">assembler</a></td><td valign="top"><a href="#SEC15">4.5 X86 Assembler</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">assembler directives</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX10">assembly, inline</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_2">B</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC21">bound checks</a></td><td valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">bss directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">byte directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_3">C</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">caching processor flags</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX5">cdecl attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC30">code generation</a></td><td valign="top"><a href="#SEC30">8.7 Code generation</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">comparison operators</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">constant propagation</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC34">CPU dependent</a></td><td valign="top"><a href="#SEC34">8.7.4 CPU dependent code generation</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_4">D</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">data directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">directives, assembler</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX8">dllexport attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_5">E</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC17">ELF</a></td><td valign="top"><a href="#SEC17">5.1 ELF file generation</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_6">F</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">FILE, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">fill directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">flags, caching</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_7">G</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX12">gas</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">global directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">globl directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">GROUP, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_8">I</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX9">inline assembly</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">int directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_9">J</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">jump optimization</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_10">L</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC16">linker</a></td><td valign="top"><a href="#SEC16">5. TinyCC Linker</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">linker scripts</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">long directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_11">M</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC21">memory checks</a></td><td valign="top"><a href="#SEC21">6. TinyCC Memory and Bound checks</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_12">O</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">optimizations</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">org directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">OUTPUT_FORMAT, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_13">P</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX2">packed attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC19">PE-i386</a></td><td valign="top"><a href="#SEC19">5.3 PE-i386 file generation</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">previous directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_14">Q</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">quad directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_15">R</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX7">regparm attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_16">S</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">scripts, linker</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX3">section attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">section directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">short directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">skip directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">space directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX6">stdcall attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC35">strength reduction</a></td><td valign="top"><a href="#SEC35">8.8 Optimizations done</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">string directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_17">T</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC20">TARGET, linker command</a></td><td valign="top"><a href="#SEC20">5.4 GNU Linker Scripts</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">text directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_18">U</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#IDX4">unused attribute</a></td><td valign="top"><a href="#SEC8">3.3 GNU C extensions</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_19">V</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC33">value stack</a></td><td valign="top"><a href="#SEC33">8.7.3 Manipulating the value stack</a></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC32">value stack, introduction</a></td><td valign="top"><a href="#SEC32">8.7.2 The value stack</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+<tr><th><a name="SEC36_20">W</a></th><td></td><td></td></tr>
+<tr><td></td><td valign="top"><a href="#SEC14">word directive</a></td><td valign="top"><a href="#SEC14">4.4 Directives</a></td></tr>
+<tr><td colspan="3"> <hr></td></tr>
+</table>
+<table><tr><th valign="top">Jump to: &nbsp; </th><td><a href="#SEC36_0" class="summary-letter"><b>_</b></a>
+ &nbsp; 
+<br>
+<a href="#SEC36_1" class="summary-letter"><b>A</b></a>
+ &nbsp; 
+<a href="#SEC36_2" class="summary-letter"><b>B</b></a>
+ &nbsp; 
+<a href="#SEC36_3" class="summary-letter"><b>C</b></a>
+ &nbsp; 
+<a href="#SEC36_4" class="summary-letter"><b>D</b></a>
+ &nbsp; 
+<a href="#SEC36_5" class="summary-letter"><b>E</b></a>
+ &nbsp; 
+<a href="#SEC36_6" class="summary-letter"><b>F</b></a>
+ &nbsp; 
+<a href="#SEC36_7" class="summary-letter"><b>G</b></a>
+ &nbsp; 
+<a href="#SEC36_8" class="summary-letter"><b>I</b></a>
+ &nbsp; 
+<a href="#SEC36_9" class="summary-letter"><b>J</b></a>
+ &nbsp; 
+<a href="#SEC36_10" class="summary-letter"><b>L</b></a>
+ &nbsp; 
+<a href="#SEC36_11" class="summary-letter"><b>M</b></a>
+ &nbsp; 
+<a href="#SEC36_12" class="summary-letter"><b>O</b></a>
+ &nbsp; 
+<a href="#SEC36_13" class="summary-letter"><b>P</b></a>
+ &nbsp; 
+<a href="#SEC36_14" class="summary-letter"><b>Q</b></a>
+ &nbsp; 
+<a href="#SEC36_15" class="summary-letter"><b>R</b></a>
+ &nbsp; 
+<a href="#SEC36_16" class="summary-letter"><b>S</b></a>
+ &nbsp; 
+<a href="#SEC36_17" class="summary-letter"><b>T</b></a>
+ &nbsp; 
+<a href="#SEC36_18" class="summary-letter"><b>U</b></a>
+ &nbsp; 
+<a href="#SEC36_19" class="summary-letter"><b>V</b></a>
+ &nbsp; 
+<a href="#SEC36_20" class="summary-letter"><b>W</b></a>
+ &nbsp; 
+</td></tr></table>
+
+<hr size="6">
+<a name="SEC_Contents"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1>Table of Contents</h1>
+<div class="contents">
+
+<ul class="toc">
+  <li><a name="TOC1" href="#SEC1">1. Introduction</a></li>
+  <li><a name="TOC2" href="#SEC2">2. Command line invocation</a>
+  <ul class="toc">
+    <li><a name="TOC3" href="#SEC3">2.1 Quick start</a></li>
+    <li><a name="TOC4" href="#SEC4">2.2 Option summary</a></li>
+  </ul></li>
+  <li><a name="TOC5" href="#SEC5">3. C language support</a>
+  <ul class="toc">
+    <li><a name="TOC6" href="#SEC6">3.1 ANSI C</a></li>
+    <li><a name="TOC7" href="#SEC7">3.2 ISOC99 extensions</a></li>
+    <li><a name="TOC8" href="#SEC8">3.3 GNU C extensions</a></li>
+    <li><a name="TOC9" href="#SEC9">3.4 TinyCC extensions</a></li>
+  </ul></li>
+  <li><a name="TOC10" href="#SEC10">4. TinyCC Assembler</a>
+  <ul class="toc">
+    <li><a name="TOC11" href="#SEC11">4.1 Syntax</a></li>
+    <li><a name="TOC12" href="#SEC12">4.2 Expressions</a></li>
+    <li><a name="TOC13" href="#SEC13">4.3 Labels</a></li>
+    <li><a name="TOC14" href="#SEC14">4.4 Directives</a></li>
+    <li><a name="TOC15" href="#SEC15">4.5 X86 Assembler</a></li>
+  </ul></li>
+  <li><a name="TOC16" href="#SEC16">5. TinyCC Linker</a>
+  <ul class="toc">
+    <li><a name="TOC17" href="#SEC17">5.1 ELF file generation</a></li>
+    <li><a name="TOC18" href="#SEC18">5.2 ELF file loader</a></li>
+    <li><a name="TOC19" href="#SEC19">5.3 PE-i386 file generation</a></li>
+    <li><a name="TOC20" href="#SEC20">5.4 GNU Linker Scripts</a></li>
+  </ul></li>
+  <li><a name="TOC21" href="#SEC21">6. TinyCC Memory and Bound checks</a></li>
+  <li><a name="TOC22" href="#SEC22">7. The <code>libtcc</code> library</a></li>
+  <li><a name="TOC23" href="#SEC23">8. Developer's guide</a>
+  <ul class="toc">
+    <li><a name="TOC24" href="#SEC24">8.1 File reading</a></li>
+    <li><a name="TOC25" href="#SEC25">8.2 Lexer</a></li>
+    <li><a name="TOC26" href="#SEC26">8.3 Parser</a></li>
+    <li><a name="TOC27" href="#SEC27">8.4 Types</a></li>
+    <li><a name="TOC28" href="#SEC28">8.5 Symbols</a></li>
+    <li><a name="TOC29" href="#SEC29">8.6 Sections</a></li>
+    <li><a name="TOC30" href="#SEC30">8.7 Code generation</a>
+    <ul class="toc">
+      <li><a name="TOC31" href="#SEC31">8.7.1 Introduction</a></li>
+      <li><a name="TOC32" href="#SEC32">8.7.2 The value stack</a></li>
+      <li><a name="TOC33" href="#SEC33">8.7.3 Manipulating the value stack</a></li>
+      <li><a name="TOC34" href="#SEC34">8.7.4 CPU dependent code generation</a></li>
+    </ul></li>
+    <li><a name="TOC35" href="#SEC35">8.8 Optimizations done</a></li>
+  </ul></li>
+  <li><a name="TOC36" href="#SEC36">Concept Index</a></li>
+</ul>
+</div>
+<hr size="1">
+<a name="SEC_About"></a>
+<table cellpadding="1" cellspacing="1" border="0">
+<tr><td valign="middle" align="left">[<a href="#SEC_Top" title="Cover (top) of document">Top</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_Contents" title="Table of contents">Contents</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC36" title="Index">Index</a>]</td>
+<td valign="middle" align="left">[<a href="#SEC_About" title="About (help)"> ? </a>]</td>
+</tr></table>
+<h1>About This Document</h1>
+<p>
+  This document was generated by <em>gr</em> on <em>May, 18 2009</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.78</em></a>.
+</p>
+<p>
+  The buttons in the navigation panels have the following meaning:
+</p>
+<table border="1">
+  <tr>
+    <th> Button </th>
+    <th> Name </th>
+    <th> Go to </th>
+    <th> From 1.2.3 go to</th>
+  </tr>
+  <tr>
+    <td align="center"> [ &lt; ] </td>
+    <td align="center">Back</td>
+    <td>Previous section in reading order</td>
+    <td>1.2.2</td>
+  </tr>
+  <tr>
+    <td align="center"> [ &gt; ] </td>
+    <td align="center">Forward</td>
+    <td>Next section in reading order</td>
+    <td>1.2.4</td>
+  </tr>
+  <tr>
+    <td align="center"> [ &lt;&lt; ] </td>
+    <td align="center">FastBack</td>
+    <td>Beginning of this chapter or previous chapter</td>
+    <td>1</td>
+  </tr>
+  <tr>
+    <td align="center"> [ Up ] </td>
+    <td align="center">Up</td>
+    <td>Up section</td>
+    <td>1.2</td>
+  </tr>
+  <tr>
+    <td align="center"> [ &gt;&gt; ] </td>
+    <td align="center">FastForward</td>
+    <td>Next chapter</td>
+    <td>2</td>
+  </tr>
+  <tr>
+    <td align="center"> [Top] </td>
+    <td align="center">Top</td>
+    <td>Cover (top) of document</td>
+    <td> &nbsp; </td>
+  </tr>
+  <tr>
+    <td align="center"> [Contents] </td>
+    <td align="center">Contents</td>
+    <td>Table of contents</td>
+    <td> &nbsp; </td>
+  </tr>
+  <tr>
+    <td align="center"> [Index] </td>
+    <td align="center">Index</td>
+    <td>Index</td>
+    <td> &nbsp; </td>
+  </tr>
+  <tr>
+    <td align="center"> [ ? ] </td>
+    <td align="center">About</td>
+    <td>About (help)</td>
+    <td> &nbsp; </td>
+  </tr>
+</table>
+
+<p>
+  where the <strong> Example </strong> assumes that the current position is at <strong> Subsubsection One-Two-Three </strong> of a document of the following structure:
+</p>
+
+<ul>
+  <li> 1. Section One
+    <ul>
+      <li>1.1 Subsection One-One
+        <ul>
+          <li>...</li>
+        </ul>
+      </li>
+      <li>1.2 Subsection One-Two
+        <ul>
+          <li>1.2.1 Subsubsection One-Two-One</li>
+          <li>1.2.2 Subsubsection One-Two-Two</li>
+          <li>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp;
+            <strong>&lt;== Current Position </strong></li>
+          <li>1.2.4 Subsubsection One-Two-Four</li>
+        </ul>
+      </li>
+      <li>1.3 Subsection One-Three
+        <ul>
+          <li>...</li>
+        </ul>
+      </li>
+      <li>1.4 Subsection One-Four</li>
+    </ul>
+  </li>
+</ul>
+
+<hr size="1">
+<p>
+ <font size="-1">
+  This document was generated by <em>gr</em> on <em>May, 18 2009</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.78</em></a>.
+ </font>
+ <br>
+
+</p>
+</body>
+</html>
diff --git a/tinyc/tcc-doc.texi b/tinyc/tcc-doc.texi
new file mode 100755
index 000000000..7cc61bbdb
--- /dev/null
+++ b/tinyc/tcc-doc.texi
@@ -0,0 +1,1227 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@setfilename tcc-doc.info
+@settitle Tiny C Compiler Reference Documentation
+@c %**end of header
+
+@include config.texi
+
+@iftex
+@titlepage
+@afourpaper
+@sp 7
+@center @titlefont{Tiny C Compiler Reference Documentation}
+@sp 3
+@end titlepage
+@headings double
+@end iftex
+
+@contents
+
+@node Top, Introduction, (dir), (dir)
+@top Tiny C Compiler Reference Documentation
+
+This manual documents version @value{VERSION} of the Tiny C Compiler.
+
+@menu
+* Introduction::                Introduction to tcc.
+* Invoke::                      Invocation of tcc (command line, options).
+* Clang::                       ANSI C and extensions.
+* asm::                         Assembler syntax.
+* linker::                      Output file generation and supported targets.
+* Bounds::                      Automatic bounds-checking of C code.
+* Libtcc::                      The libtcc library.
+* devel::                       Guide for Developers.
+@end menu
+
+
+@node Introduction
+@chapter Introduction
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+
+TCC compiles so @emph{fast} that even for big projects @code{Makefile}s may
+not be necessary.
+
+TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+
+TCC can also be used to make @emph{C scripts}, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+
+TCC can also automatically generate memory and bound checks
+(@pxref{Bounds}) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+
+With @code{libtcc}, you can use TCC as a backend for dynamic code
+generation (@pxref{Libtcc}).
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (@code{arm-tcc}) and the TMS320C67xx targets
+(@code{c67-tcc}). More information about the ARM port is available at
+@url{http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html}.
+
+For usage on Windows, see also tcc-win32.txt.
+
+@node Invoke
+@chapter Command line invocation
+
+@section Quick start
+
+@example
+@c man begin SYNOPSIS
+usage: tcc [options] [@var{infile1} @var{infile2}@dots{}] [@option{-run} @var{infile} @var{args}@dots{}]
+@c man end
+@end example
+
+@noindent
+@c man begin DESCRIPTION
+TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+
+Here are some examples to understand the logic:
+
+@table @code
+@item @samp{tcc -run a.c}
+Compile @file{a.c} and execute it directly
+
+@item @samp{tcc -run a.c arg1}
+Compile a.c and execute it directly. arg1 is given as first argument to
+the @code{main()} of a.c.
+
+@item @samp{tcc a.c -run b.c arg1}
+Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
+as first argument to the @code{main()} of the resulting program. 
+@ignore 
+Because multiple C files are specified, @option{--} are necessary to clearly 
+separate the program arguments from the TCC options.
+@end ignore
+
+@item @samp{tcc -o myprog a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them and generate the executable @file{myprog}.
+
+@item @samp{tcc -o myprog a.o b.o}
+link @file{a.o} and @file{b.o} together and generate the executable @file{myprog}.
+
+@item @samp{tcc -c a.c}
+Compile @file{a.c} and generate object file @file{a.o}.
+
+@item @samp{tcc -c asmfile.S}
+Preprocess with C preprocess and assemble @file{asmfile.S} and generate
+object file @file{asmfile.o}.
+
+@item @samp{tcc -c asmfile.s}
+Assemble (but not preprocess) @file{asmfile.s} and generate object file
+@file{asmfile.o}.
+
+@item @samp{tcc -r -o ab.o a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them together and generate the object file @file{ab.o}.
+
+@end table
+
+Scripting:
+
+TCC can be invoked from @emph{scripts}, just as shell scripts. You just
+need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
+
+@example
+#!/usr/local/bin/tcc -run
+#include <stdio.h>
+
+int main() 
+@{
+    printf("Hello World\n");
+    return 0;
+@}
+@end example
+
+TCC can read C source code from @emph{standard input} when @option{-} is used in 
+place of @option{infile}. Example:
+
+@example
+echo 'main()@{puts("hello");@}' | tcc -run -
+@end example
+@c man end
+
+@section Option summary
+
+General Options:
+
+@c man begin OPTIONS
+@table @option
+@item -v
+Display current TCC version, increase verbosity.
+
+@item -c
+Generate an object file (@option{-o} option must also be given).
+
+@item -o outfile
+Put object file, executable, or dll into output file @file{outfile}.
+
+@item -Bdir
+Set the path where the tcc internal libraries can be found (default is
+@file{PREFIX/lib/tcc}).
+
+@item -bench
+Output compilation statistics.
+
+@item -run source [args...]
+Compile file @var{source} and run it with the command line arguments
+@var{args}. In order to be able to give more than one argument to a
+script, several TCC options can be given @emph{after} the
+@option{-run} option, separated by spaces. Example:
+
+@example
+tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+@end example
+
+In a script, it gives the following header:
+
+@example
+#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+#include <stdlib.h>
+int main(int argc, char **argv)
+@{
+    ...
+@}
+@end example
+
+@end table
+
+Preprocessor options:
+
+@table @option
+@item -Idir
+Specify an additional include path. Include paths are searched in the
+order they are specified.
+
+System include paths are always searched after. The default system
+include paths are: @file{/usr/local/include}, @file{/usr/include}
+and @file{PREFIX/lib/tcc/include}. (@file{PREFIX} is usually
+@file{/usr} or @file{/usr/local}).
+
+@item -Dsym[=val]
+Define preprocessor symbol @samp{sym} to
+val. If val is not present, its value is @samp{1}. Function-like macros can
+also be defined: @option{-DF(a)=a+1}
+
+@item -Usym
+Undefine preprocessor symbol @samp{sym}.
+@end table
+
+Compilation flags:
+
+Note: each of the following warning options has a negative form beginning with
+@option{-fno-}.
+
+@table @option
+@item -funsigned-char
+Let the @code{char} type be unsigned.
+
+@item -fsigned-char
+Let the @code{char} type be signed.
+
+@item -fno-common
+Do not generate common symbols for uninitialized data.
+
+@item -fleading-underscore
+Add a leading underscore at the beginning of each C symbol.
+
+@end table
+
+Warning options:
+
+@table @option
+@item -w
+Disable all warnings.
+
+@end table
+
+Note: each of the following warning options has a negative form beginning with
+@option{-Wno-}.
+
+@table @option
+@item -Wimplicit-function-declaration
+Warn about implicit function declaration.
+
+@item -Wunsupported
+Warn about unsupported GCC features that are ignored by TCC.
+
+@item -Wwrite-strings
+Make string constants be of type @code{const char *} instead of @code{char
+*}.
+
+@item -Werror
+Abort compilation if warnings are issued.
+
+@item -Wall 
+Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
+@option{-Wwrite-strings}.
+
+@end table
+
+Linker options:
+
+@table @option
+@item -Ldir
+Specify an additional static library path for the @option{-l} option. The
+default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib}.
+
+@item -lxxx
+Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+@option{-L} option.
+
+@item -shared
+Generate a shared library instead of an executable (@option{-o} option
+must also be given).
+
+@item -static
+Generate a statically linked executable (default is a shared linked
+executable) (@option{-o} option must also be given).
+
+@item -rdynamic
+Export global symbols to the dynamic linker. It is useful when a library
+opened with @code{dlopen()} needs to access executable symbols.
+
+@item -r
+Generate an object file combining all input files (@option{-o} option must
+also be given).
+
+@item -Wl,-Ttext,address
+Set the start of the .text section to @var{address}.
+
+@item -Wl,--oformat,fmt
+Use @var{fmt} as output format. The supported output formats are:
+@table @code
+@item elf32-i386
+ELF output format (default)
+@item binary
+Binary image (only for executable output)
+@item coff
+COFF output format (only for executable output for TMS320C67xx target)
+@end table
+
+@end table
+
+Debugger options:
+
+@table @option
+@item -g
+Generate run time debug information so that you get clear run time
+error messages: @code{ test.c:68: in function 'test5()': dereferencing
+invalid pointer} instead of the laconic @code{Segmentation
+fault}.
+
+@item -b
+Generate additional support code to check
+memory allocations and array/pointer bounds. @option{-g} is implied. Note
+that the generated code is slower and bigger in this case.
+
+@item -bt N
+Display N callers in stack traces. This is useful with @option{-g} or
+@option{-b}.
+
+@end table
+
+Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are
+ignored.
+@c man end
+
+@ignore
+
+@setfilename tcc
+@settitle Tiny C Compiler
+
+@c man begin SEEALSO
+gcc(1)
+@c man end
+
+@c man begin AUTHOR
+Fabrice Bellard
+@c man end
+
+@end ignore
+
+@node Clang
+@chapter C language support
+
+@section ANSI C
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (@code{long double}, @code{double}, and
+@code{float} fully supported).
+
+@section ISOC99 extensions
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers and variable length
+arrays.
+
+Currently implemented ISOC99 features:
+
+@itemize
+
+@item 64 bit @code{long long} types are fully supported.
+
+@item The boolean type @code{_Bool} is supported.
+
+@item @code{__func__} is a string variable containing the current
+function name.
+
+@item Variadic macros: @code{__VA_ARGS__} can be used for
+   function-like macros:
+@example
+    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+@end example
+
+@noindent
+@code{dprintf} can then be used with a variable number of parameters.
+
+@item Declarations can appear anywhere in a block (as in C++).
+
+@item Array and struct/union elements can be initialized in any order by
+  using designators:
+@example
+    struct @{ int x, y; @} st[10] = @{ [0].x = 1, [0].y = 2 @};
+
+    int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
+@end example
+    
+@item Compound initializers are supported:
+@example
+    int *p = (int [])@{ 1, 2, 3 @};
+@end example
+to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+
+@item Hexadecimal floating point constants are supported:
+@example
+          double d = 0x1234p10;
+@end example
+
+@noindent
+is the same as writing 
+@example
+          double d = 4771840.0;
+@end example
+
+@item @code{inline} keyword is ignored.
+
+@item @code{restrict} keyword is ignored.
+@end itemize
+
+@section GNU C extensions
+
+TCC implements some GNU C extensions:
+
+@itemize
+
+@item array designators can be used without '=': 
+@example
+    int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
+@end example
+
+@item Structure field designators can be a label: 
+@example
+    struct @{ int x, y; @} st = @{ x: 1, y: 1@};
+@end example
+instead of
+@example
+    struct @{ int x, y; @} st = @{ .x = 1, .y = 1@};
+@end example
+
+@item @code{\e} is ASCII character 27.
+
+@item case ranges : ranges can be used in @code{case}s:
+@example
+    switch(a) @{
+    case 1 @dots{} 9:
+          printf("range 1 to 9\n");
+          break;
+    default:
+          printf("unexpected\n");
+          break;
+    @}
+@end example
+
+@cindex aligned attribute
+@cindex packed attribute
+@cindex section attribute
+@cindex unused attribute
+@cindex cdecl attribute
+@cindex stdcall attribute
+@cindex regparm attribute
+@cindex dllexport attribute
+
+@item The keyword @code{__attribute__} is handled to specify variable or
+function attributes. The following attributes are supported:
+  @itemize
+
+  @item @code{aligned(n)}: align a variable or a structure field to n bytes
+(must be a power of two).
+
+  @item @code{packed}: force alignment of a variable or a structure field to
+  1.
+
+  @item @code{section(name)}: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+
+  @item @code{unused}: specify that the variable or the function is unused.
+
+  @item @code{cdecl}: use standard C calling convention (default).
+
+  @item @code{stdcall}: use Pascal-like calling convention.
+
+  @item @code{regparm(n)}: use fast i386 calling convention. @var{n} must be
+between 1 and 3. The first @var{n} function parameters are respectively put in
+registers @code{%eax}, @code{%edx} and @code{%ecx}.
+
+  @item @code{dllexport}: export function from dll/executable (win32 only)
+
+  @end itemize
+
+Here are some examples:
+@example
+    int a __attribute__ ((aligned(8), section(".mysection")));
+@end example
+
+@noindent
+align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
+
+@example
+    int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) 
+    @{
+        return a + b;
+    @}
+@end example
+
+@noindent
+generate function @code{my_add} in section @code{.mycodesection}.
+
+@item GNU style variadic macros:
+@example
+    #define dprintf(fmt, args@dots{}) printf(fmt, ## args)
+
+    dprintf("no arg\n");
+    dprintf("one arg %d\n", 1);
+@end example
+
+@item @code{__FUNCTION__} is interpreted as C99 @code{__func__} 
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+
+@item The @code{__alignof__} keyword can be used as @code{sizeof} 
+to get the alignment of a type or an expression.
+
+@item The @code{typeof(x)} returns the type of @code{x}. 
+@code{x} is an expression or a type.
+
+@item Computed gotos: @code{&&label} returns a pointer of type 
+@code{void *} on the goto label @code{label}. @code{goto *expr} can be
+used to jump on the pointer resulting from @code{expr}.
+
+@item Inline assembly with asm instruction:
+@cindex inline assembly
+@cindex assembly, inline
+@cindex __asm__
+@example
+static inline void * my_memcpy(void * to, const void * from, size_t n)
+@{
+int d0, d1, d2;
+__asm__ __volatile__(
+        "rep ; movsl\n\t"
+        "testb $2,%b4\n\t"
+        "je 1f\n\t"
+        "movsw\n"
+        "1:\ttestb $1,%b4\n\t"
+        "je 2f\n\t"
+        "movsb\n"
+        "2:"
+        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+        :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+        : "memory");
+return (to);
+@}
+@end example
+
+@noindent
+@cindex gas
+TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+
+@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()} 
+are supported.
+
+@item @code{#pragma pack} is supported for win32 compatibility.
+
+@end itemize
+
+@section TinyCC extensions
+
+@itemize
+
+@item @code{__TINYC__} is a predefined macro to @code{1} to
+indicate that you use TCC.
+
+@item @code{#!} at the start of a line is ignored to allow scripting.
+
+@item Binary digits can be entered (@code{0b101} instead of
+@code{5}).
+
+@item @code{__BOUNDS_CHECKING_ON} is defined if bound checking is activated.
+
+@end itemize
+
+@node asm
+@chapter TinyCC Assembler
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+desactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+
+TinyCC Assembler is used to handle files with @file{.S} (C
+preprocessed assembler) and @file{.s} extensions. It is also used to
+handle the GNU inline assembler with the @code{asm} keyword.
+
+@section Syntax
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+
+@itemize
+
+@item C and C++ comments are supported.
+
+@item Identifiers are the same as C, so you cannot use '.' or '$'.
+
+@item Only 32 bit integer numbers are supported.
+
+@end itemize
+
+@section Expressions
+
+@itemize
+
+@item Integers in decimal, octal and hexa are supported.
+
+@item Unary operators: +, -, ~.
+
+@item Binary operators in decreasing priority order:
+
+@enumerate
+@item *, /, %
+@item &, |, ^
+@item +, -
+@end enumerate
+
+@item A value is either an absolute number or a label plus an offset. 
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+
+@end itemize
+
+@section Labels
+
+@itemize
+
+@item All labels are considered as local, except undefined ones.
+
+@item Numeric labels can be used as local @code{gas}-like labels. 
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+
+@example
+ 1:
+      jmp 1b /* jump to '1' label before */
+      jmp 1f /* jump to '1' label after */
+ 1:
+@end example
+
+@end itemize
+
+@section Directives
+@cindex assembler directives
+@cindex directives, assembler
+@cindex align directive
+@cindex skip directive
+@cindex space directive
+@cindex byte directive
+@cindex word directive
+@cindex short directive
+@cindex int directive
+@cindex long directive
+@cindex quad directive
+@cindex globl directive
+@cindex global directive
+@cindex section directive
+@cindex text directive
+@cindex data directive
+@cindex bss directive
+@cindex fill directive
+@cindex org directive
+@cindex previous directive
+@cindex string directive
+@cindex asciz directive
+@cindex ascii directive
+
+All directives are preceeded by a '.'. The following directives are
+supported:
+
+@itemize
+@item .align n[,value]
+@item .skip n[,value]
+@item .space n[,value]
+@item .byte value1[,...]
+@item .word value1[,...]
+@item .short value1[,...]
+@item .int value1[,...]
+@item .long value1[,...]
+@item .quad immediate_value1[,...]
+@item .globl symbol
+@item .global symbol
+@item .section section
+@item .text
+@item .data
+@item .bss
+@item .fill repeat[,size[,value]]
+@item .org n
+@item .previous
+@item .string string[,...]
+@item .asciz string[,...]
+@item .ascii string[,...]
+@end itemize
+
+@section X86 Assembler
+@cindex assembler
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+
+Currently, MMX opcodes are supported but not SSE ones.
+
+@node linker
+@chapter TinyCC Linker
+@cindex linker
+
+@section ELF file generation
+@cindex ELF
+
+TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+
+Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (@option{--start-group} and @option{--end-group}) are supported.
+
+@section ELF file loader
+
+TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+
+@section PE-i386 file generation
+@cindex PE-i386
+
+TCC for Windows supports the native Win32 executable file format (PE-i386).  It
+generates EXE files (console and gui) and DLL files.
+
+For usage on Windows, see also tcc-win32.txt.
+
+@section GNU Linker Scripts
+@cindex scripts, linker
+@cindex linker scripts
+@cindex GROUP, linker command
+@cindex FILE, linker command
+@cindex OUTPUT_FORMAT, linker command
+@cindex TARGET, linker command
+
+Because on many Linux systems some dynamic libraries (such as
+@file{/usr/lib/libc.so}) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+
+The @code{GROUP} and @code{FILE} commands are supported. @code{OUTPUT_FORMAT}
+and @code{TARGET} are ignored.
+
+Example from @file{/usr/lib/libc.so}:
+@example
+/* GNU ld script
+   Use the shared library, but some functions are only in
+   the static library, so try that secondarily.  */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+@end example
+
+@node Bounds
+@chapter TinyCC Memory and Bound checks
+@cindex bound checks
+@cindex memory checks
+
+This feature is activated with the @option{-b} (@pxref{Invoke}).
+
+Note that pointer size is @emph{unchanged} and that code generated
+with bound checks is @emph{fully compatible} with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+
+For more information about the ideas behind this method, see
+@url{http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html}.
+
+Here are some examples of caught errors:
+
+@table @asis
+
+@item Invalid range with standard string function:
+@example
+@{
+    char tab[10];
+    memset(tab, 0, 11);
+@}
+@end example
+
+@item Out of bounds-error in global or local arrays:
+@example
+@{
+    int tab[10];
+    for(i=0;i<11;i++) @{
+        sum += tab[i];
+    @}
+@}
+@end example
+
+@item Out of bounds-error in malloc'ed data:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    for(i=0;i<21;i++) @{
+        sum += tab4[i];
+    @}
+    free(tab);
+@}
+@end example
+
+@item Access of freed memory:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    for(i=0;i<20;i++) @{
+        sum += tab4[i];
+    @}
+@}
+@end example
+
+@item Double free:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    free(tab);
+@}
+@end example
+
+@end table
+
+@node Libtcc
+@chapter The @code{libtcc} library
+
+The @code{libtcc} library enables you to use TCC as a backend for
+dynamic code generation. 
+
+Read the @file{libtcc.h} to have an overview of the API. Read
+@file{libtcc_test.c} to have a very simple example.
+
+The idea consists in giving a C string containing the program you want
+to compile directly to @code{libtcc}. Then you can access to any global
+symbol (function or variable) defined.
+
+@node devel
+@chapter Developer's guide
+
+This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+
+@section File reading
+
+The @code{BufferedFile} structure contains the context needed to read a
+file, including the current line number. @code{tcc_open()} opens a new
+file and @code{tcc_close()} closes it. @code{inp()} returns the next
+character.
+
+@section Lexer
+
+@code{next()} reads the next token in the current
+file. @code{next_nomacro()} reads the next token without macro
+expansion.
+
+@code{tok} contains the current token (see @code{TOK_xxx})
+constants. Identifiers and keywords are also keywords. @code{tokc}
+contains additional infos about the token (for example a constant value
+if number or string token).
+
+@section Parser
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+
+@itemize
+
+@item For initialized arrays with unknown size, a first pass 
+is done to count the number of elements.
+
+@item For architectures where arguments are evaluated in 
+reverse order, a first pass is done to reverse the argument order.
+
+@end itemize
+
+@section Types
+
+The types are stored in a single 'int' variable. It was choosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+
+@example
+#define VT_INT        0  /* integer type */
+#define VT_BYTE       1  /* signed byte type */
+#define VT_SHORT      2  /* short type */
+#define VT_VOID       3  /* void type */
+#define VT_PTR        4  /* pointer */
+#define VT_ENUM       5  /* enum definition */
+#define VT_FUNC       6  /* function type */
+#define VT_STRUCT     7  /* struct/union definition */
+#define VT_FLOAT      8  /* IEEE float */
+#define VT_DOUBLE     9  /* IEEE double */
+#define VT_LDOUBLE   10  /* IEEE long double */
+#define VT_BOOL      11  /* ISOC99 boolean type */
+#define VT_LLONG     12  /* 64 bit integer */
+#define VT_LONG      13  /* long integer (NEVER USED as type, only
+                            during parsing) */
+#define VT_BTYPE      0x000f /* mask for basic type */
+#define VT_UNSIGNED   0x0010  /* unsigned type */
+#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
+#define VT_BITFIELD   0x0040  /* bitfield modifier */
+
+#define VT_STRUCT_SHIFT 16   /* structure/enum name shift (16 bits left) */
+@end example
+
+When a reference to another type is needed (for pointers, functions and
+structures), the @code{32 - VT_STRUCT_SHIFT} high order bits are used to
+store an identifier reference.
+
+The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long
+longs.
+
+Arrays are considered as pointers @code{VT_PTR} with the flag
+@code{VT_ARRAY} set.
+
+The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+
+@code{VT_LONG} is never used except during parsing.
+
+During parsing, the storage of an object is also stored in the type
+integer:
+
+@example
+#define VT_EXTERN  0x00000080  /* extern definition */
+#define VT_STATIC  0x00000100  /* static variable */
+#define VT_TYPEDEF 0x00000200  /* typedef definition */
+@end example
+
+@section Symbols
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains @code{Sym} structures.
+
+@code{Sym.v} contains the symbol name (remember
+an idenfier is also a token, so a string is never necessary to store
+it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
+the register in which the corresponding variable is stored. @code{Sym.c} is
+usually a constant associated to the symbol.
+
+Four main symbol stacks are defined:
+
+@table @code
+
+@item define_stack
+for the macros (@code{#define}s).
+
+@item global_stack
+for the global variables, functions and types.
+
+@item local_stack
+for the local variables, functions and types.
+
+@item global_label_stack
+for the local labels (for @code{goto}).
+
+@item label_stack
+for GCC block local labels (see the @code{__label__} keyword).
+
+@end table
+
+@code{sym_push()} is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+
+@code{sym_pop(st,b)} pops symbols from the symbol stack @var{st} until
+the symbol @var{b} is on the top of stack. If @var{b} is NULL, the stack
+is emptied.
+
+@code{sym_find(v)} return the symbol associated to the identifier
+@var{v}. The local stack is searched first from top to bottom, then the
+global stack.
+
+@section Sections
+
+The generated code and datas are written in sections. The structure
+@code{Section} contains all the necessary information for a given
+section. @code{new_section()} creates a new section. ELF file semantics
+is assumed for each section.
+
+The following sections are predefined:
+
+@table @code
+
+@item text_section
+is the section containing the generated code. @var{ind} contains the
+current position in the code section.
+
+@item data_section
+contains initialized data
+
+@item bss_section
+contains uninitialized data
+
+@item bounds_section
+@itemx lbounds_section
+are used when bound checking is activated
+
+@item stab_section
+@itemx stabstr_section
+are used when debugging is actived to store debug information
+
+@item symtab_section
+@itemx strtab_section
+contain the exported symbols (currently only used for debugging).
+
+@end table
+
+@section Code generation
+@cindex code generation
+
+@subsection Introduction
+
+The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+
+The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the @emph{value stack}.
+
+On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+
+@subsection The value stack
+@cindex value stack, introduction
+
+When an expression is parsed, its value is pushed on the value stack
+(@var{vstack}). The top of the value stack is @var{vtop}. Each value
+stack entry is the structure @code{SValue}.
+
+@code{SValue.t} is the type. @code{SValue.r} indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (@code{REG_xxx} constants), but additional values and flags are
+defined:
+
+@example
+#define VT_CONST     0x00f0
+#define VT_LLOCAL    0x00f1
+#define VT_LOCAL     0x00f2
+#define VT_CMP       0x00f3
+#define VT_JMP       0x00f4
+#define VT_JMPI      0x00f5
+#define VT_LVAL      0x0100
+#define VT_SYM       0x0200
+#define VT_MUSTCAST  0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED   0x8000
+#define VT_LVAL_BYTE     0x1000
+#define VT_LVAL_SHORT    0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+@end example
+
+@table @code
+
+@item VT_CONST
+indicates that the value is a constant. It is stored in the union
+@code{SValue.c}, depending on its type.
+
+@item VT_LOCAL
+indicates a local variable pointer at offset @code{SValue.c.i} in the
+stack.
+
+@item VT_CMP
+indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in @code{SValue.c.i}. 
+
+If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+
+@item VT_JMP
+@itemx VT_JMPI
+indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+
+These values are used to compile the @code{||} and @code{&&} logical
+operators.
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+
+@item VT_LVAL
+is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value. 
+
+Understanding the use @code{VT_LVAL} is very important if you want to
+understand how TCC works.
+
+@item VT_LVAL_BYTE
+@itemx VT_LVAL_SHORT
+@itemx VT_LVAL_UNSIGNED
+if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+
+@item VT_LLOCAL
+is a saved lvalue on the stack. @code{VT_LLOCAL} should be eliminated
+ASAP because its semantics are rather complicated.
+
+@item VT_MUSTCAST
+indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+
+@item VT_SYM
+indicates that the symbol @code{SValue.sym} must be added to the constant.
+
+@item VT_MUSTBOUND
+@itemx VT_BOUNDED
+are only used for optional bound checking.
+
+@end table
+
+@subsection Manipulating the value stack
+@cindex value stack
+
+@code{vsetc()} and @code{vset()} pushes a new value on the value
+stack. If the previous @var{vtop} was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous @var{vtop} in a safe storage.
+
+@code{vpop()} pops @var{vtop}. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+
+The @code{gv(rc)} function generates code to evaluate @var{vtop} (the
+top value of the stack) into registers. @var{rc} selects in which
+register class the value should be put. @code{gv()} is the @emph{most
+important function} of the code generator.
+
+@code{gv2()} is the same as @code{gv()} but for the top two stack
+entries.
+
+@subsection CPU dependent code generation
+@cindex CPU dependent
+See the @file{i386-gen.c} file to have an example.
+
+@table @code
+
+@item load()
+must generate the code needed to load a stack value into a register.
+
+@item store()
+must generate the code needed to store a register into a stack value
+lvalue.
+
+@item gfunc_start()
+@itemx gfunc_param()
+@itemx gfunc_call()
+should generate a function call
+
+@item gfunc_prolog()
+@itemx gfunc_epilog()
+should generate a function prolog/epilog.
+
+@item gen_opi(op)
+must generate the binary integer operation @var{op} on the two top
+entries of the stack which are guaranted to contain integer types.
+
+The result value should be put on the stack.
+
+@item gen_opf(op)
+same as @code{gen_opi()} for floating point operations. The two top
+entries of the stack are guaranted to contain floating point values of
+same types.
+
+@item gen_cvt_itof()
+integer to floating point conversion.
+
+@item gen_cvt_ftoi()
+floating point to integer conversion.
+
+@item gen_cvt_ftof()
+floating point to floating point of different size conversion.
+
+@item gen_bounded_ptr_add()
+@item gen_bounded_ptr_deref()
+are only used for bounds checking.
+
+@end table
+
+@section Optimizations done
+@cindex optimizations
+@cindex constant propagation
+@cindex strength reduction
+@cindex comparison operators
+@cindex caching processor flags
+@cindex flags, caching
+@cindex jump optimization
+Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &&, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+
+@unnumbered Concept Index
+@printindex cp
+
+@bye
+
+@c Local variables:
+@c fill-column: 78
+@c texinfo-column-for-description: 32
+@c End:
diff --git a/tinyc/tcc.c b/tinyc/tcc.c
new file mode 100755
index 000000000..3fce60804
--- /dev/null
+++ b/tinyc/tcc.c
@@ -0,0 +1,553 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "libtcc.c"
+
+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"
+           "           [-Wwarn] [-g] [-b] [-bt N] [-Ldir] [-llib] [-shared] [-soname name]\n"
+           "           [-static] [infile1 infile2...] [-run infile args...]\n"
+           "\n"
+           "General options:\n"
+           "  -v          display current version, increase verbosity\n"
+           "  -c          compile only - generate an object file\n"
+           "  -o outfile  set output filename\n"
+           "  -Bdir       set tcc internal library path\n"
+           "  -bench      output compilation statistics\n"
+           "  -run        run compiled source\n"
+           "  -fflag      set or reset (with 'no-' prefix) 'flag' (see man page)\n"
+           "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see man page)\n"
+           "  -w          disable all warnings\n"
+           "Preprocessor options:\n"
+           "  -E          preprocess only\n"
+           "  -Idir       add include path 'dir'\n"
+           "  -Dsym[=val] define 'sym' with value 'val'\n"
+           "  -Usym       undefine 'sym'\n"
+           "Linker options:\n"
+           "  -Ldir       add library path 'dir'\n"
+           "  -llib       link with dynamic or static library 'lib'\n"
+           "  -shared     generate a shared library\n"
+           "  -soname     set name for shared library to be used at runtime\n"
+           "  -static     static linking\n"
+           "  -rdynamic   export all global symbols to dynamic linker\n"
+           "  -r          generate (relocatable) object file\n"
+           "Debugger options:\n"
+           "  -g          generate runtime debug info\n"
+#ifdef CONFIG_TCC_BCHECK
+           "  -b          compile with built-in memory and bounds checker (implies -g)\n"
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+           "  -bt N       show N callers in stack traces\n"
+#endif
+           );
+}
+
+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;
+    uint16_t flags;
+} TCCOption;
+
+enum {
+    TCC_OPTION_HELP,
+    TCC_OPTION_I,
+    TCC_OPTION_D,
+    TCC_OPTION_U,
+    TCC_OPTION_L,
+    TCC_OPTION_B,
+    TCC_OPTION_l,
+    TCC_OPTION_bench,
+    TCC_OPTION_bt,
+    TCC_OPTION_b,
+    TCC_OPTION_g,
+    TCC_OPTION_c,
+    TCC_OPTION_static,
+    TCC_OPTION_shared,
+    TCC_OPTION_soname,
+    TCC_OPTION_o,
+    TCC_OPTION_r,
+    TCC_OPTION_Wl,
+    TCC_OPTION_W,
+    TCC_OPTION_O,
+    TCC_OPTION_m,
+    TCC_OPTION_f,
+    TCC_OPTION_nostdinc,
+    TCC_OPTION_nostdlib,
+    TCC_OPTION_print_search_dirs,
+    TCC_OPTION_rdynamic,
+    TCC_OPTION_run,
+    TCC_OPTION_v,
+    TCC_OPTION_w,
+    TCC_OPTION_pipe,
+    TCC_OPTION_E,
+};
+
+static const TCCOption tcc_options[] = {
+    { "h", TCC_OPTION_HELP, 0 },
+    { "?", TCC_OPTION_HELP, 0 },
+    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
+    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
+    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
+    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
+    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
+    { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "bench", TCC_OPTION_bench, 0 },
+    { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
+#ifdef CONFIG_TCC_BCHECK
+    { "b", TCC_OPTION_b, 0 },
+#endif
+    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "c", TCC_OPTION_c, 0 },
+    { "static", TCC_OPTION_static, 0 },
+    { "shared", TCC_OPTION_shared, 0 },
+    { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
+    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
+    { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "rdynamic", TCC_OPTION_rdynamic, 0 },
+    { "r", TCC_OPTION_r, 0 },
+    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG },
+    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "nostdinc", TCC_OPTION_nostdinc, 0 },
+    { "nostdlib", TCC_OPTION_nostdlib, 0 },
+    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 }, 
+    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "w", TCC_OPTION_w, 0 },
+    { "pipe", TCC_OPTION_pipe, 0},
+    { "E", TCC_OPTION_E, 0},
+    { NULL },
+};
+
+static int64_t getclock_us(void)
+{
+#ifdef _WIN32
+    struct _timeb tb;
+    _ftime(&tb);
+    return (tb.time * 1000LL + tb.millitm) * 1000LL;
+#else
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_usec;
+#endif
+}
+
+static int strstart(const char *str, const char *val, const char **ptr)
+{
+    const char *p, *q;
+    p = str;
+    q = val;
+    while (*q != '\0') {
+        if (*p != *q)
+            return 0;
+        p++;
+        q++;
+    }
+    if (ptr)
+        *ptr = p;
+    return 1;
+}
+
+/* convert 'str' into an array of space separated strings */
+static int expand_args(char ***pargv, const char *str)
+{
+    const char *s1;
+    char **argv, *arg;
+    int argc, len;
+
+    argc = 0;
+    argv = NULL;
+    for(;;) {
+        while (is_space(*str))
+            str++;
+        if (*str == '\0')
+            break;
+        s1 = str;
+        while (*str != '\0' && !is_space(*str))
+            str++;
+        len = str - s1;
+        arg = tcc_malloc(len + 1);
+        memcpy(arg, s1, len);
+        arg[len] = '\0';
+        dynarray_add((void ***)&argv, &argc, arg);
+    }
+    *pargv = argv;
+    return argc;
+}
+
+int parse_args(TCCState *s, int argc, char **argv)
+{
+    int optind;
+    const TCCOption *popt;
+    const char *optarg, *p1, *r1;
+    char *r;
+
+    optind = 0;
+    while (optind < argc) {
+
+        r = argv[optind++];
+        if (r[0] != '-' || r[1] == '\0') {
+            /* add a new file */
+            dynarray_add((void ***)&files, &nb_files, r);
+            if (!multiple_files) {
+                optind--;
+                /* argv[0] will be this file */
+                break;
+            }
+        } else {
+            /* find option in table (match only the first chars */
+            popt = tcc_options;
+            for(;;) {
+                p1 = popt->name;
+                if (p1 == NULL)
+                    error("invalid option -- '%s'", r);
+                r1 = r + 1;
+                for(;;) {
+                    if (*p1 == '\0')
+                        goto option_found;
+                    if (*r1 != *p1)
+                        break;
+                    p1++;
+                    r1++;
+                }
+                popt++;
+            }
+        option_found:
+            if (popt->flags & TCC_OPTION_HAS_ARG) {
+                if (*r1 != '\0' || (popt->flags & TCC_OPTION_NOSEP)) {
+                    optarg = r1;
+                } else {
+                    if (optind >= argc)
+                        error("argument to '%s' is missing", r);
+                    optarg = argv[optind++];
+                }
+            } else {
+                if (*r1 != '\0')
+                    return 0;
+                optarg = NULL;
+            }
+                
+            switch(popt->index) {
+            case TCC_OPTION_HELP:
+                return 0;
+
+            case TCC_OPTION_I:
+                if (tcc_add_include_path(s, optarg) < 0)
+                    error("too many include paths");
+                break;
+            case TCC_OPTION_D:
+                {
+                    char *sym, *value;
+                    sym = (char *)optarg;
+                    value = strchr(sym, '=');
+                    if (value) {
+                        *value = '\0';
+                        value++;
+                    }
+                    tcc_define_symbol(s, sym, value);
+                }
+                break;
+            case TCC_OPTION_U:
+                tcc_undefine_symbol(s, optarg);
+                break;
+            case TCC_OPTION_L:
+                tcc_add_library_path(s, optarg);
+                break;
+            case TCC_OPTION_B:
+                /* set tcc utilities path (mainly for tcc development) */
+                tcc_set_lib_path(s, optarg);
+                break;
+            case TCC_OPTION_l:
+                dynarray_add((void ***)&files, &nb_files, r);
+                nb_libraries++;
+                break;
+            case TCC_OPTION_bench:
+                do_bench = 1;
+                break;
+#ifdef CONFIG_TCC_BACKTRACE
+            case TCC_OPTION_bt:
+                num_callers = atoi(optarg);
+                break;
+#endif
+#ifdef CONFIG_TCC_BCHECK
+            case TCC_OPTION_b:
+                s->do_bounds_check = 1;
+                s->do_debug = 1;
+                break;
+#endif
+            case TCC_OPTION_g:
+                s->do_debug = 1;
+                break;
+            case TCC_OPTION_c:
+                multiple_files = 1;
+                output_type = TCC_OUTPUT_OBJ;
+                break;
+            case TCC_OPTION_static:
+                s->static_link = 1;
+                break;
+            case TCC_OPTION_shared:
+                output_type = TCC_OUTPUT_DLL;
+                break;
+            case TCC_OPTION_soname:
+                s->soname = optarg; 
+                break;
+            case TCC_OPTION_o:
+                multiple_files = 1;
+                outfile = optarg;
+                break;
+            case TCC_OPTION_r:
+                /* generate a .o merging several output files */
+                reloc_output = 1;
+                output_type = TCC_OUTPUT_OBJ;
+                break;
+            case TCC_OPTION_nostdinc:
+                s->nostdinc = 1;
+                break;
+            case TCC_OPTION_nostdlib:
+                s->nostdlib = 1;
+                break;
+            case TCC_OPTION_print_search_dirs:
+                print_search_dirs = 1;
+                break;
+            case TCC_OPTION_run:
+                {
+                    int argc1;
+                    char **argv1;
+                    argc1 = expand_args(&argv1, optarg);
+                    if (argc1 > 0) {
+                        parse_args(s, argc1, argv1);
+                    }
+                    multiple_files = 0;
+                    output_type = TCC_OUTPUT_MEMORY;
+                }
+                break;
+            case TCC_OPTION_v:
+                do {
+                    if (0 == s->verbose++)
+                        printf("tcc version %s\n", TCC_VERSION);
+                } while (*optarg++ == 'v');
+                break;
+            case TCC_OPTION_f:
+                if (tcc_set_flag(s, optarg, 1) < 0 && s->warn_unsupported)
+                    goto unsupported_option;
+                break;
+            case TCC_OPTION_W:
+                if (tcc_set_warning(s, optarg, 1) < 0 && 
+                    s->warn_unsupported)
+                    goto unsupported_option;
+                break;
+            case TCC_OPTION_w:
+                s->warn_none = 1;
+                break;
+            case TCC_OPTION_rdynamic:
+                s->rdynamic = 1;
+                break;
+            case TCC_OPTION_Wl:
+                {
+                    const char *p;
+                    if (strstart(optarg, "-Ttext,", &p)) {
+                        s->text_addr = strtoul(p, NULL, 16);
+                        s->has_text_addr = 1;
+                    } else if (strstart(optarg, "--oformat,", &p)) {
+                        if (strstart(p, "elf32-", NULL)) {
+                            s->output_format = TCC_OUTPUT_FORMAT_ELF;
+                        } else if (!strcmp(p, "binary")) {
+                            s->output_format = TCC_OUTPUT_FORMAT_BINARY;
+                        } else
+#ifdef TCC_TARGET_COFF
+                        if (!strcmp(p, "coff")) {
+                            s->output_format = TCC_OUTPUT_FORMAT_COFF;
+                        } else
+#endif
+                        {
+                            error("target %s not found", p);
+                        }
+                    } else {
+                        error("unsupported linker option '%s'", optarg);
+                    }
+                }
+                break;
+            case TCC_OPTION_E:
+                output_type = TCC_OUTPUT_PREPROCESS;
+                break;
+            default:
+                if (s->warn_unsupported) {
+                unsupported_option:
+                    warning("unsupported option '%s'", r);
+                }
+                break;
+            }
+        }
+    }
+    return optind + 1;
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    TCCState *s;
+    int nb_objfiles, ret, optind;
+    char objfilename[1024];
+    int64_t start_time = 0;
+
+    s = tcc_new();
+#ifdef _WIN32
+    tcc_set_lib_path_w32(s);
+#endif
+    output_type = TCC_OUTPUT_EXE;
+    outfile = NULL;
+    multiple_files = 1;
+    files = NULL;
+    nb_files = 0;
+    nb_libraries = 0;
+    reloc_output = 0;
+    print_search_dirs = 0;
+    ret = 0;
+
+    optind = parse_args(s, argc - 1, argv + 1);
+    if (print_search_dirs) {
+        /* enough for Linux kernel */
+        printf("install: %s/\n", s->tcc_lib_path);
+        return 0;
+    }
+    if (optind == 0 || nb_files == 0) {
+        if (optind && s->verbose)
+            return 0;
+        help();
+        return 1;
+    }
+
+    nb_objfiles = nb_files - nb_libraries;
+
+    /* if outfile provided without other options, we output an
+       executable */
+    if (outfile && output_type == TCC_OUTPUT_MEMORY)
+        output_type = TCC_OUTPUT_EXE;
+
+    /* check -c consistency : only single file handled. XXX: checks file type */
+    if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
+        /* accepts only a single input file */
+        if (nb_objfiles != 1)
+            error("cannot specify multiple files with -c");
+        if (nb_libraries != 0)
+            error("cannot specify libraries with -c");
+    }
+    
+
+    if (output_type == TCC_OUTPUT_PREPROCESS) {
+        if (!outfile) {
+            s->outfile = stdout;
+        } else {
+            s->outfile = fopen(outfile, "w");
+            if (!s->outfile)
+                error("could not open '%s", outfile);
+        }
+    } else if (output_type != TCC_OUTPUT_MEMORY) {
+        if (!outfile) {
+            /* compute default outfile name */
+            char *ext;
+            const char *name = 
+                strcmp(files[0], "-") == 0 ? "a" : tcc_basename(files[0]);
+            pstrcpy(objfilename, sizeof(objfilename), name);
+            ext = tcc_fileextension(objfilename);
+#ifdef TCC_TARGET_PE
+            if (output_type == TCC_OUTPUT_DLL)
+                strcpy(ext, ".dll");
+            else
+            if (output_type == TCC_OUTPUT_EXE)
+                strcpy(ext, ".exe");
+            else
+#endif
+            if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext)
+                strcpy(ext, ".o");
+            else
+                pstrcpy(objfilename, sizeof(objfilename), "a.out");
+            outfile = objfilename;
+        }
+    }
+
+    if (do_bench) {
+        start_time = getclock_us();
+    }
+
+    tcc_set_output_type(s, output_type);
+
+    /* compile or add each files or library */
+    for(i = 0; i < nb_files && ret == 0; i++) {
+        const char *filename;
+
+        filename = files[i];
+        if (filename[0] == '-' && filename[1]) {
+            if (tcc_add_library(s, filename + 2) < 0) {
+                error_noabort("cannot find %s", filename);
+                ret = 1;
+            }
+        } else {
+            if (1 == s->verbose)
+                printf("-> %s\n", filename);
+            if (tcc_add_file(s, filename) < 0)
+                ret = 1;
+        }
+    }
+
+    /* free all files */
+    tcc_free(files);
+
+    if (ret)
+        goto the_end;
+
+    if (do_bench)
+        tcc_print_stats(s, getclock_us() - start_time);
+
+    if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+        if (outfile)
+            fclose(s->outfile);
+    } else if (s->output_type == TCC_OUTPUT_MEMORY) {
+        ret = tcc_run(s, argc - optind, argv + optind);
+    } else
+        ret = tcc_output_file(s, outfile) ? 1 : 0;
+ the_end:
+    /* XXX: cannot do it with bound checking because of the malloc hooks */
+    if (!s->do_bounds_check)
+        tcc_delete(s);
+
+#ifdef MEM_DEBUG
+    if (do_bench) {
+        printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
+    }
+#endif
+    return ret;
+}
+
diff --git a/tinyc/tcc.h b/tinyc/tcc.h
new file mode 100755
index 000000000..be9c4ccb0
--- /dev/null
+++ b/tinyc/tcc.h
@@ -0,0 +1,766 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define _GNU_SOURCE
+#include "config.h"
+
+#ifdef CONFIG_TCCBOOT
+
+#include "tccboot.h"
+#define CONFIG_TCC_STATIC
+
+#else
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <time.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <sys/timeb.h>
+#include <io.h> /* open, close etc. */
+#include <direct.h> /* getcwd */
+#define inline __inline
+#define inp next_inp
+#endif
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+#endif
+
+#endif /* !CONFIG_TCCBOOT */
+
+#ifndef PAGESIZE
+#define PAGESIZE 4096
+#endif
+
+#include "elf.h"
+#include "stab.h"
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "libtcc.h"
+
+/* parser debug */
+//#define PARSE_DEBUG
+/* preprocessor debug */
+//#define PP_DEBUG
+/* include file debug */
+//#define INC_DEBUG
+
+//#define MEM_DEBUG
+
+/* assembler debug */
+//#define ASM_DEBUG
+
+/* target selection */
+//#define TCC_TARGET_I386   /* i386 code generator */
+//#define TCC_TARGET_ARM    /* ARMv4 code generator */
+//#define TCC_TARGET_C67    /* TMS320C67xx code generator */
+//#define TCC_TARGET_X86_64 /* x86-64 code generator */
+
+/* default target is I386 */
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
+    !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
+#define TCC_TARGET_I386
+#endif
+
+#if !defined(_WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
+    !defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
+#define CONFIG_TCC_BCHECK /* enable bound checking code */
+#endif
+
+#if defined(_WIN32) && !defined(TCC_TARGET_PE)
+#define CONFIG_TCC_STATIC
+#endif
+
+/* define it to include assembler support */
+#if !defined(TCC_TARGET_ARM) && !defined(TCC_TARGET_C67) && \
+    !defined(TCC_TARGET_X86_64)
+#define CONFIG_TCC_ASM
+#endif
+
+/* object format selection */
+#if defined(TCC_TARGET_C67)
+#define TCC_TARGET_COFF
+#endif
+
+#if !defined(_WIN32) && !defined(CONFIG_TCCBOOT)
+#define CONFIG_TCC_BACKTRACE
+#endif
+
+#define FALSE 0
+#define false 0
+#define TRUE 1
+#define true 1
+typedef int BOOL;
+
+/* path to find crt1.o, crti.o and crtn.o. Only needed when generating
+   executables or dlls */
+#define CONFIG_TCC_CRT_PREFIX CONFIG_SYSROOT "/usr/lib"
+
+#define INCLUDE_STACK_SIZE  32
+#define IFDEF_STACK_SIZE    64
+#define VSTACK_SIZE         256
+#define STRING_MAX_SIZE     1024
+#define PACK_STACK_SIZE     8
+
+#define TOK_HASH_SIZE       8192 /* must be a power of two */
+#define TOK_ALLOC_INCR      512  /* must be a power of two */
+#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
+
+/* token symbol management */
+typedef struct TokenSym {
+    struct TokenSym *hash_next;
+    struct Sym *sym_define; /* direct pointer to define */
+    struct Sym *sym_label; /* direct pointer to label */
+    struct Sym *sym_struct; /* direct pointer to structure */
+    struct Sym *sym_identifier; /* direct pointer to identifier */
+    int tok; /* token number */
+    int len;
+    char str[1];
+} TokenSym;
+
+#ifdef TCC_TARGET_PE
+typedef unsigned short nwchar_t;
+#else
+typedef int nwchar_t;
+#endif
+
+typedef struct CString {
+    int size; /* size in bytes */
+    void *data; /* either 'char *' or 'nwchar_t *' */
+    int size_allocated;
+    void *data_allocated; /* if non NULL, data has been malloced */
+} CString;
+
+/* type definition */
+typedef struct CType {
+    int t;
+    struct Sym *ref;
+} CType;
+
+/* constant value */
+typedef union CValue {
+    long double ld;
+    double d;
+    float f;
+    int i;
+    unsigned int ui;
+    unsigned int ul; /* address (should be unsigned long on 64 bit cpu) */
+    long long ll;
+    unsigned long long ull;
+    struct CString *cstr;
+    void *ptr;
+    int tab[1];
+} CValue;
+
+/* value on stack */
+typedef struct SValue {
+    CType type;      /* type */
+    unsigned short r;      /* register + flags */
+    unsigned short r2;     /* second register, used for 'long long'
+                              type. If not used, set to VT_CONST */
+    CValue c;              /* constant, if VT_CONST */
+    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST) */
+} SValue;
+
+/* symbol management */
+typedef struct Sym {
+    int v;    /* symbol token */
+    long r;    /* associated register */
+    long c;    /* associated number */
+    CType type;    /* associated type */
+    struct Sym *next; /* next related symbol */
+    struct Sym *prev; /* prev symbol in stack */
+    struct Sym *prev_tok; /* previous symbol for this token */
+} Sym;
+
+/* section definition */
+/* XXX: use directly ELF structure for parameters ? */
+/* special flag to indicate that the section should not be linked to
+   the other ones */
+#define SHF_PRIVATE 0x80000000
+
+/* special flag, too */
+#define SECTION_ABS ((void *)1)
+
+typedef struct Section {
+    unsigned long data_offset; /* current data offset */
+    unsigned char *data;       /* section data */
+    unsigned long data_allocated; /* used for realloc() handling */
+    int sh_name;             /* elf section name (only used during output) */
+    int sh_num;              /* elf section number */
+    int sh_type;             /* elf section type */
+    int sh_flags;            /* elf section flags */
+    int sh_info;             /* elf section info */
+    int sh_addralign;        /* elf section alignment */
+    int sh_entsize;          /* elf entry size */
+    unsigned long sh_size;   /* section size (only used during output) */
+    unsigned long sh_addr;      /* address at which the section is relocated */
+    unsigned long sh_offset;    /* file offset */
+    int nb_hashed_syms;      /* used to resize the hash table */
+    struct Section *link;    /* link to another section */
+    struct Section *reloc;   /* corresponding section for relocation, if any */
+    struct Section *hash;     /* hash table for symbols */
+    struct Section *next;
+    char name[1];           /* section name */
+} Section;
+
+typedef struct DLLReference {
+    int level;
+    void *handle;
+    char name[1];
+} DLLReference;
+
+/* GNUC attribute definition */
+typedef struct AttributeDef {
+    int aligned;
+    int packed; 
+    Section *section;
+    int func_attr; /* calling convention, exports, ... */
+} AttributeDef;
+
+/* -------------------------------------------------- */
+/* gr: wrappers for casting sym->r for other purposes */
+typedef struct {
+    unsigned
+      func_call : 8,
+      func_args : 8,
+      func_export : 1;
+} func_attr_t;
+
+#define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call)
+#define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export)
+#define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args)
+#define INLINE_DEF(r) (*(int **)&(r))
+/* -------------------------------------------------- */
+
+#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
+#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
+#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
+
+/* stored in 'Sym.c' field */
+#define FUNC_NEW       1 /* ansi function prototype */
+#define FUNC_OLD       2 /* old function prototype */
+#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
+
+/* stored in 'Sym.r' field */
+#define FUNC_CDECL     0 /* standard c call */
+#define FUNC_STDCALL   1 /* pascal c call */
+#define FUNC_FASTCALL1 2 /* first param in %eax */
+#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
+#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
+#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
+
+/* field 'Sym.t' for macros */
+#define MACRO_OBJ      0 /* object like macro */
+#define MACRO_FUNC     1 /* function like macro */
+
+/* field 'Sym.r' for C labels */
+#define LABEL_DEFINED  0 /* label is defined */
+#define LABEL_FORWARD  1 /* label is forward defined */
+#define LABEL_DECLARED 2 /* label is declared but never used */
+
+/* type_decl() types */
+#define TYPE_ABSTRACT  1 /* type without variable */
+#define TYPE_DIRECT    2 /* type with variable */
+
+#define IO_BUF_SIZE 8192
+
+typedef struct BufferedFile {
+    uint8_t *buf_ptr;
+    uint8_t *buf_end;
+    int fd;
+    int line_num;    /* current line number - here to simplify code */
+    int ifndef_macro;  /* #ifndef macro / #endif search */
+    int ifndef_macro_saved; /* saved ifndef_macro */
+    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
+    char inc_type;          /* type of include */
+    char inc_filename[512]; /* filename specified by the user */
+    char filename[1024];    /* current filename - here to simplify code */
+    unsigned char buffer[IO_BUF_SIZE + 1]; /* extra size for CH_EOB char */
+} BufferedFile;
+
+#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
+#define CH_EOF   (-1)   /* end of file */
+
+/* parsing state (used to save parser state to reparse part of the
+   source several times) */
+typedef struct ParseState {
+    int *macro_ptr;
+    int line_num;
+    int tok;
+    CValue tokc;
+} ParseState;
+
+/* used to record tokens */
+typedef struct TokenString {
+    int *str;
+    int len;
+    int allocated_len;
+    int last_line_num;
+} TokenString;
+
+/* include file cache, used to find files faster and also to eliminate
+   inclusion if the include file is protected by #ifndef ... #endif */
+typedef struct CachedInclude {
+    int ifndef_macro;
+    int hash_next; /* -1 if none */
+    char type; /* '"' or '>' to give include type */
+    char filename[1]; /* path specified in #include */
+} CachedInclude;
+
+#define CACHED_INCLUDES_HASH_SIZE 512
+
+#ifdef CONFIG_TCC_ASM
+typedef struct ExprValue {
+    uint32_t v;
+    Sym *sym;
+} ExprValue;
+
+#define MAX_ASM_OPERANDS 30
+typedef struct ASMOperand {
+    int id; /* GCC 3 optionnal identifier (0 if number only supported */
+    char *constraint;
+    char asm_str[16]; /* computed asm string for operand */
+    SValue *vt; /* C value of the expression */
+    int ref_index; /* if >= 0, gives reference to a output constraint */
+    int input_index; /* if >= 0, gives reference to an input constraint */
+    int priority; /* priority, used to assign registers */
+    int reg; /* if >= 0, register number used for this operand */
+    int is_llong; /* true if double register value */
+    int is_memory; /* true if memory operand */
+    int is_rw;     /* for '+' modifier */
+} ASMOperand;
+
+#endif
+
+struct TCCState {
+    int output_type;
+ 
+    BufferedFile **include_stack_ptr;
+    int *ifdef_stack_ptr;
+
+    /* include file handling */
+    char **include_paths;
+    int nb_include_paths;
+    char **sysinclude_paths;
+    int nb_sysinclude_paths;
+    CachedInclude **cached_includes;
+    int nb_cached_includes;
+
+    char **library_paths;
+    int nb_library_paths;
+
+    /* array of all loaded dlls (including those referenced by loaded
+       dlls) */
+    DLLReference **loaded_dlls;
+    int nb_loaded_dlls;
+
+    /* sections */
+    Section **sections;
+    int nb_sections; /* number of sections, including first dummy section */
+
+    Section **priv_sections;
+    int nb_priv_sections; /* number of private sections */
+
+    /* got handling */
+    Section *got;
+    Section *plt;
+    unsigned long *got_offsets;
+    int nb_got_offsets;
+    /* give the correspondance from symtab indexes to dynsym indexes */
+    int *symtab_to_dynsym;
+
+    /* temporary dynamic symbol sections (for dll loading) */
+    Section *dynsymtab_section;
+    /* exported dynamic symbol section */
+    Section *dynsym;
+
+    int nostdinc; /* if true, no standard headers are added */
+    int nostdlib; /* if true, no standard libraries are added */
+    int nocommon; /* if true, do not use common symbols for .bss data */
+
+    /* if true, static linking is performed */
+    int static_link;
+
+    /* soname as specified on the command line (-soname) */
+    const char *soname;
+
+    /* if true, all symbols are exported */
+    int rdynamic;
+
+    /* if true, only link in referenced objects from archive */
+    int alacarte_link;
+
+    /* address of text section */
+    unsigned long text_addr;
+    int has_text_addr;
+    
+    /* output format, see TCC_OUTPUT_FORMAT_xxx */
+    int output_format;
+
+    /* C language options */
+    int char_is_unsigned;
+    int leading_underscore;
+    
+    /* warning switches */
+    int warn_write_strings;
+    int warn_unsupported;
+    int warn_error;
+    int warn_none;
+    int warn_implicit_function_declaration;
+
+    /* display some information during compilation */
+    int verbose;
+    /* compile with debug symbol (and use them if error during execution) */
+    int do_debug;
+    /* compile with built-in memory and bounds checker */
+    int do_bounds_check;
+    /* give the path of the tcc libraries */
+    const char *tcc_lib_path;
+
+    /* error handling */
+    void *error_opaque;
+    void (*error_func)(void *opaque, const char *msg);
+    int error_set_jmp_enabled;
+    jmp_buf error_jmp_buf;
+    int nb_errors;
+
+    /* tiny assembler state */
+    Sym *asm_labels;
+
+    /* see include_stack_ptr */
+    BufferedFile *include_stack[INCLUDE_STACK_SIZE];
+
+    /* see ifdef_stack_ptr */
+    int ifdef_stack[IFDEF_STACK_SIZE];
+
+    /* see cached_includes */
+    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
+
+    /* pack stack */
+    int pack_stack[PACK_STACK_SIZE];
+    int *pack_stack_ptr;
+
+    /* output file for preprocessing */
+    FILE *outfile;
+
+    /* for tcc_relocate */
+    int runtime_added;
+
+#ifdef TCC_TARGET_X86_64
+    /* write PLT and GOT here */
+    char *runtime_plt_and_got;
+    unsigned int runtime_plt_and_got_offset;
+#endif
+};
+
+/* The current value can be: */
+#define VT_VALMASK   0x00ff
+#define VT_CONST     0x00f0  /* constant in vc 
+                              (must be first non register value) */
+#define VT_LLOCAL    0x00f1  /* lvalue, offset on stack */
+#define VT_LOCAL     0x00f2  /* offset on stack */
+#define VT_CMP       0x00f3  /* the value is stored in processor flags (in vc) */
+#define VT_JMP       0x00f4  /* value is the consequence of jmp true (even) */
+#define VT_JMPI      0x00f5  /* value is the consequence of jmp false (odd) */
+#define VT_LVAL      0x0100  /* var is an lvalue */
+#define VT_SYM       0x0200  /* a symbol value is added */
+#define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
+                                char/short stored in integer registers) */
+#define VT_MUSTBOUND 0x0800  /* bound checking must be done before
+                                dereferencing value */
+#define VT_BOUNDED   0x8000  /* value is bounded. The address of the
+                                bounding function call point is in vc */
+#define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
+#define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
+#define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+
+/* types */
+#define VT_INT        0  /* integer type */
+#define VT_BYTE       1  /* signed byte type */
+#define VT_SHORT      2  /* short type */
+#define VT_VOID       3  /* void type */
+#define VT_PTR        4  /* pointer */
+#define VT_ENUM       5  /* enum definition */
+#define VT_FUNC       6  /* function type */
+#define VT_STRUCT     7  /* struct/union definition */
+#define VT_FLOAT      8  /* IEEE float */
+#define VT_DOUBLE     9  /* IEEE double */
+#define VT_LDOUBLE   10  /* IEEE long double */
+#define VT_BOOL      11  /* ISOC99 boolean type */
+#define VT_LLONG     12  /* 64 bit integer */
+#define VT_LONG      13  /* long integer (NEVER USED as type, only
+                            during parsing) */
+#define VT_BTYPE      0x000f /* mask for basic type */
+#define VT_UNSIGNED   0x0010  /* unsigned type */
+#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
+#define VT_BITFIELD   0x0040  /* bitfield modifier */
+#define VT_CONSTANT   0x0800  /* const modifier */
+#define VT_VOLATILE   0x1000  /* volatile modifier */
+#define VT_SIGNED     0x2000  /* signed type */
+
+/* storage */
+#define VT_EXTERN  0x00000080  /* extern definition */
+#define VT_STATIC  0x00000100  /* static variable */
+#define VT_TYPEDEF 0x00000200  /* typedef definition */
+#define VT_INLINE  0x00000400  /* inline definition */
+
+#define VT_STRUCT_SHIFT 16   /* shift for bitfield shift values */
+
+/* type mask (except storage) */
+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
+#define VT_TYPE    (~(VT_STORAGE))
+
+/* token values */
+
+/* warning: the following compare tokens depend on i386 asm code */
+#define TOK_ULT 0x92
+#define TOK_UGE 0x93
+#define TOK_EQ  0x94
+#define TOK_NE  0x95
+#define TOK_ULE 0x96
+#define TOK_UGT 0x97
+#define TOK_Nset 0x98
+#define TOK_Nclear 0x99
+#define TOK_LT  0x9c
+#define TOK_GE  0x9d
+#define TOK_LE  0x9e
+#define TOK_GT  0x9f
+
+#define TOK_LAND  0xa0
+#define TOK_LOR   0xa1
+
+#define TOK_DEC   0xa2
+#define TOK_MID   0xa3 /* inc/dec, to void constant */
+#define TOK_INC   0xa4
+#define TOK_UDIV  0xb0 /* unsigned division */
+#define TOK_UMOD  0xb1 /* unsigned modulo */
+#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
+#define TOK_CINT   0xb3 /* number in tokc */
+#define TOK_CCHAR 0xb4 /* char constant in tokc */
+#define TOK_STR   0xb5 /* pointer to string in tokc */
+#define TOK_TWOSHARPS 0xb6 /* ## preprocessing token */
+#define TOK_LCHAR    0xb7
+#define TOK_LSTR     0xb8
+#define TOK_CFLOAT   0xb9 /* float constant */
+#define TOK_LINENUM  0xba /* line number info */
+#define TOK_CDOUBLE  0xc0 /* double constant */
+#define TOK_CLDOUBLE 0xc1 /* long double constant */
+#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
+#define TOK_ADDC1    0xc3 /* add with carry generation */
+#define TOK_ADDC2    0xc4 /* add with carry use */
+#define TOK_SUBC1    0xc5 /* add with carry generation */
+#define TOK_SUBC2    0xc6 /* add with carry use */
+#define TOK_CUINT    0xc8 /* unsigned int constant */
+#define TOK_CLLONG   0xc9 /* long long constant */
+#define TOK_CULLONG  0xca /* unsigned long long constant */
+#define TOK_ARROW    0xcb
+#define TOK_DOTS     0xcc /* three dots */
+#define TOK_SHR      0xcd /* unsigned shift right */
+#define TOK_PPNUM    0xce /* preprocessor number */
+
+#define TOK_SHL   0x01 /* shift left */
+#define TOK_SAR   0x02 /* signed shift right */
+  
+/* assignement operators : normal operator or 0x80 */
+#define TOK_A_MOD 0xa5
+#define TOK_A_AND 0xa6
+#define TOK_A_MUL 0xaa
+#define TOK_A_ADD 0xab
+#define TOK_A_SUB 0xad
+#define TOK_A_DIV 0xaf
+#define TOK_A_XOR 0xde
+#define TOK_A_OR  0xfc
+#define TOK_A_SHL 0x81
+#define TOK_A_SAR 0x82
+
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+#ifndef countof
+#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
+#endif
+
+#define TOK_EOF       (-1)  /* end of file */
+#define TOK_LINEFEED  10    /* line feed */
+
+/* all identificators and strings have token above that */
+#define TOK_IDENT 256
+
+/* only used for i386 asm opcodes definitions */
+#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
+
+#define DEF_BWL(x) \
+ DEF(TOK_ASM_ ## x ## b, #x "b") \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+
+#define DEF_WL(x) \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+
+#define DEF_FP1(x) \
+ DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
+ DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
+ DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
+ DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
+
+#define DEF_FP(x) \
+ DEF(TOK_ASM_ ## f ## x, "f" #x ) \
+ DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
+ DEF_FP1(x)
+
+#define DEF_ASMTEST(x) \
+ DEF_ASM(x ## o) \
+ DEF_ASM(x ## no) \
+ DEF_ASM(x ## b) \
+ DEF_ASM(x ## c) \
+ DEF_ASM(x ## nae) \
+ DEF_ASM(x ## nb) \
+ DEF_ASM(x ## nc) \
+ DEF_ASM(x ## ae) \
+ DEF_ASM(x ## e) \
+ DEF_ASM(x ## z) \
+ DEF_ASM(x ## ne) \
+ DEF_ASM(x ## nz) \
+ DEF_ASM(x ## be) \
+ DEF_ASM(x ## na) \
+ DEF_ASM(x ## nbe) \
+ DEF_ASM(x ## a) \
+ DEF_ASM(x ## s) \
+ DEF_ASM(x ## ns) \
+ DEF_ASM(x ## p) \
+ DEF_ASM(x ## pe) \
+ DEF_ASM(x ## np) \
+ DEF_ASM(x ## po) \
+ DEF_ASM(x ## l) \
+ DEF_ASM(x ## nge) \
+ DEF_ASM(x ## nl) \
+ DEF_ASM(x ## ge) \
+ DEF_ASM(x ## le) \
+ DEF_ASM(x ## ng) \
+ DEF_ASM(x ## nle) \
+ DEF_ASM(x ## g)
+
+#define TOK_ASM_int TOK_INT
+
+enum tcc_token {
+    TOK_LAST = TOK_IDENT - 1,
+#define DEF(id, str) id,
+#include "tcctok.h"
+#undef DEF
+};
+
+#define TOK_UIDENT TOK_DEFINE
+
+#ifdef _WIN32
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#ifndef __GNUC__
+  #define strtold (long double)strtod
+  #define strtof (float)strtod
+  #define strtoll (long long)strtol
+#endif
+#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
+    || defined(__OpenBSD__)
+/* currently incorrect */
+long double strtold(const char *nptr, char **endptr)
+{
+    return (long double)strtod(nptr, endptr);
+}
+float strtof(const char *nptr, char **endptr)
+{
+    return (float)strtod(nptr, endptr);
+}
+#else
+/* XXX: need to define this to use them in non ISOC99 context */
+extern float strtof (const char *__nptr, char **__endptr);
+extern long double strtold (const char *__nptr, char **__endptr);
+#endif
+
+#ifdef _WIN32
+#define IS_PATHSEP(c) (c == '/' || c == '\\')
+#define IS_ABSPATH(p) (IS_PATHSEP(p[0]) || (p[0] && p[1] == ':' && IS_PATHSEP(p[2])))
+#define PATHCMP stricmp
+#else
+#define IS_PATHSEP(c) (c == '/')
+#define IS_ABSPATH(p) IS_PATHSEP(p[0])
+#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);
+
+#ifdef CONFIG_TCC_BACKTRACE
+extern int num_callers;
+extern const char **rt_bound_error_msg;
+#endif
+
+/* 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';
+}
+
diff --git a/tinyc/tccasm.c b/tinyc/tccasm.c
new file mode 100755
index 000000000..8834b53fb
--- /dev/null
+++ b/tinyc/tccasm.c
@@ -0,0 +1,1021 @@
+/*
+ *  GAS like assembler for TCC
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+static int asm_get_local_label_name(TCCState *s1, unsigned int n)
+{
+    char buf[64];
+    TokenSym *ts;
+
+    snprintf(buf, sizeof(buf), "L..%u", n);
+    ts = tok_alloc(buf, strlen(buf));
+    return ts->tok;
+}
+
+static 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. */
+
+static void asm_expr_unary(TCCState *s1, ExprValue *pe)
+{
+    Sym *sym;
+    int op, n, label;
+    const char *p;
+
+    switch(tok) {
+    case TOK_PPNUM:
+        p = tokc.cstr->data;
+        n = strtoul(p, (char **)&p, 0);
+        if (*p == 'b' || *p == 'f') {
+            /* backward or forward label */
+            label = asm_get_local_label_name(s1, n);
+            sym = label_find(label);
+            if (*p == 'b') {
+                /* backward : find the last corresponding defined label */
+                if (sym && sym->r == 0)
+                    sym = sym->prev_tok;
+                if (!sym)
+                    error("local label '%d' not found backward", n);
+            } else {
+                /* forward */
+                if (!sym || sym->r) {
+                    /* if the last label is defined, then define a new one */
+                    sym = label_push(&s1->asm_labels, label, 0);
+                    sym->type.t = VT_STATIC | VT_VOID;
+                }
+            }
+            pe->v = 0;
+            pe->sym = sym;
+        } else if (*p == '\0') {
+            pe->v = n;
+            pe->sym = NULL;
+        } else {
+            error("invalid number syntax");
+        }
+        next();
+        break;
+    case '+':
+        next();
+        asm_expr_unary(s1, pe);
+        break;
+    case '-':
+    case '~':
+        op = tok;
+        next();
+        asm_expr_unary(s1, pe);
+        if (pe->sym)
+            error("invalid operation with label");
+        if (op == '-')
+            pe->v = -pe->v;
+        else
+            pe->v = ~pe->v;
+        break;
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+	pe->v = tokc.i;
+	pe->sym = NULL;
+	next();
+	break;
+    case '(':
+        next();
+        asm_expr(s1, pe);
+        skip(')');
+        break;
+    default:
+        if (tok >= TOK_IDENT) {
+            /* label case : if the label was not found, add one */
+            sym = label_find(tok);
+            if (!sym) {
+                sym = label_push(&s1->asm_labels, tok, 0);
+                /* NOTE: by default, the symbol is global */
+                sym->type.t = VT_VOID;
+            }
+            if (sym->r == SHN_ABS) {
+                /* if absolute symbol, no need to put a symbol value */
+                pe->v = (long)sym->next;
+                pe->sym = NULL;
+            } else {
+                pe->v = 0;
+                pe->sym = sym;
+            }
+            next();
+        } else {
+            error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
+        }
+        break;
+    }
+}
+    
+static void asm_expr_prod(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_unary(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '*' && op != '/' && op != '%' && 
+            op != TOK_SHL && op != TOK_SAR)
+            break;
+        next();
+        asm_expr_unary(s1, &e2);
+        if (pe->sym || e2.sym)
+            error("invalid operation with label");
+        switch(op) {
+        case '*':
+            pe->v *= e2.v;
+            break;
+        case '/':  
+            if (e2.v == 0) {
+            div_error:
+                error("division by zero");
+            }
+            pe->v /= e2.v;
+            break;
+        case '%':  
+            if (e2.v == 0)
+                goto div_error;
+            pe->v %= e2.v;
+            break;
+        case TOK_SHL:
+            pe->v <<= e2.v;
+            break;
+        default:
+        case TOK_SAR:
+            pe->v >>= e2.v;
+            break;
+        }
+    }
+}
+
+static void asm_expr_logic(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_prod(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '&' && op != '|' && op != '^')
+            break;
+        next();
+        asm_expr_prod(s1, &e2);
+        if (pe->sym || e2.sym)
+            error("invalid operation with label");
+        switch(op) {
+        case '&':
+            pe->v &= e2.v;
+            break;
+        case '|':  
+            pe->v |= e2.v;
+            break;
+        default:
+        case '^':
+            pe->v ^= e2.v;
+            break;
+        }
+    }
+}
+
+static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_logic(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '+' && op != '-')
+            break;
+        next();
+        asm_expr_logic(s1, &e2);
+        if (op == '+') {
+            if (pe->sym != NULL && e2.sym != NULL)
+                goto cannot_relocate;
+            pe->v += e2.v;
+            if (pe->sym == NULL && e2.sym != NULL)
+                pe->sym = e2.sym;
+        } else {
+            pe->v -= e2.v;
+            /* NOTE: we are less powerful than gas in that case
+               because we store only one symbol in the expression */
+            if (!pe->sym && !e2.sym) {
+                /* OK */
+            } else if (pe->sym && !e2.sym) {
+                /* OK */
+            } else if (pe->sym && e2.sym) {
+                if (pe->sym == e2.sym) { 
+                    /* OK */
+                } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
+                    /* we also accept defined symbols in the same section */
+                    pe->v += (long)pe->sym->next - (long)e2.sym->next;
+                } else {
+                    goto cannot_relocate;
+                }
+                pe->sym = NULL; /* same symbols can be substracted to NULL */
+            } else {
+            cannot_relocate:
+                error("invalid operation with label");
+            }
+        }
+    }
+}
+
+static void asm_expr(TCCState *s1, ExprValue *pe)
+{
+    asm_expr_sum(s1, pe);
+}
+
+static int asm_int_expr(TCCState *s1)
+{
+    ExprValue e;
+    asm_expr(s1, &e);
+    if (e.sym)
+        expect("constant");
+    return e.v;
+}
+
+/* NOTE: the same name space as C labels is used to avoid using too
+   much memory when storing labels in TokenStrings */
+static void asm_new_label1(TCCState *s1, int label, int is_local,
+                           int sh_num, int value)
+{
+    Sym *sym;
+
+    sym = label_find(label);
+    if (sym) {
+        if (sym->r) {
+            /* the label is already defined */
+            if (!is_local) {
+                error("assembler label '%s' already defined", 
+                      get_tok_str(label, NULL));
+            } else {
+                /* redefinition of local labels is possible */
+                goto new_label;
+            }
+        }
+    } else {
+    new_label:
+        sym = label_push(&s1->asm_labels, label, 0);
+        sym->type.t = VT_STATIC | VT_VOID;
+    }
+    sym->r = sh_num;
+    sym->next = (void *)value;
+}
+
+static void asm_new_label(TCCState *s1, int label, int is_local)
+{
+    asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
+}
+
+static void asm_free_labels(TCCState *st)
+{
+    Sym *s, *s1;
+    Section *sec;
+    
+    for(s = st->asm_labels; s != NULL; s = s1) {
+        s1 = s->prev;
+        /* define symbol value in object file */
+        if (s->r) {
+            if (s->r == SHN_ABS)
+                sec = SECTION_ABS;
+            else
+                sec = st->sections[s->r];
+            put_extern_sym2(s, sec, (long)s->next, 0, 0);
+        }
+        /* remove label */
+        table_ident[s->v - TOK_IDENT]->sym_label = NULL;
+        sym_free(s);
+    }
+    st->asm_labels = NULL;
+}
+
+static void use_section1(TCCState *s1, Section *sec)
+{
+    cur_text_section->data_offset = ind;
+    cur_text_section = sec;
+    ind = cur_text_section->data_offset;
+}
+
+static void use_section(TCCState *s1, const char *name)
+{
+    Section *sec;
+    sec = find_section(s1, name);
+    use_section1(s1, sec);
+}
+
+static void asm_parse_directive(TCCState *s1)
+{
+    int n, offset, v, size, tok1;
+    Section *sec;
+    uint8_t *ptr;
+
+    /* assembler directive */
+    next();
+    sec = cur_text_section;
+    switch(tok) {
+    case TOK_ASM_align:
+    case TOK_ASM_skip:
+    case TOK_ASM_space:
+        tok1 = tok;
+        next();
+        n = asm_int_expr(s1);
+        if (tok1 == TOK_ASM_align) {
+            if (n < 0 || (n & (n-1)) != 0)
+                error("alignment must be a positive power of two");
+            offset = (ind + n - 1) & -n;
+            size = offset - ind;
+            /* the section must have a compatible alignment */
+            if (sec->sh_addralign < n)
+                sec->sh_addralign = n;
+        } else {
+            size = n;
+        }
+        v = 0;
+        if (tok == ',') {
+            next();
+            v = asm_int_expr(s1);
+        }
+    zero_pad:
+        if (sec->sh_type != SHT_NOBITS) {
+            sec->data_offset = ind;
+            ptr = section_ptr_add(sec, size);
+            memset(ptr, v, size);
+        }
+        ind += size;
+        break;
+    case TOK_ASM_quad:
+        next();
+        for(;;) {
+            uint64_t vl;
+            const char *p;
+
+            p = tokc.cstr->data;
+            if (tok != TOK_PPNUM) {
+            error_constant:
+                error("64 bit constant");
+            }
+            vl = strtoll(p, (char **)&p, 0);
+            if (*p != '\0')
+                goto error_constant;
+            next();
+            if (sec->sh_type != SHT_NOBITS) {
+                /* XXX: endianness */
+                gen_le32(vl);
+                gen_le32(vl >> 32);
+            } else {
+                ind += 8;
+            }
+            if (tok != ',')
+                break;
+            next();
+        }
+        break;
+    case TOK_ASM_byte:
+        size = 1;
+        goto asm_data;
+    case TOK_ASM_word:
+    case TOK_SHORT:
+        size = 2;
+        goto asm_data;
+    case TOK_LONG:
+    case TOK_INT:
+        size = 4;
+    asm_data:
+        next();
+        for(;;) {
+            ExprValue e;
+            asm_expr(s1, &e);
+            if (sec->sh_type != SHT_NOBITS) {
+                if (size == 4) {
+                    gen_expr32(&e);
+                } else {
+                    if (e.sym)
+                        expect("constant");
+                    if (size == 1)
+                        g(e.v);
+                    else
+                        gen_le16(e.v);
+                }
+            } else {
+                ind += size;
+            }
+            if (tok != ',')
+                break;
+            next();
+        }
+        break;
+    case TOK_ASM_fill:
+        {
+            int repeat, size, val, i, j;
+            uint8_t repeat_buf[8];
+            next();
+            repeat = asm_int_expr(s1);
+            if (repeat < 0) {
+                error("repeat < 0; .fill ignored");
+                break;
+            }
+            size = 1;
+            val = 0;
+            if (tok == ',') {
+                next();
+                size = asm_int_expr(s1);
+                if (size < 0) {
+                    error("size < 0; .fill ignored");
+                    break;
+                }
+                if (size > 8)
+                    size = 8;
+                if (tok == ',') {
+                    next();
+                    val = asm_int_expr(s1);
+                }
+            }
+            /* XXX: endianness */
+            repeat_buf[0] = val;
+            repeat_buf[1] = val >> 8;
+            repeat_buf[2] = val >> 16;
+            repeat_buf[3] = val >> 24;
+            repeat_buf[4] = 0;
+            repeat_buf[5] = 0;
+            repeat_buf[6] = 0;
+            repeat_buf[7] = 0;
+            for(i = 0; i < repeat; i++) {
+                for(j = 0; j < size; j++) {
+                    g(repeat_buf[j]);
+                }
+            }
+        }
+        break;
+    case TOK_ASM_org:
+        {
+            unsigned long n;
+            next();
+            /* XXX: handle section symbols too */
+            n = asm_int_expr(s1);
+            if (n < ind)
+                error("attempt to .org backwards");
+            v = 0;
+            size = n - ind;
+            goto zero_pad;
+        }
+        break;
+    case TOK_ASM_globl:
+    case TOK_ASM_global:
+	{ 
+            Sym *sym;
+
+            next();
+            sym = label_find(tok);
+            if (!sym) {
+                sym = label_push(&s1->asm_labels, tok, 0);
+                sym->type.t = VT_VOID;
+            }
+            sym->type.t &= ~VT_STATIC;
+            next();
+	}
+	break;
+    case TOK_ASM_string:
+    case TOK_ASM_ascii:
+    case TOK_ASM_asciz:
+        {
+            const uint8_t *p;
+            int i, size, t;
+
+            t = tok;
+            next();
+            for(;;) {
+                if (tok != TOK_STR)
+                    expect("string constant");
+                p = tokc.cstr->data;
+                size = tokc.cstr->size;
+                if (t == TOK_ASM_ascii && size > 0)
+                    size--;
+                for(i = 0; i < size; i++)
+                    g(p[i]);
+                next();
+                if (tok == ',') {
+                    next();
+                } else if (tok != TOK_STR) {
+                    break;
+                }
+            }
+	}
+	break;
+    case TOK_ASM_text:
+    case TOK_ASM_data:
+    case TOK_ASM_bss:
+	{ 
+            char sname[64];
+            tok1 = tok;
+            n = 0;
+            next();
+            if (tok != ';' && tok != TOK_LINEFEED) {
+		n = asm_int_expr(s1);
+		next();
+            }
+            sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
+            use_section(s1, sname);
+	}
+	break;
+    case TOK_SECTION1:
+        {
+            char sname[256];
+
+            /* XXX: support more options */
+            next();
+            sname[0] = '\0';
+            while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
+                if (tok == TOK_STR)
+                    pstrcat(sname, sizeof(sname), tokc.cstr->data);
+                else
+                    pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
+                next();
+            }
+            if (tok == ',') {
+                /* skip section options */
+                next();
+                if (tok != TOK_STR)
+                    expect("string constant");
+                next();
+            }
+            last_text_section = cur_text_section;
+            use_section(s1, sname);
+        }
+        break;
+    case TOK_ASM_previous:
+        { 
+            Section *sec;
+            next();
+            if (!last_text_section)
+                error("no previous section referenced");
+            sec = cur_text_section;
+            use_section1(s1, last_text_section);
+            last_text_section = sec;
+        }
+        break;
+    default:
+        error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
+        break;
+    }
+}
+
+
+/* assemble a file */
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
+{
+    int opcode;
+
+#if 0
+    /* print stats about opcodes */
+    {
+        const ASMInstr *pa;
+        int freq[4];
+        int op_vals[500];
+        int nb_op_vals, i, j;
+
+        nb_op_vals = 0;
+        memset(freq, 0, sizeof(freq));
+        for(pa = asm_instrs; pa->sym != 0; pa++) {
+            freq[pa->nb_ops]++;
+            for(i=0;i<pa->nb_ops;i++) {
+                for(j=0;j<nb_op_vals;j++) {
+                    if (pa->op_type[i] == op_vals[j])
+                        goto found;
+                }
+                op_vals[nb_op_vals++] = pa->op_type[i];
+            found: ;
+            }
+        }
+        for(i=0;i<nb_op_vals;i++) {
+            int v = op_vals[i];
+            if ((v & (v - 1)) != 0)
+                printf("%3d: %08x\n", i, v);
+        }
+        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
+               sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
+               freq[0], freq[1], freq[2], freq[3]);
+    }
+#endif
+
+    /* XXX: undefine C labels */
+
+    ch = file->buf_ptr[0];
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+    parse_flags = PARSE_FLAG_ASM_COMMENTS;
+    if (do_preprocess)
+        parse_flags |= PARSE_FLAG_PREPROCESS;
+    next();
+    for(;;) {
+        if (tok == TOK_EOF)
+            break;
+        parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+    redo:
+        if (tok == '#') {
+            /* horrible gas comment */
+            while (tok != TOK_LINEFEED)
+                next();
+        } else if (tok == '.') {
+            asm_parse_directive(s1);
+        } else if (tok == TOK_PPNUM) {
+            const char *p;
+            int n;
+            p = tokc.cstr->data;
+            n = strtoul(p, (char **)&p, 10);
+            if (*p != '\0')
+                expect("':'");
+            /* new local label */
+            asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
+            next();
+            skip(':');
+            goto redo;
+        } else if (tok >= TOK_IDENT) {
+            /* instruction or label */
+            opcode = tok;
+            next();
+            if (tok == ':') {
+                /* new label */
+                asm_new_label(s1, opcode, 0);
+                next();
+                goto redo;
+            } else if (tok == '=') {
+                int n;
+                next();
+                n = asm_int_expr(s1);
+                asm_new_label1(s1, opcode, 0, SHN_ABS, n);
+                goto redo;
+            } else {
+                asm_opcode(s1, opcode);
+            }
+        }
+        /* end of line */
+        if (tok != ';' && tok != TOK_LINEFEED){
+            expect("end of line");
+        }
+        parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+        next();
+    }
+
+    asm_free_labels(s1);
+
+    return 0;
+}
+
+/* Assemble the current file */
+static int tcc_assemble(TCCState *s1, int do_preprocess)
+{
+    Sym *define_start;
+    int ret;
+
+    preprocess_init(s1);
+
+    /* default section is text */
+    cur_text_section = text_section;
+    ind = cur_text_section->data_offset;
+
+    define_start = define_stack;
+
+    ret = tcc_assemble_internal(s1, do_preprocess);
+
+    cur_text_section->data_offset = ind;
+
+    free_defines(define_start); 
+
+    return ret;
+}
+
+/********************************************************************/
+/* GCC inline asm support */
+
+/* assemble the string 'str' in the current C compilation unit without
+   C preprocessing. NOTE: str is modified by modifying the '\0' at the
+   end */
+static void tcc_assemble_inline(TCCState *s1, char *str, int len)
+{
+    BufferedFile *bf, *saved_file;
+    int saved_parse_flags, *saved_macro_ptr;
+
+    bf = tcc_malloc(sizeof(BufferedFile));
+    memset(bf, 0, sizeof(BufferedFile));
+    bf->fd = -1;
+    bf->buf_ptr = str;
+    bf->buf_end = str + len;
+    str[len] = CH_EOB;
+    /* same name as current file so that errors are correctly
+       reported */
+    pstrcpy(bf->filename, sizeof(bf->filename), file->filename);
+    bf->line_num = file->line_num;
+    saved_file = file;
+    file = bf;
+    saved_parse_flags = parse_flags;
+    saved_macro_ptr = macro_ptr;
+    macro_ptr = NULL;
+    
+    tcc_assemble_internal(s1, 0);
+
+    parse_flags = saved_parse_flags;
+    macro_ptr = saved_macro_ptr;
+    file = saved_file;
+    tcc_free(bf);
+}
+
+/* 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, 
+                           const char *name, const char **pp)
+{
+    int index;
+    TokenSym *ts;
+    const char *p;
+
+    if (isnum(*name)) {
+        index = 0;
+        while (isnum(*name)) {
+            index = (index * 10) + (*name) - '0';
+            name++;
+        }
+        if ((unsigned)index >= nb_operands)
+            index = -1;
+    } else if (*name == '[') {
+        name++;
+        p = strchr(name, ']');
+        if (p) {
+            ts = tok_alloc(name, p - name);
+            for(index = 0; index < nb_operands; index++) {
+                if (operands[index].id == ts->tok)
+                    goto found;
+            }
+            index = -1;
+        found:
+            name = p + 1;
+        } else {
+            index = -1;
+        }
+    } else {
+        index = -1;
+    }
+    if (pp)
+        *pp = name;
+    return index;
+}
+
+static void subst_asm_operands(ASMOperand *operands, int nb_operands, 
+                               int nb_outputs,
+                               CString *out_str, CString *in_str)
+{
+    int c, index, modifier;
+    const char *str;
+    ASMOperand *op;
+    SValue sv;
+
+    cstr_new(out_str);
+    str = in_str->data;
+    for(;;) {
+        c = *str++;
+        if (c == '%') {
+            if (*str == '%') {
+                str++;
+                goto add_char;
+            }
+            modifier = 0;
+            if (*str == 'c' || *str == 'n' ||
+                *str == 'b' || *str == 'w' || *str == 'h')
+                modifier = *str++;
+            index = find_constraint(operands, nb_operands, str, &str);
+            if (index < 0)
+                error("invalid operand reference after %%");
+            op = &operands[index];
+            sv = *op->vt;
+            if (op->reg >= 0) {
+                sv.r = op->reg;
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
+                    sv.r |= VT_LVAL;
+            }
+            subst_asm_operand(out_str, &sv, modifier);
+        } else {
+        add_char:
+            cstr_ccat(out_str, c);
+            if (c == '\0')
+                break;
+        }
+    }
+}
+
+
+static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
+                               int is_output)
+{
+    ASMOperand *op;
+    int nb_operands;
+
+    if (tok != ':') {
+        nb_operands = *nb_operands_ptr;
+        for(;;) {
+            if (nb_operands >= MAX_ASM_OPERANDS)
+                error("too many asm operands");
+            op = &operands[nb_operands++];
+            op->id = 0;
+            if (tok == '[') {
+                next();
+                if (tok < TOK_IDENT)
+                    expect("identifier");
+                op->id = tok;
+                next();
+                skip(']');
+            }
+            if (tok != TOK_STR)
+                expect("string constant");
+            op->constraint = tcc_malloc(tokc.cstr->size);
+            strcpy(op->constraint, tokc.cstr->data);
+            next();
+            skip('(');
+            gexpr();
+            if (is_output) {
+                test_lvalue();
+            } else {
+                /* we want to avoid LLOCAL case, except when the 'm'
+                   constraint is used. Note that it may come from
+                   register storage, so we need to convert (reg)
+                   case */
+                if ((vtop->r & VT_LVAL) &&
+                    ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
+                     (vtop->r & VT_VALMASK) < VT_CONST) &&
+                    !strchr(op->constraint, 'm')) {
+                    gv(RC_INT);
+                }
+            }
+            op->vt = vtop;
+            skip(')');
+            if (tok == ',') {
+                next();
+            } else {
+                break;
+            }
+        }
+        *nb_operands_ptr = nb_operands;
+    }
+}
+
+static void parse_asm_str(CString *astr)
+{
+    skip('(');
+    /* read the string */
+    if (tok != TOK_STR)
+        expect("string constant");
+    cstr_new(astr);
+    while (tok == TOK_STR) {
+        /* XXX: add \0 handling too ? */
+        cstr_cat(astr, tokc.cstr->data);
+        next();
+    }
+    cstr_ccat(astr, '\0');
+}
+
+/* parse the GCC asm() instruction */
+static void asm_instr(void)
+{
+    CString astr, astr1;
+    ASMOperand operands[MAX_ASM_OPERANDS];
+    int nb_inputs, nb_outputs, nb_operands, i, must_subst, out_reg;
+    uint8_t clobber_regs[NB_ASM_REGS];
+
+    next();
+    /* since we always generate the asm() instruction, we can ignore
+       volatile */
+    if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
+        next();
+    }
+    parse_asm_str(&astr);
+    nb_operands = 0;
+    nb_outputs = 0;
+    must_subst = 0;
+    memset(clobber_regs, 0, sizeof(clobber_regs));
+    if (tok == ':') {
+        next();
+        must_subst = 1;
+        /* output args */
+        parse_asm_operands(operands, &nb_operands, 1);
+        nb_outputs = nb_operands;
+        if (tok == ':') {
+            next();
+            if (tok != ')') {
+                /* input args */
+                parse_asm_operands(operands, &nb_operands, 0);
+                if (tok == ':') {
+                    /* clobber list */
+                    /* XXX: handle registers */
+                    next();
+                    for(;;) {
+                        if (tok != TOK_STR)
+                            expect("string constant");
+                        asm_clobber(clobber_regs, tokc.cstr->data);
+                        next();
+                        if (tok == ',') {
+                            next();
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    skip(')');
+    /* NOTE: we do not eat the ';' so that we can restore the current
+       token after the assembler parsing */
+    if (tok != ';')
+        expect("';'");
+    nb_inputs = nb_operands - nb_outputs;
+    
+    /* save all values in the memory */
+    save_regs(0);
+
+    /* compute constraints */
+    asm_compute_constraints(operands, nb_operands, nb_outputs, 
+                            clobber_regs, &out_reg);
+
+    /* substitute the operands in the asm string. No substitution is
+       done if no operands (GCC behaviour) */
+#ifdef ASM_DEBUG
+    printf("asm: \"%s\"\n", (char *)astr.data);
+#endif
+    if (must_subst) {
+        subst_asm_operands(operands, nb_operands, nb_outputs, &astr1, &astr);
+        cstr_free(&astr);
+    } else {
+        astr1 = astr;
+    }
+#ifdef ASM_DEBUG
+    printf("subst_asm: \"%s\"\n", (char *)astr1.data);
+#endif
+
+    /* generate loads */
+    asm_gen_code(operands, nb_operands, nb_outputs, 0, 
+                 clobber_regs, out_reg);    
+
+    /* assemble the string with tcc internal assembler */
+    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
+
+    /* restore the current C token */
+    next();
+
+    /* store the output values if needed */
+    asm_gen_code(operands, nb_operands, nb_outputs, 1, 
+                 clobber_regs, out_reg);
+    
+    /* free everything */
+    for(i=0;i<nb_operands;i++) {
+        ASMOperand *op;
+        op = &operands[i];
+        tcc_free(op->constraint);
+        vpop();
+    }
+    cstr_free(&astr1);
+}
+
+static void asm_global_instr(void)
+{
+    CString astr;
+
+    next();
+    parse_asm_str(&astr);
+    skip(')');
+    /* NOTE: we do not eat the ';' so that we can restore the current
+       token after the assembler parsing */
+    if (tok != ';')
+        expect("';'");
+    
+#ifdef ASM_DEBUG
+    printf("asm_global: \"%s\"\n", (char *)astr.data);
+#endif
+    cur_text_section = text_section;
+    ind = cur_text_section->data_offset;
+
+    /* assemble the string with tcc internal assembler */
+    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
+    
+    cur_text_section->data_offset = ind;
+
+    /* restore the current C token */
+    next();
+
+    cstr_free(&astr);
+}
diff --git a/tinyc/tcccoff.c b/tinyc/tcccoff.c
new file mode 100755
index 000000000..0dcbe50f0
--- /dev/null
+++ b/tinyc/tcccoff.c
@@ -0,0 +1,957 @@
+/*
+ *  COFF file handling for TCC
+ * 
+ *  Copyright (c) 2003, 2004 TK
+ *  Copyright (c) 2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "coff.h"
+
+#define MAXNSCNS 255		/* MAXIMUM NUMBER OF SECTIONS         */
+#define MAX_STR_TABLE 1000000
+AOUTHDR o_filehdr;		/* OPTIONAL (A.OUT) FILE HEADER       */
+
+SCNHDR section_header[MAXNSCNS];
+
+#define MAX_FUNCS 1000
+#define MAX_FUNC_NAME_LENGTH 128
+
+int nFuncs;
+char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+int LineNoFilePtr[MAX_FUNCS];
+int EndAddress[MAX_FUNCS];
+int LastLineNo[MAX_FUNCS];
+int FuncEntries[MAX_FUNCS];
+
+BOOL OutputTheSection(Section * sect);
+short int GetCoffFlags(const char *s);
+void SortSymbolTable(void);
+Section *FindSection(TCCState * s1, const char *sname);
+
+int C67_main_entry_point;
+
+int FindCoffSymbolIndex(const char *func_name);
+int nb_syms;
+
+typedef struct {
+    long tag;
+    long size;
+    long fileptr;
+    long nextsym;
+    short int dummy;
+} AUXFUNC;
+
+typedef struct {
+    long regmask;
+    unsigned short lineno;
+    unsigned short nentries;
+    int localframe;
+    int nextentry;
+    short int dummy;
+} AUXBF;
+
+typedef struct {
+    long dummy;
+    unsigned short lineno;
+    unsigned short dummy1;
+    int dummy2;
+    int dummy3;
+    unsigned short dummy4;
+} AUXEF;
+
+int tcc_output_coff(TCCState *s1, FILE *f)
+{
+    Section *tcc_sect;
+    SCNHDR *coff_sec;
+    int file_pointer;
+    char *Coff_str_table, *pCoff_str_table;
+    int CoffTextSectionNo, coff_nb_syms;
+    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
+    Section *stext, *sdata, *sbss;
+    int i, NSectionsToOutput = 0;
+
+    Coff_str_table = pCoff_str_table = NULL;
+
+    stext = FindSection(s1, ".text");
+    sdata = FindSection(s1, ".data");
+    sbss = FindSection(s1, ".bss");
+
+    nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
+    coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
+
+    file_hdr.f_magic = COFF_C67_MAGIC;	/* magic number */
+    file_hdr.f_timdat = 0;	/* time & date stamp */
+    file_hdr.f_opthdr = sizeof(AOUTHDR);	/* sizeof(optional hdr) */
+    file_hdr.f_flags = 0x1143;	/* flags (copied from what code composer does) */
+    file_hdr.f_TargetID = 0x99;	/* for C6x = 0x0099 */
+
+    o_filehdr.magic = 0x0108;	/* see magic.h                          */
+    o_filehdr.vstamp = 0x0190;	/* version stamp                        */
+    o_filehdr.tsize = stext->data_offset;	/* text size in bytes, padded to FW bdry */
+    o_filehdr.dsize = sdata->data_offset;	/* initialized data "  "                */
+    o_filehdr.bsize = sbss->data_offset;	/* uninitialized data "   "             */
+    o_filehdr.entrypt = C67_main_entry_point;	/* entry pt.                          */
+    o_filehdr.text_start = stext->sh_addr;	/* base of text used for this file      */
+    o_filehdr.data_start = sdata->sh_addr;	/* base of data used for this file      */
+
+
+    // create all the section headers
+
+    file_pointer = FILHSZ + sizeof(AOUTHDR);
+
+    CoffTextSectionNo = -1;
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    NSectionsToOutput++;
+
+	    if (CoffTextSectionNo == -1 && tcc_sect == stext)
+		CoffTextSectionNo = NSectionsToOutput;	// rem which coff sect number the .text sect is
+
+	    strcpy(coff_sec->s_name, tcc_sect->name);	/* section name */
+
+	    coff_sec->s_paddr = tcc_sect->sh_addr;	/* physical address */
+	    coff_sec->s_vaddr = tcc_sect->sh_addr;	/* virtual address */
+	    coff_sec->s_size = tcc_sect->data_offset;	/* section size */
+	    coff_sec->s_scnptr = 0;	/* file ptr to raw data for section */
+	    coff_sec->s_relptr = 0;	/* file ptr to relocation */
+	    coff_sec->s_lnnoptr = 0;	/* file ptr to line numbers */
+	    coff_sec->s_nreloc = 0;	/* number of relocation entries */
+	    coff_sec->s_flags = GetCoffFlags(coff_sec->s_name);	/* flags */
+	    coff_sec->s_reserved = 0;	/* reserved byte */
+	    coff_sec->s_page = 0;	/* memory page id */
+
+	    file_pointer += sizeof(SCNHDR);
+	}
+    }
+
+    file_hdr.f_nscns = NSectionsToOutput;	/* number of sections */
+
+    // now loop through and determine file pointer locations
+    // for the raw data
+
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put raw data
+	    coff_sec->s_scnptr = file_pointer;	/* file ptr to raw data for section */
+	    file_pointer += coff_sec->s_size;
+	}
+    }
+
+    // now loop through and determine file pointer locations
+    // for the relocation data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put relocations data
+	    if (coff_sec->s_nreloc > 0) {
+		coff_sec->s_relptr = file_pointer;	/* file ptr to relocation */
+		file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
+	    }
+	}
+    }
+
+    // now loop through and determine file pointer locations
+    // for the line number data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	coff_sec->s_nlnno = 0;
+	coff_sec->s_lnnoptr = 0;
+
+	if (s1->do_debug && tcc_sect == stext) {
+	    // count how many line nos data
+
+	    // also find association between source file name and function
+	    // so we can sort the symbol table
+
+
+	    Stab_Sym *sym, *sym_end;
+	    char func_name[MAX_FUNC_NAME_LENGTH],
+		last_func_name[MAX_FUNC_NAME_LENGTH];
+	    unsigned long func_addr, last_pc, pc;
+	    const char *incl_files[INCLUDE_STACK_SIZE];
+	    int incl_index, len, last_line_num;
+	    const char *str, *p;
+
+	    coff_sec->s_lnnoptr = file_pointer;	/* file ptr to linno */
+
+
+	    func_name[0] = '\0';
+	    func_addr = 0;
+	    incl_index = 0;
+	    last_func_name[0] = '\0';
+	    last_pc = 0xffffffff;
+	    last_line_num = 1;
+	    sym = (Stab_Sym *) stab_section->data + 1;
+	    sym_end =
+		(Stab_Sym *) (stab_section->data +
+			      stab_section->data_offset);
+
+	    nFuncs = 0;
+	    while (sym < sym_end) {
+		switch (sym->n_type) {
+		    /* function start or end */
+		case N_FUN:
+		    if (sym->n_strx == 0) {
+			// end of function
+
+			coff_sec->s_nlnno++;
+			file_pointer += LINESZ;
+
+			pc = sym->n_value + func_addr;
+			func_name[0] = '\0';
+			func_addr = 0;
+			EndAddress[nFuncs] = pc;
+			FuncEntries[nFuncs] =
+			    (file_pointer -
+			     LineNoFilePtr[nFuncs]) / LINESZ - 1;
+			LastLineNo[nFuncs++] = last_line_num + 1;
+		    } else {
+			// beginning of function
+
+			LineNoFilePtr[nFuncs] = file_pointer;
+			coff_sec->s_nlnno++;
+			file_pointer += LINESZ;
+
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+
+			p = strchr(str, ':');
+			if (!p) {
+			    pstrcpy(func_name, sizeof(func_name), str);
+			    pstrcpy(Func[nFuncs], sizeof(func_name), str);
+			} else {
+			    len = p - str;
+			    if (len > sizeof(func_name) - 1)
+				len = sizeof(func_name) - 1;
+			    memcpy(func_name, str, len);
+			    memcpy(Func[nFuncs], str, len);
+			    func_name[len] = '\0';
+			}
+
+			// save the file that it came in so we can sort later
+			pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
+				incl_files[incl_index - 1]);
+
+			func_addr = sym->n_value;
+		    }
+		    break;
+
+		    /* line number info */
+		case N_SLINE:
+		    pc = sym->n_value + func_addr;
+
+		    last_pc = pc;
+		    last_line_num = sym->n_desc;
+
+		    /* XXX: slow! */
+		    strcpy(last_func_name, func_name);
+
+		    coff_sec->s_nlnno++;
+		    file_pointer += LINESZ;
+		    break;
+		    /* include files */
+		case N_BINCL:
+		    str =
+			(const char *) stabstr_section->data + sym->n_strx;
+		  add_incl:
+		    if (incl_index < INCLUDE_STACK_SIZE) {
+			incl_files[incl_index++] = str;
+		    }
+		    break;
+		case N_EINCL:
+		    if (incl_index > 1)
+			incl_index--;
+		    break;
+		case N_SO:
+		    if (sym->n_strx == 0) {
+			incl_index = 0;	/* end of translation unit */
+		    } else {
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+			/* do not add path */
+			len = strlen(str);
+			if (len > 0 && str[len - 1] != '/')
+			    goto add_incl;
+		    }
+		    break;
+		}
+		sym++;
+	    }
+	}
+
+    }
+
+    file_hdr.f_symptr = file_pointer;	/* file pointer to symtab */
+
+    if (s1->do_debug)
+	file_hdr.f_nsyms = coff_nb_syms;	/* number of symtab entries */
+    else
+	file_hdr.f_nsyms = 0;
+
+    file_pointer += file_hdr.f_nsyms * SYMNMLEN;
+
+    // OK now we are all set to write the file
+
+
+    fwrite(&file_hdr, FILHSZ, 1, f);
+    fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
+
+    // write section headers
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    fwrite(coff_sec, sizeof(SCNHDR), 1, f);
+	}
+    }
+
+    // write raw data
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
+	}
+    }
+
+    // write relocation data
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put relocations data
+	    if (coff_sec->s_nreloc > 0) {
+		fwrite(tcc_sect->reloc,
+		       coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
+	    }
+	}
+    }
+
+
+    // group the symbols in order of filename, func1, func2, etc
+    // finally global symbols
+
+    if (s1->do_debug)
+	SortSymbolTable();
+
+    // write line no data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (s1->do_debug && tcc_sect == stext) {
+	    // count how many line nos data
+
+
+	    Stab_Sym *sym, *sym_end;
+	    char func_name[128], last_func_name[128];
+	    unsigned long func_addr, last_pc, pc;
+	    const char *incl_files[INCLUDE_STACK_SIZE];
+	    int incl_index, len, last_line_num;
+	    const char *str, *p;
+
+	    LINENO CoffLineNo;
+
+	    func_name[0] = '\0';
+	    func_addr = 0;
+	    incl_index = 0;
+	    last_func_name[0] = '\0';
+	    last_pc = 0;
+	    last_line_num = 1;
+	    sym = (Stab_Sym *) stab_section->data + 1;
+	    sym_end =
+		(Stab_Sym *) (stab_section->data +
+			      stab_section->data_offset);
+
+	    while (sym < sym_end) {
+		switch (sym->n_type) {
+		    /* function start or end */
+		case N_FUN:
+		    if (sym->n_strx == 0) {
+			// end of function
+
+			CoffLineNo.l_addr.l_paddr = last_pc;
+			CoffLineNo.l_lnno = last_line_num + 1;
+			fwrite(&CoffLineNo, 6, 1, f);
+
+			pc = sym->n_value + func_addr;
+			func_name[0] = '\0';
+			func_addr = 0;
+		    } else {
+			// beginning of function
+
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+
+
+			p = strchr(str, ':');
+			if (!p) {
+			    pstrcpy(func_name, sizeof(func_name), str);
+			} else {
+			    len = p - str;
+			    if (len > sizeof(func_name) - 1)
+				len = sizeof(func_name) - 1;
+			    memcpy(func_name, str, len);
+			    func_name[len] = '\0';
+			}
+			func_addr = sym->n_value;
+			last_pc = func_addr;
+			last_line_num = -1;
+
+			// output a function begin
+
+			CoffLineNo.l_addr.l_symndx =
+			    FindCoffSymbolIndex(func_name);
+			CoffLineNo.l_lnno = 0;
+
+			fwrite(&CoffLineNo, 6, 1, f);
+		    }
+		    break;
+
+		    /* line number info */
+		case N_SLINE:
+		    pc = sym->n_value + func_addr;
+
+
+		    /* XXX: slow! */
+		    strcpy(last_func_name, func_name);
+
+		    // output a line reference
+
+		    CoffLineNo.l_addr.l_paddr = last_pc;
+
+		    if (last_line_num == -1) {
+			CoffLineNo.l_lnno = sym->n_desc;
+		    } else {
+			CoffLineNo.l_lnno = last_line_num + 1;
+		    }
+
+		    fwrite(&CoffLineNo, 6, 1, f);
+
+		    last_pc = pc;
+		    last_line_num = sym->n_desc;
+
+		    break;
+
+		    /* include files */
+		case N_BINCL:
+		    str =
+			(const char *) stabstr_section->data + sym->n_strx;
+		  add_incl2:
+		    if (incl_index < INCLUDE_STACK_SIZE) {
+			incl_files[incl_index++] = str;
+		    }
+		    break;
+		case N_EINCL:
+		    if (incl_index > 1)
+			incl_index--;
+		    break;
+		case N_SO:
+		    if (sym->n_strx == 0) {
+			incl_index = 0;	/* end of translation unit */
+		    } else {
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+			/* do not add path */
+			len = strlen(str);
+			if (len > 0 && str[len - 1] != '/')
+			    goto add_incl2;
+		    }
+		    break;
+		}
+		sym++;
+	    }
+	}
+    }
+
+    // write symbol table
+    if (s1->do_debug) {
+	int k;
+	struct syment csym;
+	AUXFUNC auxfunc;
+	AUXBF auxbf;
+	AUXEF auxef;
+	int i;
+	Elf32_Sym *p;
+	const char *name;
+	int nstr;
+	int n = 0;
+
+	Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
+	pCoff_str_table = Coff_str_table;
+	nstr = 0;
+
+	p = (Elf32_Sym *) symtab_section->data;
+
+
+	for (i = 0; i < nb_syms; i++) {
+
+	    name = symtab_section->link->data + p->st_name;
+
+	    for (k = 0; k < 8; k++)
+		csym._n._n_name[k] = 0;
+
+	    if (strlen(name) <= 8) {
+		strcpy(csym._n._n_name, name);
+	    } else {
+		if (pCoff_str_table - Coff_str_table + strlen(name) >
+		    MAX_STR_TABLE - 1)
+		    error("String table too large");
+
+		csym._n._n_n._n_zeroes = 0;
+		csym._n._n_n._n_offset =
+		    pCoff_str_table - Coff_str_table + 4;
+
+		strcpy(pCoff_str_table, name);
+		pCoff_str_table += strlen(name) + 1;	// skip over null
+		nstr++;
+	    }
+
+	    if (p->st_info == 4) {
+		// put a filename symbol
+		csym.n_value = 33;	// ?????
+		csym.n_scnum = N_DEBUG;
+		csym.n_type = 0;
+		csym.n_sclass = C_FILE;
+		csym.n_numaux = 0;
+		fwrite(&csym, 18, 1, f);
+		n++;
+
+	    } else if (p->st_info == 0x12) {
+		// find the function data
+
+		for (k = 0; k < nFuncs; k++) {
+		    if (strcmp(name, Func[k]) == 0)
+			break;
+		}
+
+		if (k >= nFuncs) {
+		    char s[256];
+
+		    sprintf(s, "debug info can't find function: %s", name);
+
+		    error(s);
+		}
+		// put a Function Name
+
+		csym.n_value = p->st_value;	// physical address
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
+		csym.n_sclass = C_EXT;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxfunc.tag = 0;
+		auxfunc.size = EndAddress[k] - p->st_value;
+		auxfunc.fileptr = LineNoFilePtr[k];
+		auxfunc.nextsym = n + 6;	// tktk
+		auxfunc.dummy = 0;
+		fwrite(&auxfunc, 18, 1, f);
+
+		// put a .bf
+
+		strcpy(csym._n._n_name, ".bf");
+		csym.n_value = p->st_value;	// physical address
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = 0;
+		csym.n_sclass = C_FCN;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxbf.regmask = 0;
+		auxbf.lineno = 0;
+		auxbf.nentries = FuncEntries[k];
+		auxbf.localframe = 0;
+		auxbf.nextentry = n + 6;
+		auxbf.dummy = 0;
+		fwrite(&auxbf, 18, 1, f);
+
+		// put a .ef
+
+		strcpy(csym._n._n_name, ".ef");
+		csym.n_value = EndAddress[k];	// physical address  
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = 0;
+		csym.n_sclass = C_FCN;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxef.dummy = 0;
+		auxef.lineno = LastLineNo[k];
+		auxef.dummy1 = 0;
+		auxef.dummy2 = 0;
+		auxef.dummy3 = 0;
+		auxef.dummy4 = 0;
+		fwrite(&auxef, 18, 1, f);
+
+		n += 6;
+
+	    } else {
+		// try an put some type info
+
+		if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
+		    csym.n_type = T_DOUBLE;	// int
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
+		    csym.n_type = T_FLOAT;
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_INT) {
+		    csym.n_type = T_INT;	// int
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
+		    csym.n_type = T_SHORT;
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
+		    csym.n_type = T_CHAR;
+		    csym.n_sclass = C_EXT;
+		} else {
+		    csym.n_type = T_INT;	// just mark as a label
+		    csym.n_sclass = C_LABEL;
+		}
+
+
+		csym.n_value = p->st_value;
+		csym.n_scnum = 2;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		auxfunc.tag = 0;
+		auxfunc.size = 0x20;
+		auxfunc.fileptr = 0;
+		auxfunc.nextsym = 0;
+		auxfunc.dummy = 0;
+		fwrite(&auxfunc, 18, 1, f);
+		n++;
+		n++;
+
+	    }
+
+	    p++;
+	}
+    }
+
+    if (s1->do_debug) {
+	// write string table
+
+	// first write the size
+	i = pCoff_str_table - Coff_str_table;
+	fwrite(&i, 4, 1, f);
+
+	// then write the strings
+	fwrite(Coff_str_table, i, 1, f);
+
+	tcc_free(Coff_str_table);
+    }
+
+    return 0;
+}
+
+
+
+// group the symbols in order of filename, func1, func2, etc
+// finally global symbols
+
+void SortSymbolTable(void)
+{
+    int i, j, k, n = 0;
+    Elf32_Sym *p, *p2, *NewTable;
+    char *name, *name2;
+
+    NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
+
+    p = (Elf32_Sym *) symtab_section->data;
+
+
+    // find a file symbol, copy it over
+    // then scan the whole symbol list and copy any function
+    // symbols that match the file association
+
+    for (i = 0; i < nb_syms; i++) {
+	if (p->st_info == 4) {
+	    name = (char *) symtab_section->link->data + p->st_name;
+
+	    // this is a file symbol, copy it over
+
+	    NewTable[n++] = *p;
+
+	    p2 = (Elf32_Sym *) symtab_section->data;
+
+	    for (j = 0; j < nb_syms; j++) {
+		if (p2->st_info == 0x12) {
+		    // this is a func symbol
+
+		    name2 =
+			(char *) symtab_section->link->data + p2->st_name;
+
+		    // find the function data index
+
+		    for (k = 0; k < nFuncs; k++) {
+			if (strcmp(name2, Func[k]) == 0)
+			    break;
+		    }
+
+		    if (k >= nFuncs) {
+			char s[256];
+
+			sprintf(s,
+				"debug (sort) info can't find function: %s",
+				name2);
+
+			error(s);
+		    }
+
+		    if (strcmp(AssociatedFile[k], name) == 0) {
+			// yes they match copy it over
+
+			NewTable[n++] = *p2;
+		    }
+		}
+		p2++;
+	    }
+	}
+	p++;
+    }
+
+    // now all the filename and func symbols should have been copied over
+    // copy all the rest over (all except file and funcs)
+
+    p = (Elf32_Sym *) symtab_section->data;
+    for (i = 0; i < nb_syms; i++) {
+	if (p->st_info != 4 && p->st_info != 0x12) {
+	    NewTable[n++] = *p;
+	}
+	p++;
+    }
+
+    if (n != nb_syms)
+	error("Internal Compiler error, debug info");
+
+    // copy it all back
+
+    p = (Elf32_Sym *) symtab_section->data;
+    for (i = 0; i < nb_syms; i++) {
+	*p++ = NewTable[i];
+    }
+
+    tcc_free(NewTable);
+}
+
+
+int FindCoffSymbolIndex(const char *func_name)
+{
+    int i, n = 0;
+    Elf32_Sym *p;
+    char *name;
+
+    p = (Elf32_Sym *) symtab_section->data;
+
+    for (i = 0; i < nb_syms; i++) {
+
+	name = (char *) symtab_section->link->data + p->st_name;
+
+	if (p->st_info == 4) {
+	    // put a filename symbol
+	    n++;
+	} else if (p->st_info == 0x12) {
+
+	    if (strcmp(func_name, name) == 0)
+		return n;
+
+	    n += 6;
+
+	    // put a Function Name
+
+	    // now put aux info
+
+	    // put a .bf
+
+	    // now put aux info
+
+	    // put a .ef
+
+	    // now put aux info
+
+	} else {
+	    n += 2;
+	}
+
+	p++;
+    }
+
+    return n;			// total number of symbols
+}
+
+BOOL OutputTheSection(Section * sect)
+{
+    const char *s = sect->name;
+
+    if (!strcmp(s, ".text"))
+	return true;
+    else if (!strcmp(s, ".data"))
+	return true;
+    else
+	return 0;
+}
+
+short int GetCoffFlags(const char *s)
+{
+    if (!strcmp(s, ".text"))
+	return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
+    else if (!strcmp(s, ".data"))
+	return STYP_DATA;
+    else if (!strcmp(s, ".bss"))
+	return STYP_BSS;
+    else if (!strcmp(s, ".stack"))
+	return STYP_BSS | STYP_ALIGN | 0x200;
+    else if (!strcmp(s, ".cinit"))
+	return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
+    else
+	return 0;
+}
+
+Section *FindSection(TCCState * s1, const char *sname)
+{
+    Section *s;
+    int i;
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	s = s1->sections[i];
+
+	if (!strcmp(sname, s->name))
+	    return s;
+    }
+
+    error("could not find section %s", sname);
+    return 0;
+}
+
+int tcc_load_coff(TCCState * s1, int fd)
+{
+// tktk TokenSym *ts;
+
+    FILE *f;
+    unsigned int str_size;
+    char *Coff_str_table, *name;
+    int i, k;
+    struct syment csym;
+    char name2[9];
+    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
+
+    f = fdopen(fd, "rb");
+    if (!f) {
+	error("Unable to open .out file for input");
+    }
+
+    if (fread(&file_hdr, FILHSZ, 1, f) != 1)
+	error("error reading .out file for input");
+
+    if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
+	error("error reading .out file for input");
+
+    // first read the string table
+
+    if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
+	error("error reading .out file for input");
+
+    if (fread(&str_size, sizeof(int), 1, f) != 1)
+	error("error reading .out file for input");
+
+
+    Coff_str_table = (char *) tcc_malloc(str_size);
+
+    if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
+	error("error reading .out file for input");
+
+    // read/process all the symbols
+
+    // seek back to symbols
+
+    if (fseek(f, file_hdr.f_symptr, SEEK_SET))
+	error("error reading .out file for input");
+
+    for (i = 0; i < file_hdr.f_nsyms; i++) {
+	if (fread(&csym, SYMESZ, 1, f) != 1)
+	    error("error reading .out file for input");
+
+	if (csym._n._n_n._n_zeroes == 0) {
+	    name = Coff_str_table + csym._n._n_n._n_offset - 4;
+	} else {
+	    name = csym._n._n_name;
+
+	    if (name[7] != 0) {
+		for (k = 0; k < 8; k++)
+		    name2[k] = name[k];
+
+		name2[8] = 0;
+
+		name = name2;
+	    }
+	}
+//              if (strcmp("_DAC_Buffer",name)==0)  // tktk
+//                      name[0]=0;
+
+	if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) ||	// structures
+	    (csym.n_type == 0x18 && csym.n_sclass == 0x2) ||	// pointer to structure
+	    (csym.n_type == 0x7 && csym.n_sclass == 0x2) ||	// doubles
+	    (csym.n_type == 0x6 && csym.n_sclass == 0x2))	// floats
+	{
+	    // strip off any leading underscore (except for other main routine)
+
+	    if (name[0] == '_' && strcmp(name, "_main") != 0)
+		name++;
+
+	    tcc_add_symbol(s1, name, (void*)csym.n_value);
+	}
+	// skip any aux records
+
+	if (csym.n_numaux == 1) {
+	    if (fread(&csym, SYMESZ, 1, f) != 1)
+		error("error reading .out file for input");
+	    i++;
+	}
+    }
+
+    return 0;
+}
diff --git a/tinyc/tccelf.c b/tinyc/tccelf.c
new file mode 100755
index 000000000..4020e249c
--- /dev/null
+++ b/tinyc/tccelf.c
@@ -0,0 +1,2732 @@
+/*
+ *  ELF file handling for TCC
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TCC_TARGET_X86_64
+#define ElfW_Rel ElfW(Rela)
+#define SHT_RELX SHT_RELA
+#define REL_SECTION_FMT ".rela%s"
+/* x86-64 requires PLT for DLLs */
+#define TCC_OUTPUT_DLL_WITH_PLT
+#else
+#define ElfW_Rel ElfW(Rel)
+#define SHT_RELX SHT_REL
+#define REL_SECTION_FMT ".rel%s"
+#endif
+
+/* 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)
+{
+    int offset, len;
+    char *ptr;
+
+    len = strlen(sym) + 1;
+    offset = s->data_offset;
+    ptr = section_ptr_add(s, len);
+    memcpy(ptr, sym, len);
+    return offset;
+}
+
+/* elf symbol hashing function */
+static unsigned long elf_hash(const unsigned char *name)
+{
+    unsigned long h = 0, g;
+    
+    while (*name) {
+        h = (h << 4) + *name++;
+        g = h & 0xf0000000;
+        if (g)
+            h ^= g >> 24;
+        h &= ~g;
+    }
+    return h;
+}
+
+/* rebuild hash table of section s */
+/* NOTE: we do factorize the hash table code to go faster */
+static void rebuild_hash(Section *s, unsigned int nb_buckets)
+{
+    ElfW(Sym) *sym;
+    int *ptr, *hash, nb_syms, sym_index, h;
+    char *strtab;
+
+    strtab = s->link->data;
+    nb_syms = s->data_offset / sizeof(ElfW(Sym));
+
+    s->hash->data_offset = 0;
+    ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
+    ptr[0] = nb_buckets;
+    ptr[1] = nb_syms;
+    ptr += 2;
+    hash = ptr;
+    memset(hash, 0, (nb_buckets + 1) * sizeof(int));
+    ptr += nb_buckets + 1;
+
+    sym = (ElfW(Sym) *)s->data + 1;
+    for(sym_index = 1; sym_index < nb_syms; sym_index++) {
+        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            h = elf_hash(strtab + sym->st_name) % nb_buckets;
+            *ptr = hash[h];
+            hash[h] = sym_index;
+        } else {
+            *ptr = 0;
+        }
+        ptr++;
+        sym++;
+    }
+}
+
+/* return the symbol number */
+static int put_elf_sym(Section *s, 
+                       unsigned long value, unsigned long size,
+                       int info, int other, int shndx, const char *name)
+{
+    int name_offset, sym_index;
+    int nbuckets, h;
+    ElfW(Sym) *sym;
+    Section *hs;
+    
+    sym = section_ptr_add(s, sizeof(ElfW(Sym)));
+    if (name)
+        name_offset = put_elf_str(s->link, name);
+    else
+        name_offset = 0;
+    /* XXX: endianness */
+    sym->st_name = name_offset;
+    sym->st_value = value;
+    sym->st_size = size;
+    sym->st_info = info;
+    sym->st_other = other;
+    sym->st_shndx = shndx;
+    sym_index = sym - (ElfW(Sym) *)s->data;
+    hs = s->hash;
+    if (hs) {
+        int *ptr, *base;
+        ptr = section_ptr_add(hs, sizeof(int));
+        base = (int *)hs->data;
+        /* only add global or weak symbols */
+        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
+            /* add another hashing entry */
+            nbuckets = base[0];
+            h = elf_hash(name) % nbuckets;
+            *ptr = base[2 + h];
+            base[2 + h] = sym_index;
+            base[1]++;
+            /* we resize the hash table */
+            hs->nb_hashed_syms++;
+            if (hs->nb_hashed_syms > 2 * nbuckets) {
+                rebuild_hash(s, 2 * nbuckets);
+            }
+        } else {
+            *ptr = 0;
+            base[1]++;
+        }
+    }
+    return sym_index;
+}
+
+/* find global ELF symbol 'name' and return its index. Return 0 if not
+   found. */
+static int find_elf_sym(Section *s, const char *name)
+{
+    ElfW(Sym) *sym;
+    Section *hs;
+    int nbuckets, sym_index, h;
+    const char *name1;
+    
+    hs = s->hash;
+    if (!hs)
+        return 0;
+    nbuckets = ((int *)hs->data)[0];
+    h = elf_hash(name) % nbuckets;
+    sym_index = ((int *)hs->data)[2 + h];
+    while (sym_index != 0) {
+        sym = &((ElfW(Sym) *)s->data)[sym_index];
+        name1 = s->link->data + sym->st_name;
+        if (!strcmp(name, name1))
+            return sym_index;
+        sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
+    }
+    return 0;
+}
+
+/* return elf symbol value or error */
+void *tcc_get_symbol(TCCState *s, const char *name)
+{
+    int sym_index;
+    ElfW(Sym) *sym;
+    sym_index = find_elf_sym(symtab_section, name);
+    if (!sym_index)
+        return NULL;
+    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+    return (void*)(long)sym->st_value;
+}
+
+void *tcc_get_symbol_err(TCCState *s, const char *name)
+{
+    void *sym;
+    sym = tcc_get_symbol(s, name);
+    if (!sym)
+        error("%s not defined", name);
+    return sym;
+}
+
+/* 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, unsigned long value, unsigned long size,
+                       int info, int other, int sh_num, const char *name)
+{
+    ElfW(Sym) *esym;
+    int sym_bind, sym_index, sym_type, esym_bind;
+    unsigned char sym_vis, esym_vis, new_vis;
+
+    sym_bind = ELFW(ST_BIND)(info);
+    sym_type = ELFW(ST_TYPE)(info);
+    sym_vis = ELFW(ST_VISIBILITY)(other);
+        
+    if (sym_bind != STB_LOCAL) {
+        /* we search global or weak symbols */
+        sym_index = find_elf_sym(s, name);
+        if (!sym_index)
+            goto do_def;
+        esym = &((ElfW(Sym) *)s->data)[sym_index];
+        if (esym->st_shndx != SHN_UNDEF) {
+            esym_bind = ELFW(ST_BIND)(esym->st_info);
+            /* propagate the most constraining visibility */
+            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
+            esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
+            if (esym_vis == STV_DEFAULT) {
+                new_vis = sym_vis;
+            } else if (sym_vis == STV_DEFAULT) {
+                new_vis = esym_vis;
+            } else {
+                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
+            }
+            esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+                             | new_vis;
+            other = esym->st_other; /* in case we have to patch esym */
+            if (sh_num == SHN_UNDEF) {
+                /* ignore adding of undefined symbol if the
+                   corresponding symbol is already defined */
+            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
+                /* global overrides weak, so patch */
+                goto do_patch;
+            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
+                /* weak is ignored if already global */
+            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
+                /* ignore hidden symbols after */
+            } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
+                /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
+                   No idea if this is the correct solution ... */
+                goto do_patch;
+            } else if (s == tcc_state->dynsymtab_section) {
+                /* we accept that two DLL define the same symbol */
+            } else {
+#if 1
+                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
+                       sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
+#endif
+                error_noabort("'%s' defined twice", name);
+            }
+        } else {
+        do_patch:
+            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
+            esym->st_shndx = sh_num;
+            esym->st_value = value;
+            esym->st_size = size;
+            esym->st_other = other;
+        }
+    } else {
+    do_def:
+        sym_index = put_elf_sym(s, value, size, 
+                                ELFW(ST_INFO)(sym_bind, sym_type), other, 
+                                sh_num, name);
+    }
+    return sym_index;
+}
+
+/* put relocation */
+static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+                          int type, int symbol)
+{
+    char buf[256];
+    Section *sr;
+    ElfW_Rel *rel;
+
+    sr = s->reloc;
+    if (!sr) {
+        /* if no relocation section, create it */
+        snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
+        /* if the symtab is allocated, then we consider the relocation
+           are also */
+        sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
+        sr->sh_entsize = sizeof(ElfW_Rel);
+        sr->link = symtab;
+        sr->sh_info = s->sh_num;
+        s->reloc = sr;
+    }
+    rel = section_ptr_add(sr, sizeof(ElfW_Rel));
+    rel->r_offset = offset;
+    rel->r_info = ELFW(R_INFO)(symbol, type);
+#ifdef TCC_TARGET_X86_64
+    rel->r_addend = 0;
+#endif
+}
+
+/* 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, 
+                      unsigned long value)
+{
+    Stab_Sym *sym;
+
+    sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
+    if (str) {
+        sym->n_strx = put_elf_str(stabstr_section, str);
+    } else {
+        sym->n_strx = 0;
+    }
+    sym->n_type = type;
+    sym->n_other = other;
+    sym->n_desc = desc;
+    sym->n_value = value;
+}
+
+static void put_stabs_r(const char *str, int type, int other, int desc, 
+                        unsigned long value, Section *sec, int sym_index)
+{
+    put_stabs(str, type, other, desc, value);
+    put_elf_reloc(symtab_section, stab_section, 
+                  stab_section->data_offset - sizeof(unsigned int),
+                  R_DATA_32, sym_index);
+}
+
+static 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)
+{
+    put_stabs(NULL, type, other, desc, 0);
+}
+
+/* In an ELF file symbol table, the local symbols must appear below
+   the global and weak ones. Since TCC cannot sort it while generating
+   the code, we must do it after. All the relocation tables are also
+   modified to take into account the symbol table sorting */
+static void sort_syms(TCCState *s1, Section *s)
+{
+    int *old_to_new_syms;
+    ElfW(Sym) *new_syms;
+    int nb_syms, i;
+    ElfW(Sym) *p, *q;
+    ElfW_Rel *rel, *rel_end;
+    Section *sr;
+    int type, sym_index;
+
+    nb_syms = s->data_offset / sizeof(ElfW(Sym));
+    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
+    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
+
+    /* first pass for local symbols */
+    p = (ElfW(Sym) *)s->data;
+    q = new_syms;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+    /* save the number of local symbols in section header */
+    s->sh_info = q - new_syms;
+
+    /* then second pass for non local symbols */
+    p = (ElfW(Sym) *)s->data;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+    
+    /* we copy the new symbols to the old */
+    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
+    tcc_free(new_syms);
+
+    /* now we modify all the relocations */
+    for(i = 1; i < s1->nb_sections; i++) {
+        sr = s1->sections[i];
+        if (sr->sh_type == SHT_RELX && sr->link == s) {
+            rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+            for(rel = (ElfW_Rel *)sr->data;
+                rel < rel_end;
+                rel++) {
+                sym_index = ELFW(R_SYM)(rel->r_info);
+                type = ELFW(R_TYPE)(rel->r_info);
+                sym_index = old_to_new_syms[sym_index];
+                rel->r_info = ELFW(R_INFO)(sym_index, type);
+            }
+        }
+    }
+    
+    tcc_free(old_to_new_syms);
+}
+
+/* relocate common symbols in the .bss section */
+static void relocate_common_syms(void)
+{
+    ElfW(Sym) *sym, *sym_end;
+    unsigned long offset, align;
+    
+    sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
+    for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
+        sym < sym_end;
+        sym++) {
+        if (sym->st_shndx == SHN_COMMON) {
+            /* align symbol */
+            align = sym->st_value;
+            offset = bss_section->data_offset;
+            offset = (offset + align - 1) & -align;
+            sym->st_value = offset;
+            sym->st_shndx = bss_section->sh_num;
+            offset += sym->st_size;
+            bss_section->data_offset = offset;
+        }
+    }
+}
+
+/* relocate symbol table, resolve undefined symbols if do_resolve is
+   true and output error if undefined symbol. */
+static void relocate_syms(TCCState *s1, int do_resolve)
+{
+    ElfW(Sym) *sym, *esym, *sym_end;
+    int sym_bind, sh_num, sym_index;
+    const char *name;
+    unsigned long addr;
+
+    sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
+    for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
+        sym < sym_end;
+        sym++) {
+        sh_num = sym->st_shndx;
+        if (sh_num == SHN_UNDEF) {
+            name = strtab_section->data + sym->st_name;
+            if (do_resolve) {
+                name = symtab_section->link->data + sym->st_name;
+                addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
+                if (addr) {
+                    sym->st_value = addr;
+                    goto found;
+                }
+            } else if (s1->dynsym) {
+                /* if dynamic symbol exist, then use it */
+                sym_index = find_elf_sym(s1->dynsym, name);
+                if (sym_index) {
+                    esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
+                    sym->st_value = esym->st_value;
+                    goto found;
+                }
+            }
+            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
+               it */
+            if (!strcmp(name, "_fp_hw"))
+                goto found;
+            /* only weak symbols are accepted to be undefined. Their
+               value is zero */
+            sym_bind = ELFW(ST_BIND)(sym->st_info);
+            if (sym_bind == STB_WEAK) {
+                sym->st_value = 0;
+            } else {
+                error_noabort("undefined symbol '%s'", name);
+            }
+        } else if (sh_num < SHN_LORESERVE) {
+            /* add section base */
+            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+        }
+    found: ;
+    }
+}
+
+#ifdef TCC_TARGET_X86_64
+#define JMP_TABLE_ENTRY_SIZE 14
+static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
+{
+    char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
+    s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
+    /* jmp *0x0(%rip) */
+    p[0] = 0xff;
+    p[1] = 0x25;
+    *(int *)(p + 2) = 0;
+    *(unsigned long *)(p + 6) = val;
+    return (unsigned long)p;
+}
+
+static unsigned long add_got_table(TCCState *s1, unsigned long val)
+{
+    unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
+                                        s1->runtime_plt_and_got_offset);
+    s1->runtime_plt_and_got_offset += sizeof(void *);
+    *p = val;
+    return (unsigned long)p;
+}
+#endif
+
+/* relocate a given section (CPU dependent) */
+static void relocate_section(TCCState *s1, Section *s)
+{
+    Section *sr;
+    ElfW_Rel *rel, *rel_end, *qrel;
+    ElfW(Sym) *sym;
+    int type, sym_index;
+    unsigned char *ptr;
+    unsigned long val, addr;
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+    int esym_index;
+#endif
+
+    sr = s->reloc;
+    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+    qrel = (ElfW_Rel *)sr->data;
+    for(rel = qrel;
+        rel < rel_end;
+        rel++) {
+        ptr = s->data + rel->r_offset;
+
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        val = sym->st_value;
+#ifdef TCC_TARGET_X86_64
+        /* XXX: not tested */
+        val += rel->r_addend;
+#endif
+        type = ELFW(R_TYPE)(rel->r_info);
+        addr = s->sh_addr + rel->r_offset;
+
+        /* CPU specific */
+        switch(type) {
+#if defined(TCC_TARGET_I386)
+        case R_386_32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                esym_index = s1->symtab_to_dynsym[sym_index];
+                qrel->r_offset = rel->r_offset;
+                if (esym_index) {
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
+                    qrel++;
+                    break;
+                } else {
+                    qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
+                    qrel++;
+                }
+            }
+            *(int *)ptr += val;
+            break;
+        case R_386_PC32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->symtab_to_dynsym[sym_index];
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
+                    qrel++;
+                    break;
+                }
+            }
+            *(int *)ptr += val - addr;
+            break;
+        case R_386_PLT32:
+            *(int *)ptr += val - addr;
+            break;
+        case R_386_GLOB_DAT:
+        case R_386_JMP_SLOT:
+            *(int *)ptr = val;
+            break;
+        case R_386_GOTPC:
+            *(int *)ptr += s1->got->sh_addr - addr;
+            break;
+        case R_386_GOTOFF:
+            *(int *)ptr += val - s1->got->sh_addr;
+            break;
+        case R_386_GOT32:
+            /* we load the got offset */
+            *(int *)ptr += s1->got_offsets[sym_index];
+            break;
+#elif defined(TCC_TARGET_ARM)
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+        case R_ARM_JUMP24:
+        case R_ARM_PLT32:
+            {
+                int x;
+                x = (*(int *)ptr)&0xffffff;
+                (*(int *)ptr) &= 0xff000000;
+                if (x & 0x800000)
+                    x -= 0x1000000;
+                x *= 4;
+                x += val - addr;
+                if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
+                    error("can't relocate value at %x",addr);
+                x >>= 2;
+                x &= 0xffffff;
+                (*(int *)ptr) |= x;
+            }
+            break;
+        case R_ARM_PREL31:
+            {
+                int x;
+                x = (*(int *)ptr) & 0x7fffffff;
+                (*(int *)ptr) &= 0x80000000;
+                x = (x * 2) / 2;
+                x += val - addr;
+                if((x^(x>>1))&0x40000000)
+                    error("can't relocate value at %x",addr);
+                (*(int *)ptr) |= x & 0x7fffffff;
+            }
+        case R_ARM_ABS32:
+            *(int *)ptr += val;
+            break;
+        case R_ARM_BASE_PREL:
+            *(int *)ptr += s1->got->sh_addr - addr;
+            break;
+        case R_ARM_GOTOFF32:
+            *(int *)ptr += val - s1->got->sh_addr;
+            break;
+        case R_ARM_GOT_BREL:
+            /* we load the got offset */
+            *(int *)ptr += s1->got_offsets[sym_index];
+            break;
+        case R_ARM_COPY:
+            break;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
+                    type,addr,(unsigned int )ptr,val);
+            break;
+#elif defined(TCC_TARGET_C67)
+        case R_C60_32:
+            *(int *)ptr += val;
+            break;
+        case R_C60LO16:
+            {
+                uint32_t orig;
+                
+                /* put the low 16 bits of the absolute address */
+                // add to what is already there
+                
+                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
+                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
+                
+                //patch both at once - assumes always in pairs Low - High
+                
+                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |  (((val+orig)      & 0xffff) << 7);
+                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
+            }
+            break;
+        case R_C60HI16:
+            break;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
+                    type,addr,(unsigned int )ptr,val);
+            break;
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_64:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                qrel->r_addend = *(long long *)ptr + val;
+                qrel++;
+            }
+            *(long long *)ptr += val;
+            break;
+        case R_X86_64_32:
+        case R_X86_64_32S:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* XXX: this logic may depend on TCC's codegen
+                   now TCC uses R_X86_64_32 even for a 64bit pointer */
+                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                qrel->r_addend = *(int *)ptr + val;
+                qrel++;
+            }
+            *(int *)ptr += val;
+            break;
+        case R_X86_64_PC32: {
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->symtab_to_dynsym[sym_index];
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
+                    qrel->r_addend = *(int *)ptr;
+                    qrel++;
+                    break;
+                }
+            }
+            long diff = val - addr;
+            if (diff <= -2147483647 || diff > 2147483647) {
+                /* XXX: naive support for over 32bit jump */
+                if (s1->output_type == TCC_OUTPUT_MEMORY) {
+                    val = add_jmp_table(s1, val);
+                    diff = val - addr;
+                }
+                if (diff <= -2147483647 || diff > 2147483647) {
+                    error("internal error: relocation failed");
+                }
+            }
+            *(int *)ptr += diff;
+        }
+            break;
+        case R_X86_64_PLT32:
+            *(int *)ptr += val - addr;
+            break;
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_JUMP_SLOT:
+            *(int *)ptr = val;
+            break;
+        case R_X86_64_GOTPCREL:
+            if (s1->output_type == TCC_OUTPUT_MEMORY) {
+                val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
+                *(int *)ptr += val - addr;
+                break;
+            }
+            *(int *)ptr += (s1->got->sh_addr - addr +
+                            s1->got_offsets[sym_index] - 4);
+            break;
+        case R_X86_64_GOTTPOFF:
+            *(int *)ptr += val - s1->got->sh_addr;
+            break;
+        case R_X86_64_GOT32:
+            /* we load the got offset */
+            *(int *)ptr += s1->got_offsets[sym_index];
+            break;
+#else
+#error unsupported processor
+#endif
+        }
+    }
+    /* if the relocation is allocated, we change its symbol table */
+    if (sr->sh_flags & SHF_ALLOC)
+        sr->link = s1->dynsym;
+}
+
+/* relocate relocation table in 'sr' */
+static void relocate_rel(TCCState *s1, Section *sr)
+{
+    Section *s;
+    ElfW_Rel *rel, *rel_end;
+    
+    s = s1->sections[sr->sh_info];
+    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+    for(rel = (ElfW_Rel *)sr->data;
+        rel < rel_end;
+        rel++) {
+        rel->r_offset += s->sh_addr;
+    }
+}
+
+/* count the number of dynamic relocations so that we can reserve
+   their space */
+static int prepare_dynamic_rel(TCCState *s1, Section *sr)
+{
+    ElfW_Rel *rel, *rel_end;
+    int sym_index, esym_index, type, count;
+
+    count = 0;
+    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+    for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        type = ELFW(R_TYPE)(rel->r_info);
+        switch(type) {
+#if defined(TCC_TARGET_I386)
+        case R_386_32:
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+#endif
+            count++;
+            break;
+#if defined(TCC_TARGET_I386)
+        case R_386_PC32:
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_PC32:
+#endif
+            esym_index = s1->symtab_to_dynsym[sym_index];
+            if (esym_index)
+                count++;
+            break;
+        default:
+            break;
+        }
+    }
+    if (count) {
+        /* allocate the section */
+        sr->sh_flags |= SHF_ALLOC;
+        sr->sh_size = count * sizeof(ElfW_Rel);
+    }
+    return count;
+}
+
+static void put_got_offset(TCCState *s1, int index, unsigned long val)
+{
+    int n;
+    unsigned long *tab;
+
+    if (index >= s1->nb_got_offsets) {
+        /* find immediately bigger power of 2 and reallocate array */
+        n = 1;
+        while (index >= n)
+            n *= 2;
+        tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
+        if (!tab)
+            error("memory full");
+        s1->got_offsets = tab;
+        memset(s1->got_offsets + s1->nb_got_offsets, 0,
+               (n - s1->nb_got_offsets) * sizeof(unsigned long));
+        s1->nb_got_offsets = n;
+    }
+    s1->got_offsets[index] = val;
+}
+
+/* XXX: suppress that */
+static void put32(unsigned char *p, uint32_t val)
+{
+    p[0] = val;
+    p[1] = val >> 8;
+    p[2] = val >> 16;
+    p[3] = val >> 24;
+}
+
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
+    defined(TCC_TARGET_X86_64)
+static uint32_t get32(unsigned char *p)
+{
+    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+#endif
+
+static void build_got(TCCState *s1)
+{
+    unsigned char *ptr;
+
+    /* if no got, then create it */
+    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+    s1->got->sh_entsize = 4;
+    add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT), 
+                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
+    ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
+#if PTR_SIZE == 4
+    /* keep space for _DYNAMIC pointer, if present */
+    put32(ptr, 0);
+    /* two dummy got entries */
+    put32(ptr + 4, 0);
+    put32(ptr + 8, 0);
+#else
+    /* keep space for _DYNAMIC pointer, if present */
+    put32(ptr, 0);
+    put32(ptr + 4, 0);
+    /* two dummy got entries */
+    put32(ptr + 8, 0);
+    put32(ptr + 12, 0);
+    put32(ptr + 16, 0);
+    put32(ptr + 20, 0);
+#endif
+}
+
+/* put a got entry corresponding to a symbol in symtab_section. 'size'
+   and 'info' can be modifed if more precise info comes from the DLL */
+static void put_got_entry(TCCState *s1,
+                          int reloc_type, unsigned long size, int info, 
+                          int sym_index)
+{
+    int index;
+    const char *name;
+    ElfW(Sym) *sym;
+    unsigned long offset;
+    int *ptr;
+
+    if (!s1->got)
+        build_got(s1);
+
+    /* if a got entry already exists for that symbol, no need to add one */
+    if (sym_index < s1->nb_got_offsets &&
+        s1->got_offsets[sym_index] != 0)
+        return;
+    
+    put_got_offset(s1, sym_index, s1->got->data_offset);
+
+    if (s1->dynsym) {
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        name = symtab_section->link->data + sym->st_name;
+        offset = sym->st_value;
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+        if (reloc_type ==
+#ifdef TCC_TARGET_X86_64
+            R_X86_64_JUMP_SLOT
+#else
+            R_386_JMP_SLOT
+#endif
+            ) {
+            Section *plt;
+            uint8_t *p;
+            int modrm;
+
+#if defined(TCC_OUTPUT_DLL_WITH_PLT)
+            modrm = 0x25;
+#else
+            /* if we build a DLL, we add a %ebx offset */
+            if (s1->output_type == TCC_OUTPUT_DLL)
+                modrm = 0xa3;
+            else
+                modrm = 0x25;
+#endif
+
+            /* add a PLT entry */
+            plt = s1->plt;
+            if (plt->data_offset == 0) {
+                /* first plt entry */
+                p = section_ptr_add(plt, 16);
+                p[0] = 0xff; /* pushl got + PTR_SIZE */
+                p[1] = modrm + 0x10;
+                put32(p + 2, PTR_SIZE);
+                p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+                p[7] = modrm;
+                put32(p + 8, PTR_SIZE * 2);
+            }
+
+            p = section_ptr_add(plt, 16);
+            p[0] = 0xff; /* jmp *(got + x) */
+            p[1] = modrm;
+            put32(p + 2, s1->got->data_offset);
+            p[6] = 0x68; /* push $xxx */
+            put32(p + 7, (plt->data_offset - 32) >> 1);
+            p[11] = 0xe9; /* jmp plt_start */
+            put32(p + 12, -(plt->data_offset));
+
+            /* the symbol is modified so that it will be relocated to
+               the PLT */
+#if !defined(TCC_OUTPUT_DLL_WITH_PLT)
+            if (s1->output_type == TCC_OUTPUT_EXE)
+#endif
+                offset = plt->data_offset - 16;
+        }
+#elif defined(TCC_TARGET_ARM)
+        if (reloc_type == R_ARM_JUMP_SLOT) {
+            Section *plt;
+            uint8_t *p;
+            
+            /* if we build a DLL, we add a %ebx offset */
+            if (s1->output_type == TCC_OUTPUT_DLL)
+                error("DLLs unimplemented!");
+
+            /* add a PLT entry */
+            plt = s1->plt;
+            if (plt->data_offset == 0) {
+                /* first plt entry */
+                p = section_ptr_add(plt, 16);
+                put32(p     , 0xe52de004);
+                put32(p +  4, 0xe59fe010);
+                put32(p +  8, 0xe08fe00e);
+                put32(p + 12, 0xe5bef008);
+            }
+
+            p = section_ptr_add(plt, 16);
+            put32(p  , 0xe59fc004);
+            put32(p+4, 0xe08fc00c);
+            put32(p+8, 0xe59cf000);
+            put32(p+12, s1->got->data_offset);
+
+            /* the symbol is modified so that it will be relocated to
+               the PLT */
+            if (s1->output_type == TCC_OUTPUT_EXE)
+                offset = plt->data_offset - 16;
+        }
+#elif defined(TCC_TARGET_C67)
+        error("C67 got not implemented");
+#else
+#error unsupported CPU
+#endif
+        index = put_elf_sym(s1->dynsym, offset, 
+                            size, info, 0, sym->st_shndx, name);
+        /* put a got entry */
+        put_elf_reloc(s1->dynsym, s1->got, 
+                      s1->got->data_offset, 
+                      reloc_type, index);
+    }
+    ptr = section_ptr_add(s1->got, PTR_SIZE);
+    *ptr = 0;
+}
+
+/* build GOT and PLT entries */
+static void build_got_entries(TCCState *s1)
+{
+    Section *s, *symtab;
+    ElfW_Rel *rel, *rel_end;
+    ElfW(Sym) *sym;
+    int i, type, reloc_type, sym_index;
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type != SHT_RELX)
+            continue;
+        /* no need to handle got relocations */
+        if (s->link != symtab_section)
+            continue;
+        symtab = s->link;
+        rel_end = (ElfW_Rel *)(s->data + s->data_offset);
+        for(rel = (ElfW_Rel *)s->data;
+            rel < rel_end;
+            rel++) {
+            type = ELFW(R_TYPE)(rel->r_info);
+            switch(type) {
+#if defined(TCC_TARGET_I386)
+            case R_386_GOT32:
+            case R_386_GOTOFF:
+            case R_386_GOTPC:
+            case R_386_PLT32:
+                if (!s1->got)
+                    build_got(s1);
+                if (type == R_386_GOT32 || type == R_386_PLT32) {
+                    sym_index = ELFW(R_SYM)(rel->r_info);
+                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                    /* look at the symbol got offset. If none, then add one */
+                    if (type == R_386_GOT32)
+                        reloc_type = R_386_GLOB_DAT;
+                    else
+                        reloc_type = R_386_JMP_SLOT;
+                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
+                                  sym_index);
+                }
+                break;
+#elif defined(TCC_TARGET_ARM)
+            case R_ARM_GOT_BREL:
+            case R_ARM_GOTOFF32:
+            case R_ARM_BASE_PREL:
+            case R_ARM_PLT32:
+                if (!s1->got)
+                    build_got(s1);
+                if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
+                    sym_index = ELFW(R_SYM)(rel->r_info);
+                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                    /* look at the symbol got offset. If none, then add one */
+                    if (type == R_ARM_GOT_BREL)
+                        reloc_type = R_ARM_GLOB_DAT;
+                    else
+                        reloc_type = R_ARM_JUMP_SLOT;
+                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
+                                  sym_index);
+                }
+                break;
+#elif defined(TCC_TARGET_C67)
+            case R_C60_GOT32:
+            case R_C60_GOTOFF:
+            case R_C60_GOTPC:
+            case R_C60_PLT32:
+                if (!s1->got)
+                    build_got(s1);
+                if (type == R_C60_GOT32 || type == R_C60_PLT32) {
+                    sym_index = ELFW(R_SYM)(rel->r_info);
+                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                    /* look at the symbol got offset. If none, then add one */
+                    if (type == R_C60_GOT32)
+                        reloc_type = R_C60_GLOB_DAT;
+                    else
+                        reloc_type = R_C60_JMP_SLOT;
+                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
+                                  sym_index);
+                }
+                break;
+#elif defined(TCC_TARGET_X86_64)
+            case R_X86_64_GOT32:
+            case R_X86_64_GOTTPOFF:
+            case R_X86_64_GOTPCREL:
+            case R_X86_64_PLT32:
+                if (!s1->got)
+                    build_got(s1);
+                if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
+                    type == R_X86_64_PLT32) {
+                    sym_index = ELFW(R_SYM)(rel->r_info);
+                    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                    /* look at the symbol got offset. If none, then add one */
+                    if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
+                        reloc_type = R_X86_64_GLOB_DAT;
+                    else
+                        reloc_type = R_X86_64_JUMP_SLOT;
+                    put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, 
+                                  sym_index);
+                }
+                break;
+#else
+#error unsupported CPU
+#endif
+            default:
+                break;
+            }
+        }
+    }
+}
+
+static Section *new_symtab(TCCState *s1,
+                           const char *symtab_name, int sh_type, int sh_flags,
+                           const char *strtab_name, 
+                           const char *hash_name, int hash_sh_flags)
+{
+    Section *symtab, *strtab, *hash;
+    int *ptr, nb_buckets;
+
+    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
+    symtab->sh_entsize = sizeof(ElfW(Sym));
+    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
+    put_elf_str(strtab, "");
+    symtab->link = strtab;
+    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
+    
+    nb_buckets = 1;
+
+    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
+    hash->sh_entsize = sizeof(int);
+    symtab->hash = hash;
+    hash->link = symtab;
+
+    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
+    ptr[0] = nb_buckets;
+    ptr[1] = 1;
+    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
+    return symtab;
+}
+
+/* put dynamic tag */
+static void put_dt(Section *dynamic, int dt, unsigned long val)
+{
+    ElfW(Dyn) *dyn;
+    dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
+    dyn->d_tag = dt;
+    dyn->d_un.d_val = val;
+}
+
+static void add_init_array_defines(TCCState *s1, const char *section_name)
+{
+    Section *s;
+    long end_offset;
+    char sym_start[1024];
+    char sym_end[1024];
+    
+    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
+    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
+
+    s = find_section(s1, section_name);
+    if (!s) {
+        end_offset = 0;
+        s = data_section;
+    } else {
+        end_offset = s->data_offset;
+    }
+
+    add_elf_sym(symtab_section, 
+                0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                s->sh_num, sym_start);
+    add_elf_sym(symtab_section, 
+                end_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                s->sh_num, sym_end);
+}
+
+/* add tcc runtime libraries */
+static void tcc_add_runtime(TCCState *s1)
+{
+#if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
+    char buf[1024];
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+    if (s1->do_bounds_check) {
+        unsigned long *ptr;
+        Section *init_section;
+        unsigned char *pinit;
+        int sym_index;
+
+        /* XXX: add an object file to do that */
+        ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
+        *ptr = 0;
+        add_elf_sym(symtab_section, 0, 0, 
+                    ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                    bounds_section->sh_num, "__bounds_start");
+        /* add bound check code */
+        snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o");
+        tcc_add_file(s1, buf);
+#ifdef TCC_TARGET_I386
+        if (s1->output_type != TCC_OUTPUT_MEMORY) {
+            /* add 'call __bound_init()' in .init section */
+            init_section = find_section(s1, ".init");
+            pinit = section_ptr_add(init_section, 5);
+            pinit[0] = 0xe8;
+            put32(pinit + 1, -4);
+            sym_index = find_elf_sym(symtab_section, "__bound_init");
+            put_elf_reloc(symtab_section, init_section, 
+                          init_section->data_offset - 4, R_386_PC32, sym_index);
+        }
+#endif
+    }
+#endif
+    /* add libc */
+    if (!s1->nostdlib) {
+        tcc_add_library(s1, "c");
+
+#ifdef CONFIG_USE_LIBGCC
+        tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
+#else
+        snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a");
+        tcc_add_file(s1, buf);
+#endif
+    }
+    /* add crt end if not memory output */
+    if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
+        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
+    }
+}
+
+/* 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)
+{
+    char buf[1024];
+    int i;
+    Section *s;
+
+    add_elf_sym(symtab_section, 
+                text_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                text_section->sh_num, "_etext");
+    add_elf_sym(symtab_section, 
+                data_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                data_section->sh_num, "_edata");
+    add_elf_sym(symtab_section, 
+                bss_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                bss_section->sh_num, "_end");
+    /* horrible new standard ldscript defines */
+    add_init_array_defines(s1, ".preinit_array");
+    add_init_array_defines(s1, ".init_array");
+    add_init_array_defines(s1, ".fini_array");
+    
+    /* add start and stop symbols for sections whose name can be
+       expressed in C */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type == SHT_PROGBITS &&
+            (s->sh_flags & SHF_ALLOC)) {
+            const char *p;
+            int ch;
+
+            /* check if section name can be expressed in C */
+            p = s->name;
+            for(;;) {
+                ch = *p;
+                if (!ch)
+                    break;
+                if (!isid(ch) && !isnum(ch))
+                    goto next_sec;
+                p++;
+            }
+            snprintf(buf, sizeof(buf), "__start_%s", s->name);
+            add_elf_sym(symtab_section, 
+                        0, 0,
+                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                        s->sh_num, buf);
+            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
+            add_elf_sym(symtab_section,
+                        s->data_offset, 0,
+                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                        s->sh_num, buf);
+        }
+    next_sec: ;
+    }
+}
+
+/* name of ELF interpreter */
+#if defined __FreeBSD__
+static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
+#elif defined TCC_ARM_EABI
+static char elf_interp[] = "/lib/ld-linux.so.3";
+#elif defined(TCC_TARGET_X86_64)
+static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
+#elif defined(TCC_UCLIBC)
+static char elf_interp[] = "/lib/ld-uClibc.so.0";
+#else
+static char elf_interp[] = "/lib/ld-linux.so.2";
+#endif
+
+static void tcc_output_binary(TCCState *s1, FILE *f,
+                              const int *section_order)
+{
+    Section *s;
+    int i, offset, size;
+
+    offset = 0;
+    for(i=1;i<s1->nb_sections;i++) {
+        s = s1->sections[section_order[i]];
+        if (s->sh_type != SHT_NOBITS &&
+            (s->sh_flags & SHF_ALLOC)) {
+            while (offset < s->sh_offset) {
+                fputc(0, f);
+                offset++;
+            }
+            size = s->sh_size;
+            fwrite(s->data, 1, size, f);
+            offset += size;
+        }
+    }
+}
+
+/* output an ELF file */
+/* XXX: suppress unneeded sections */
+int elf_output_file(TCCState *s1, const char *filename)
+{
+    ElfW(Ehdr) ehdr;
+    FILE *f;
+    int fd, mode, ret;
+    int *section_order;
+    int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
+    unsigned long addr;
+    Section *strsec, *s;
+    ElfW(Shdr) shdr, *sh;
+    ElfW(Phdr) *phdr, *ph;
+    Section *interp, *dynamic, *dynstr;
+    unsigned long saved_dynamic_data_offset;
+    ElfW(Sym) *sym;
+    int type, file_type;
+    unsigned long rel_addr, rel_size;
+    
+    file_type = s1->output_type;
+    s1->nb_errors = 0;
+
+    if (file_type != TCC_OUTPUT_OBJ) {
+        tcc_add_runtime(s1);
+    }
+
+    phdr = NULL;
+    section_order = NULL;
+    interp = NULL;
+    dynamic = NULL;
+    dynstr = NULL; /* avoid warning */
+    saved_dynamic_data_offset = 0; /* avoid warning */
+    
+    if (file_type != TCC_OUTPUT_OBJ) {
+        relocate_common_syms();
+
+        tcc_add_linker_symbols(s1);
+
+        if (!s1->static_link) {
+            const char *name;
+            int sym_index, index;
+            ElfW(Sym) *esym, *sym_end;
+            
+            if (file_type == TCC_OUTPUT_EXE) {
+                char *ptr;
+                /* add interpreter section only if executable */
+                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
+                interp->sh_addralign = 1;
+                ptr = section_ptr_add(interp, sizeof(elf_interp));
+                strcpy(ptr, elf_interp);
+            }
+        
+            /* add dynamic symbol table */
+            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
+                                    ".dynstr", 
+                                    ".hash", SHF_ALLOC);
+            dynstr = s1->dynsym->link;
+            
+            /* add dynamic section */
+            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC, 
+                                  SHF_ALLOC | SHF_WRITE);
+            dynamic->link = dynstr;
+            dynamic->sh_entsize = sizeof(ElfW(Dyn));
+        
+            /* add PLT */
+            s1->plt = new_section(s1, ".plt", SHT_PROGBITS, 
+                                  SHF_ALLOC | SHF_EXECINSTR);
+            s1->plt->sh_entsize = 4;
+
+            build_got(s1);
+
+            /* scan for undefined symbols and see if they are in the
+               dynamic symbols. If a symbol STT_FUNC is found, then we
+               add it in the PLT. If a symbol STT_OBJECT is found, we
+               add it in the .bss section with a suitable relocation */
+            sym_end = (ElfW(Sym) *)(symtab_section->data + 
+                                    symtab_section->data_offset);
+            if (file_type == TCC_OUTPUT_EXE) {
+                for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
+                    sym < sym_end;
+                    sym++) {
+                    if (sym->st_shndx == SHN_UNDEF) {
+                        name = symtab_section->link->data + sym->st_name;
+                        sym_index = find_elf_sym(s1->dynsymtab_section, name);
+                        if (sym_index) {
+                            esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
+                            type = ELFW(ST_TYPE)(esym->st_info);
+                            if (type == STT_FUNC) {
+                                put_got_entry(s1, R_JMP_SLOT, esym->st_size, 
+                                              esym->st_info, 
+                                              sym - (ElfW(Sym) *)symtab_section->data);
+                            } else if (type == STT_OBJECT) {
+                                unsigned long offset;
+                                offset = bss_section->data_offset;
+                                /* XXX: which alignment ? */
+                                offset = (offset + 16 - 1) & -16;
+                                index = put_elf_sym(s1->dynsym, offset, esym->st_size, 
+                                                    esym->st_info, 0, 
+                                                    bss_section->sh_num, name);
+                                put_elf_reloc(s1->dynsym, bss_section, 
+                                              offset, R_COPY, index);
+                                offset += esym->st_size;
+                                bss_section->data_offset = offset;
+                            }
+                        } else {
+                                /* STB_WEAK undefined symbols are accepted */
+                                /* XXX: _fp_hw seems to be part of the ABI, so we ignore
+                                   it */
+                            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
+                                !strcmp(name, "_fp_hw")) {
+                            } else {
+                                error_noabort("undefined symbol '%s'", name);
+                            }
+                        }
+                    } else if (s1->rdynamic && 
+                               ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+                        /* if -rdynamic option, then export all non
+                           local symbols */
+                        name = symtab_section->link->data + sym->st_name;
+                        put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
+                                    sym->st_info, 0, 
+                                    sym->st_shndx, name);
+                    }
+                }
+            
+                if (s1->nb_errors)
+                    goto fail;
+
+                /* now look at unresolved dynamic symbols and export
+                   corresponding symbol */
+                sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data + 
+                                        s1->dynsymtab_section->data_offset);
+                for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; 
+                    esym < sym_end;
+                    esym++) {
+                    if (esym->st_shndx == SHN_UNDEF) {
+                        name = s1->dynsymtab_section->link->data + esym->st_name;
+                        sym_index = find_elf_sym(symtab_section, name);
+                        if (sym_index) {
+                            /* XXX: avoid adding a symbol if already
+                               present because of -rdynamic ? */
+                            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                            put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
+                                        sym->st_info, 0, 
+                                        sym->st_shndx, name);
+                        } else {
+                            if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
+                                /* weak symbols can stay undefined */
+                            } else {
+                                warning("undefined dynamic symbol '%s'", name);
+                            }
+                        }
+                    }
+                }
+            } else {
+                int nb_syms;
+                /* shared library case : we simply export all the global symbols */
+                nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
+                s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
+                for(sym = (ElfW(Sym) *)symtab_section->data + 1; 
+                    sym < sym_end;
+                    sym++) {
+                    if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+#if defined(TCC_OUTPUT_DLL_WITH_PLT)
+                        if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
+                            sym->st_shndx == SHN_UNDEF) {
+                            put_got_entry(s1, R_JMP_SLOT, sym->st_size, 
+                                          sym->st_info, 
+                                          sym - (ElfW(Sym) *)symtab_section->data);
+                        }
+                        else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
+                            put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, 
+                                          sym->st_info, 
+                                          sym - (ElfW(Sym) *)symtab_section->data);
+                        }
+                        else
+#endif
+                        {
+                            name = symtab_section->link->data + sym->st_name;
+                            index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, 
+                                                sym->st_info, 0, 
+                                                sym->st_shndx, name);
+                            s1->symtab_to_dynsym[sym - 
+                                                 (ElfW(Sym) *)symtab_section->data] = 
+                                index;
+                        }
+                    }
+                }
+            }
+
+            build_got_entries(s1);
+        
+            /* add a list of needed dlls */
+            for(i = 0; i < s1->nb_loaded_dlls; i++) {
+                DLLReference *dllref = s1->loaded_dlls[i];
+                if (dllref->level == 0)
+                    put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
+            }
+            /* XXX: currently, since we do not handle PIC code, we
+               must relocate the readonly segments */
+            if (file_type == TCC_OUTPUT_DLL) {
+                if (s1->soname)
+                    put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
+                put_dt(dynamic, DT_TEXTREL, 0);
+            }
+
+            /* add necessary space for other entries */
+            saved_dynamic_data_offset = dynamic->data_offset;
+            dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
+        } else {
+            /* still need to build got entries in case of static link */
+            build_got_entries(s1);
+        }
+    }
+
+    memset(&ehdr, 0, sizeof(ehdr));
+
+    /* we add a section for symbols */
+    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
+    put_elf_str(strsec, "");
+    
+    /* compute number of sections */
+    shnum = s1->nb_sections;
+
+    /* this array is used to reorder sections in the output file */
+    section_order = tcc_malloc(sizeof(int) * shnum);
+    section_order[0] = 0;
+    sh_order_index = 1;
+    
+    /* compute number of program headers */
+    switch(file_type) {
+    default:
+    case TCC_OUTPUT_OBJ:
+        phnum = 0;
+        break;
+    case TCC_OUTPUT_EXE:
+        if (!s1->static_link)
+            phnum = 4;
+        else
+            phnum = 2;
+        break;
+    case TCC_OUTPUT_DLL:
+        phnum = 3;
+        break;
+    }
+
+    /* allocate strings for section names and decide if an unallocated
+       section should be output */
+    /* NOTE: the strsec section comes last, so its size is also
+       correct ! */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        s->sh_name = put_elf_str(strsec, s->name);
+#if 0 //gr       
+        printf("section: f=%08x t=%08x i=%08x %s %s\n", 
+               s->sh_flags, 
+               s->sh_type, 
+               s->sh_info, 
+               s->name, 
+               s->reloc ? s->reloc->name : "n"
+               ); 
+#endif
+        /* when generating a DLL, we include relocations but we may
+           patch them */
+        if (file_type == TCC_OUTPUT_DLL && 
+            s->sh_type == SHT_RELX && 
+            !(s->sh_flags & SHF_ALLOC)) {
+            /* //gr: avoid bogus relocs for empty (debug) sections */
+            if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
+                prepare_dynamic_rel(s1, s);
+            else if (s1->do_debug)
+                s->sh_size = s->data_offset;
+        } else if (s1->do_debug ||
+            file_type == TCC_OUTPUT_OBJ || 
+            (s->sh_flags & SHF_ALLOC) ||
+            i == (s1->nb_sections - 1)) {
+            /* we output all sections if debug or object file */
+            s->sh_size = s->data_offset;
+        }
+    }
+
+    /* allocate program segment headers */
+    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
+        
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+        file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+    } else {
+        file_offset = 0;
+    }
+    if (phnum > 0) {
+        /* compute section to program header mapping */
+        if (s1->has_text_addr) { 
+            int a_offset, p_offset;
+            addr = s1->text_addr;
+            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
+               ELF_PAGE_SIZE */
+            a_offset = addr & (ELF_PAGE_SIZE - 1);
+            p_offset = file_offset & (ELF_PAGE_SIZE - 1);
+            if (a_offset < p_offset) 
+                a_offset += ELF_PAGE_SIZE;
+            file_offset += (a_offset - p_offset);
+        } else {
+            if (file_type == TCC_OUTPUT_DLL)
+                addr = 0;
+            else
+                addr = ELF_START_ADDR;
+            /* compute address after headers */
+            addr += (file_offset & (ELF_PAGE_SIZE - 1));
+        }
+        
+        /* dynamic relocation table information, for .dynamic section */
+        rel_size = 0;
+        rel_addr = 0;
+
+        /* leave one program header for the program interpreter */
+        ph = &phdr[0];
+        if (interp)
+            ph++;
+
+        for(j = 0; j < 2; j++) {
+            ph->p_type = PT_LOAD;
+            if (j == 0)
+                ph->p_flags = PF_R | PF_X;
+            else
+                ph->p_flags = PF_R | PF_W;
+            ph->p_align = ELF_PAGE_SIZE;
+            
+            /* we do the following ordering: interp, symbol tables,
+               relocations, progbits, nobits */
+            /* XXX: do faster and simpler sorting */
+            for(k = 0; k < 5; k++) {
+                for(i = 1; i < s1->nb_sections; i++) {
+                    s = s1->sections[i];
+                    /* compute if section should be included */
+                    if (j == 0) {
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
+                            SHF_ALLOC)
+                            continue;
+                    } else {
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != 
+                            (SHF_ALLOC | SHF_WRITE))
+                            continue;
+                    }
+                    if (s == interp) {
+                        if (k != 0)
+                            continue;
+                    } else if (s->sh_type == SHT_DYNSYM ||
+                               s->sh_type == SHT_STRTAB ||
+                               s->sh_type == SHT_HASH) {
+                        if (k != 1)
+                            continue;
+                    } else if (s->sh_type == SHT_RELX) {
+                        if (k != 2)
+                            continue;
+                    } else if (s->sh_type == SHT_NOBITS) {
+                        if (k != 4)
+                            continue;
+                    } else {
+                        if (k != 3)
+                            continue;
+                    }
+                    section_order[sh_order_index++] = i;
+
+                    /* section matches: we align it and add its size */
+                    tmp = addr;
+                    addr = (addr + s->sh_addralign - 1) & 
+                        ~(s->sh_addralign - 1);
+                    file_offset += addr - tmp;
+                    s->sh_offset = file_offset;
+                    s->sh_addr = addr;
+                    
+                    /* update program header infos */
+                    if (ph->p_offset == 0) {
+                        ph->p_offset = file_offset;
+                        ph->p_vaddr = addr;
+                        ph->p_paddr = ph->p_vaddr;
+                    }
+                    /* update dynamic relocation infos */
+                    if (s->sh_type == SHT_RELX) {
+                        if (rel_size == 0)
+                            rel_addr = addr;
+                        rel_size += s->sh_size;
+                    }
+                    addr += s->sh_size;
+                    if (s->sh_type != SHT_NOBITS)
+                        file_offset += s->sh_size;
+                }
+            }
+            ph->p_filesz = file_offset - ph->p_offset;
+            ph->p_memsz = addr - ph->p_vaddr;
+            ph++;
+            if (j == 0) {
+                if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+                    /* if in the middle of a page, we duplicate the page in
+                       memory so that one copy is RX and the other is RW */
+                    if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
+                        addr += ELF_PAGE_SIZE;
+                } else {
+                    addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
+                    file_offset = (file_offset + ELF_PAGE_SIZE - 1) & 
+                        ~(ELF_PAGE_SIZE - 1);
+                }
+            }
+        }
+
+        /* if interpreter, then add corresponing program header */
+        if (interp) {
+            ph = &phdr[0];
+            
+            ph->p_type = PT_INTERP;
+            ph->p_offset = interp->sh_offset;
+            ph->p_vaddr = interp->sh_addr;
+            ph->p_paddr = ph->p_vaddr;
+            ph->p_filesz = interp->sh_size;
+            ph->p_memsz = interp->sh_size;
+            ph->p_flags = PF_R;
+            ph->p_align = interp->sh_addralign;
+        }
+        
+        /* if dynamic section, then add corresponing program header */
+        if (dynamic) {
+            ElfW(Sym) *sym_end;
+
+            ph = &phdr[phnum - 1];
+            
+            ph->p_type = PT_DYNAMIC;
+            ph->p_offset = dynamic->sh_offset;
+            ph->p_vaddr = dynamic->sh_addr;
+            ph->p_paddr = ph->p_vaddr;
+            ph->p_filesz = dynamic->sh_size;
+            ph->p_memsz = dynamic->sh_size;
+            ph->p_flags = PF_R | PF_W;
+            ph->p_align = dynamic->sh_addralign;
+
+            /* put GOT dynamic section address */
+            put32(s1->got->data, dynamic->sh_addr);
+
+            /* relocate the PLT */
+            if (file_type == TCC_OUTPUT_EXE
+#if defined(TCC_OUTPUT_DLL_WITH_PLT)
+                || file_type == TCC_OUTPUT_DLL
+#endif
+                ) {
+                uint8_t *p, *p_end;
+
+                p = s1->plt->data;
+                p_end = p + s1->plt->data_offset;
+                if (p < p_end) {
+#if defined(TCC_TARGET_I386)
+                    put32(p + 2, get32(p + 2) + s1->got->sh_addr);
+                    put32(p + 8, get32(p + 8) + s1->got->sh_addr);
+                    p += 16;
+                    while (p < p_end) {
+                        put32(p + 2, get32(p + 2) + s1->got->sh_addr);
+                        p += 16;
+                    }
+#elif defined(TCC_TARGET_X86_64)
+                    int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
+                    put32(p + 2, get32(p + 2) + x);
+                    put32(p + 8, get32(p + 8) + x - 6);
+                    p += 16;
+                    while (p < p_end) {
+                        put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
+                        p += 16;
+                    }
+#elif defined(TCC_TARGET_ARM)
+                    int x;
+                    x=s1->got->sh_addr - s1->plt->sh_addr - 12;
+                    p +=16;
+                    while (p < p_end) {
+                        put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
+                        p += 16;
+                    }
+#elif defined(TCC_TARGET_C67)
+                    /* XXX: TODO */
+#else
+#error unsupported CPU
+#endif
+                }
+            }
+
+            /* relocate symbols in .dynsym */
+            sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
+            for(sym = (ElfW(Sym) *)s1->dynsym->data + 1; 
+                sym < sym_end;
+                sym++) {
+                if (sym->st_shndx == SHN_UNDEF) {
+                    /* relocate to the PLT if the symbol corresponds
+                       to a PLT entry */
+                    if (sym->st_value)
+                        sym->st_value += s1->plt->sh_addr;
+                } else if (sym->st_shndx < SHN_LORESERVE) {
+                    /* do symbol relocation */
+                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+                }
+            }
+
+            /* put dynamic section entries */
+            dynamic->data_offset = saved_dynamic_data_offset;
+            put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
+            put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
+            put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
+            put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
+            put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
+#ifdef TCC_TARGET_X86_64
+            put_dt(dynamic, DT_RELA, rel_addr);
+            put_dt(dynamic, DT_RELASZ, rel_size);
+            put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
+#else
+            put_dt(dynamic, DT_REL, rel_addr);
+            put_dt(dynamic, DT_RELSZ, rel_size);
+            put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
+#endif
+            if (s1->do_debug)
+                put_dt(dynamic, DT_DEBUG, 0);
+            put_dt(dynamic, DT_NULL, 0);
+        }
+
+        ehdr.e_phentsize = sizeof(ElfW(Phdr));
+        ehdr.e_phnum = phnum;
+        ehdr.e_phoff = sizeof(ElfW(Ehdr));
+    }
+
+    /* all other sections come after */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
+            continue;
+        section_order[sh_order_index++] = i;
+        
+        file_offset = (file_offset + s->sh_addralign - 1) & 
+            ~(s->sh_addralign - 1);
+        s->sh_offset = file_offset;
+        if (s->sh_type != SHT_NOBITS)
+            file_offset += s->sh_size;
+    }
+    
+    /* if building executable or DLL, then relocate each section
+       except the GOT which is already relocated */
+    if (file_type != TCC_OUTPUT_OBJ) {
+        relocate_syms(s1, 0);
+
+        if (s1->nb_errors != 0) {
+        fail:
+            ret = -1;
+            goto the_end;
+        }
+
+        /* relocate sections */
+        /* XXX: ignore sections with allocated relocations ? */
+        for(i = 1; i < s1->nb_sections; i++) {
+            s = s1->sections[i];
+            if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
+                relocate_section(s1, s);
+        }
+
+        /* relocate relocation entries if the relocation tables are
+           allocated in the executable */
+        for(i = 1; i < s1->nb_sections; i++) {
+            s = s1->sections[i];
+            if ((s->sh_flags & SHF_ALLOC) &&
+                s->sh_type == SHT_RELX) {
+                relocate_rel(s1, s);
+            }
+        }
+
+        /* get entry point address */
+        if (file_type == TCC_OUTPUT_EXE)
+            ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
+        else
+            ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
+    }
+
+    /* write elf file */
+    if (file_type == TCC_OUTPUT_OBJ)
+        mode = 0666;
+    else
+        mode = 0777;
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode); 
+    if (fd < 0) {
+        error_noabort("could not write '%s'", filename);
+        goto fail;
+    }
+    f = fdopen(fd, "wb");
+    if (s1->verbose)
+        printf("<- %s\n", filename);
+
+#ifdef TCC_TARGET_COFF
+    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
+        tcc_output_coff(s1, f);
+    } else
+#endif
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+        sort_syms(s1, symtab_section);
+        
+        /* align to 4 */
+        file_offset = (file_offset + 3) & -4;
+    
+        /* fill header */
+        ehdr.e_ident[0] = ELFMAG0;
+        ehdr.e_ident[1] = ELFMAG1;
+        ehdr.e_ident[2] = ELFMAG2;
+        ehdr.e_ident[3] = ELFMAG3;
+        ehdr.e_ident[4] = TCC_ELFCLASS;
+        ehdr.e_ident[5] = ELFDATA2LSB;
+        ehdr.e_ident[6] = EV_CURRENT;
+#ifdef __FreeBSD__
+        ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+#ifdef TCC_TARGET_ARM
+#ifdef TCC_ARM_EABI
+        ehdr.e_ident[EI_OSABI] = 0;
+        ehdr.e_flags = 4 << 24;
+#else
+        ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
+#endif
+#endif
+        switch(file_type) {
+        default:
+        case TCC_OUTPUT_EXE:
+            ehdr.e_type = ET_EXEC;
+            break;
+        case TCC_OUTPUT_DLL:
+            ehdr.e_type = ET_DYN;
+            break;
+        case TCC_OUTPUT_OBJ:
+            ehdr.e_type = ET_REL;
+            break;
+        }
+        ehdr.e_machine = EM_TCC_TARGET;
+        ehdr.e_version = EV_CURRENT;
+        ehdr.e_shoff = file_offset;
+        ehdr.e_ehsize = sizeof(ElfW(Ehdr));
+        ehdr.e_shentsize = sizeof(ElfW(Shdr));
+        ehdr.e_shnum = shnum;
+        ehdr.e_shstrndx = shnum - 1;
+        
+        fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
+        fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
+        offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+
+        for(i=1;i<s1->nb_sections;i++) {
+            s = s1->sections[section_order[i]];
+            if (s->sh_type != SHT_NOBITS) {
+                while (offset < s->sh_offset) {
+                    fputc(0, f);
+                    offset++;
+                }
+                size = s->sh_size;
+                fwrite(s->data, 1, size, f);
+                offset += size;
+            }
+        }
+
+        /* output section headers */
+        while (offset < ehdr.e_shoff) {
+            fputc(0, f);
+            offset++;
+        }
+    
+        for(i=0;i<s1->nb_sections;i++) {
+            sh = &shdr;
+            memset(sh, 0, sizeof(ElfW(Shdr)));
+            s = s1->sections[i];
+            if (s) {
+                sh->sh_name = s->sh_name;
+                sh->sh_type = s->sh_type;
+                sh->sh_flags = s->sh_flags;
+                sh->sh_entsize = s->sh_entsize;
+                sh->sh_info = s->sh_info;
+                if (s->link)
+                    sh->sh_link = s->link->sh_num;
+                sh->sh_addralign = s->sh_addralign;
+                sh->sh_addr = s->sh_addr;
+                sh->sh_offset = s->sh_offset;
+                sh->sh_size = s->sh_size;
+            }
+            fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
+        }
+    } else {
+        tcc_output_binary(s1, f, section_order);
+    }
+    fclose(f);
+
+    ret = 0;
+ the_end:
+    tcc_free(s1->symtab_to_dynsym);
+    tcc_free(section_order);
+    tcc_free(phdr);
+    tcc_free(s1->got_offsets);
+    return ret;
+}
+
+int tcc_output_file(TCCState *s, const char *filename)
+{
+    int ret;
+#ifdef TCC_TARGET_PE
+    if (s->output_type != TCC_OUTPUT_OBJ) {
+        ret = pe_output_file(s, filename);
+    } else
+#endif
+    {
+        ret = elf_output_file(s, filename);
+    }
+    return ret;
+}
+
+static void *load_data(int fd, unsigned long file_offset, unsigned long size)
+{
+    void *data;
+
+    data = tcc_malloc(size);
+    lseek(fd, file_offset, SEEK_SET);
+    read(fd, data, size);
+    return data;
+}
+
+typedef struct SectionMergeInfo {
+    Section *s;            /* corresponding existing section */
+    unsigned long offset;  /* offset of the new section in the existing section */
+    uint8_t new_section;       /* true if section 's' was added */
+    uint8_t link_once;         /* true if link once section */
+} 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, 
+                                int fd, unsigned long file_offset)
+{ 
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) *shdr, *sh;
+    int size, i, j, offset, offseti, nb_syms, sym_index, ret;
+    unsigned char *strsec, *strtab;
+    int *old_to_new_syms;
+    char *sh_name, *name;
+    SectionMergeInfo *sm_table, *sm;
+    ElfW(Sym) *sym, *symtab;
+    ElfW_Rel *rel, *rel_end;
+    Section *s;
+
+    int stab_index;
+    int stabstr_index;
+
+    stab_index = stabstr_index = 0;
+
+    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
+        goto fail1;
+    if (ehdr.e_ident[0] != ELFMAG0 ||
+        ehdr.e_ident[1] != ELFMAG1 ||
+        ehdr.e_ident[2] != ELFMAG2 ||
+        ehdr.e_ident[3] != ELFMAG3)
+        goto fail1;
+    /* test if object file */
+    if (ehdr.e_type != ET_REL)
+        goto fail1;
+    /* test CPU specific stuff */
+    if (ehdr.e_ident[5] != ELFDATA2LSB ||
+        ehdr.e_machine != EM_TCC_TARGET) {
+    fail1:
+        error_noabort("invalid object file");
+        return -1;
+    }
+    /* read sections */
+    shdr = load_data(fd, file_offset + ehdr.e_shoff, 
+                     sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
+    
+    /* load section names */
+    sh = &shdr[ehdr.e_shstrndx];
+    strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+
+    /* load symtab and strtab */
+    old_to_new_syms = NULL;
+    symtab = NULL;
+    strtab = NULL;
+    nb_syms = 0;
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        sh = &shdr[i];
+        if (sh->sh_type == SHT_SYMTAB) {
+            if (symtab) {
+                error_noabort("object must contain only one symtab");
+            fail:
+                ret = -1;
+                goto the_end;
+            }
+            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+            symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+            sm_table[i].s = symtab_section;
+
+            /* now load strtab */
+            sh = &shdr[sh->sh_link];
+            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+        }
+    }
+        
+    /* now examine each section and try to merge its content with the
+       ones in memory */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        /* no need to examine section name strtab */
+        if (i == ehdr.e_shstrndx)
+            continue;
+        sh = &shdr[i];
+        sh_name = strsec + sh->sh_name;
+        /* ignore sections types we do not handle */
+        if (sh->sh_type != SHT_PROGBITS &&
+            sh->sh_type != SHT_RELX && 
+#ifdef TCC_ARM_EABI
+            sh->sh_type != SHT_ARM_EXIDX &&
+#endif
+            sh->sh_type != SHT_NOBITS && 
+            strcmp(sh_name, ".stabstr")
+            )
+            continue;
+        if (sh->sh_addralign < 1)
+            sh->sh_addralign = 1;
+        /* find corresponding section, if any */
+        for(j = 1; j < s1->nb_sections;j++) {
+            s = s1->sections[j];
+            if (!strcmp(s->name, sh_name)) {
+                if (!strncmp(sh_name, ".gnu.linkonce", 
+                             sizeof(".gnu.linkonce") - 1)) {
+                    /* if a 'linkonce' section is already present, we
+                       do not add it again. It is a little tricky as
+                       symbols can still be defined in
+                       it. */
+                    sm_table[i].link_once = 1;
+                    goto next;
+                } else {
+                    goto found;
+                }
+            }
+        }
+        /* not found: create new section */
+        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
+        /* take as much info as possible from the section. sh_link and
+           sh_info will be updated later */
+        s->sh_addralign = sh->sh_addralign;
+        s->sh_entsize = sh->sh_entsize;
+        sm_table[i].new_section = 1;
+    found:
+        if (sh->sh_type != s->sh_type) {
+            error_noabort("invalid section type");
+            goto fail;
+        }
+
+        /* align start of section */
+        offset = s->data_offset;
+
+        if (0 == strcmp(sh_name, ".stab")) {
+            stab_index = i;
+            goto no_align;
+        }
+        if (0 == strcmp(sh_name, ".stabstr")) {
+            stabstr_index = i;
+            goto no_align;
+        }
+
+        size = sh->sh_addralign - 1;
+        offset = (offset + size) & ~size;
+        if (sh->sh_addralign > s->sh_addralign)
+            s->sh_addralign = sh->sh_addralign;
+        s->data_offset = offset;
+    no_align:
+        sm_table[i].offset = offset;
+        sm_table[i].s = s;
+        /* concatenate sections */
+        size = sh->sh_size;
+        if (sh->sh_type != SHT_NOBITS) {
+            unsigned char *ptr;
+            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
+            ptr = section_ptr_add(s, size);
+            read(fd, ptr, size);
+        } else {
+            s->data_offset += size;
+        }
+    next: ;
+    }
+
+    /* //gr relocate stab strings */
+    if (stab_index && stabstr_index) {
+        Stab_Sym *a, *b;
+        unsigned o;
+        s = sm_table[stab_index].s;
+        a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
+        b = (Stab_Sym *)(s->data + s->data_offset);
+        o = sm_table[stabstr_index].offset;
+        while (a < b) 
+            a->n_strx += o, a++;
+    }
+
+    /* second short pass to update sh_link and sh_info fields of new
+       sections */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        s = sm_table[i].s;
+        if (!s || !sm_table[i].new_section)
+            continue;
+        sh = &shdr[i];
+        if (sh->sh_link > 0)
+            s->link = sm_table[sh->sh_link].s;
+        if (sh->sh_type == SHT_RELX) {
+            s->sh_info = sm_table[sh->sh_info].s->sh_num;
+            /* update backward link */
+            s1->sections[s->sh_info]->reloc = s;
+        }
+    }
+    sm = sm_table;
+
+    /* resolve symbols */
+    old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
+
+    sym = symtab + 1;
+    for(i = 1; i < nb_syms; i++, sym++) {
+        if (sym->st_shndx != SHN_UNDEF &&
+            sym->st_shndx < SHN_LORESERVE) {
+            sm = &sm_table[sym->st_shndx];
+            if (sm->link_once) {
+                /* if a symbol is in a link once section, we use the
+                   already defined symbol. It is very important to get
+                   correct relocations */
+                if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+                    name = strtab + sym->st_name;
+                    sym_index = find_elf_sym(symtab_section, name);
+                    if (sym_index)
+                        old_to_new_syms[i] = sym_index;
+                }
+                continue;
+            }
+            /* if no corresponding section added, no need to add symbol */
+            if (!sm->s)
+                continue;
+            /* convert section number */
+            sym->st_shndx = sm->s->sh_num;
+            /* offset value */
+            sym->st_value += sm->offset;
+        }
+        /* add symbol */
+        name = strtab + sym->st_name;
+        sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, 
+                                sym->st_info, sym->st_other, 
+                                sym->st_shndx, name);
+        old_to_new_syms[i] = sym_index;
+    }
+
+    /* third pass to patch relocation entries */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        s = sm_table[i].s;
+        if (!s)
+            continue;
+        sh = &shdr[i];
+        offset = sm_table[i].offset;
+        switch(s->sh_type) {
+        case SHT_RELX:
+            /* take relocation offset information */
+            offseti = sm_table[sh->sh_info].offset;
+            rel_end = (ElfW_Rel *)(s->data + s->data_offset);
+            for(rel = (ElfW_Rel *)(s->data + offset);
+                rel < rel_end;
+                rel++) {
+                int type;
+                unsigned sym_index;
+                /* convert symbol index */
+                type = ELFW(R_TYPE)(rel->r_info);
+                sym_index = ELFW(R_SYM)(rel->r_info);
+                /* NOTE: only one symtab assumed */
+                if (sym_index >= nb_syms)
+                    goto invalid_reloc;
+                sym_index = old_to_new_syms[sym_index];
+                /* ignore link_once in rel section. */
+                if (!sym_index && !sm->link_once) {
+                invalid_reloc:
+                    error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
+                        i, strsec + sh->sh_name, rel->r_offset);
+                    goto fail;
+                }
+                rel->r_info = ELFW(R_INFO)(sym_index, type);
+                /* offset the relocation offset */
+                rel->r_offset += offseti;
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    
+    ret = 0;
+ the_end:
+    tcc_free(symtab);
+    tcc_free(strtab);
+    tcc_free(old_to_new_syms);
+    tcc_free(sm_table);
+    tcc_free(strsec);
+    tcc_free(shdr);
+    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 */
+    char ar_uid[6];             /* owner uid; printed as decimal */
+    char ar_gid[6];             /* owner gid; printed as decimal */
+    char ar_mode[8];            /* file mode, printed as octal   */
+    char ar_size[10];           /* file size, printed as decimal */
+    char ar_fmag[2];            /* should contain ARFMAG */
+} ArchiveHeader;
+
+static int get_be32(const uint8_t *b)
+{
+    return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
+}
+
+/* load only the objects which resolve undefined symbols */
+static int tcc_load_alacarte(TCCState *s1, int fd, int size)
+{
+    int i, bound, nsyms, sym_index, off, ret;
+    uint8_t *data;
+    const char *ar_names, *p;
+    const uint8_t *ar_index;
+    ElfW(Sym) *sym;
+
+    data = tcc_malloc(size);
+    if (read(fd, data, size) != size)
+        goto fail;
+    nsyms = get_be32(data);
+    ar_index = data + 4;
+    ar_names = ar_index + nsyms * 4;
+
+    do {
+        bound = 0;
+        for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
+            sym_index = find_elf_sym(symtab_section, p);
+            if(sym_index) {
+                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                if(sym->st_shndx == SHN_UNDEF) {
+                    off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
+#if 0
+                    printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
+#endif
+                    ++bound;
+                    lseek(fd, off, SEEK_SET);
+                    if(tcc_load_object_file(s1, fd, off) < 0) {
+                    fail:
+                        ret = -1;
+                        goto the_end;
+                    }
+                }
+            }
+        }
+    } while(bound);
+    ret = 0;
+ the_end:
+    tcc_free(data);
+    return ret;
+}
+
+/* load a '.a' file */
+static int tcc_load_archive(TCCState *s1, int fd)
+{
+    ArchiveHeader hdr;
+    char ar_size[11];
+    char ar_name[17];
+    char magic[8];
+    int size, len, i;
+    unsigned long file_offset;
+
+    /* skip magic which was already checked */
+    read(fd, magic, sizeof(magic));
+    
+    for(;;) {
+        len = read(fd, &hdr, sizeof(hdr));
+        if (len == 0)
+            break;
+        if (len != sizeof(hdr)) {
+            error_noabort("invalid archive");
+            return -1;
+        }
+        memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
+        ar_size[sizeof(hdr.ar_size)] = '\0';
+        size = strtol(ar_size, NULL, 0);
+        memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
+        for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
+            if (ar_name[i] != ' ')
+                break;
+        }
+        ar_name[i + 1] = '\0';
+        //        printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
+        file_offset = lseek(fd, 0, SEEK_CUR);
+        /* align to even */
+        size = (size + 1) & ~1;
+        if (!strcmp(ar_name, "/")) {
+            /* coff symbol table : we handle it */
+            if(s1->alacarte_link)
+                return tcc_load_alacarte(s1, fd, size);
+        } else if (!strcmp(ar_name, "//") ||
+                   !strcmp(ar_name, "__.SYMDEF") ||
+                   !strcmp(ar_name, "__.SYMDEF/") ||
+                   !strcmp(ar_name, "ARFILENAMES/")) {
+            /* skip symbol table or archive names */
+        } else {
+            if (tcc_load_object_file(s1, fd, file_offset) < 0)
+                return -1;
+        }
+        lseek(fd, file_offset + size, SEEK_SET);
+    }
+    return 0;
+}
+
+/* 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)
+{ 
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) *shdr, *sh, *sh1;
+    int i, j, nb_syms, nb_dts, sym_bind, ret;
+    ElfW(Sym) *sym, *dynsym;
+    ElfW(Dyn) *dt, *dynamic;
+    unsigned char *dynstr;
+    const char *name, *soname;
+    DLLReference *dllref;
+    
+    read(fd, &ehdr, sizeof(ehdr));
+
+    /* test CPU specific stuff */
+    if (ehdr.e_ident[5] != ELFDATA2LSB ||
+        ehdr.e_machine != EM_TCC_TARGET) {
+        error_noabort("bad architecture");
+        return -1;
+    }
+
+    /* read sections */
+    shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+
+    /* load dynamic section and dynamic symbols */
+    nb_syms = 0;
+    nb_dts = 0;
+    dynamic = NULL;
+    dynsym = NULL; /* avoid warning */
+    dynstr = NULL; /* avoid warning */
+    for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
+        switch(sh->sh_type) {
+        case SHT_DYNAMIC:
+            nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
+            dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
+            break;
+        case SHT_DYNSYM:
+            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+            dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
+            sh1 = &shdr[sh->sh_link];
+            dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
+            break;
+        default:
+            break;
+        }
+    }
+    
+    /* compute the real library name */
+    soname = tcc_basename(filename);
+        
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+        if (dt->d_tag == DT_SONAME) {
+            soname = dynstr + dt->d_un.d_val;
+        }
+    }
+
+    /* if the dll is already loaded, do not load it */
+    for(i = 0; i < s1->nb_loaded_dlls; i++) {
+        dllref = s1->loaded_dlls[i];
+        if (!strcmp(soname, dllref->name)) {
+            /* but update level if needed */
+            if (level < dllref->level)
+                dllref->level = level;
+            ret = 0;
+            goto the_end;
+        }
+    }
+    
+    //    printf("loading dll '%s'\n", soname);
+
+    /* add the dll and its level */
+    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
+    dllref->level = level;
+    strcpy(dllref->name, soname);
+    dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+
+    /* add dynamic symbols in dynsym_section */
+    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
+        sym_bind = ELFW(ST_BIND)(sym->st_info);
+        if (sym_bind == STB_LOCAL)
+            continue;
+        name = dynstr + sym->st_name;
+        add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
+                    sym->st_info, sym->st_other, sym->st_shndx, name);
+    }
+
+    /* load all referenced DLLs */
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+        switch(dt->d_tag) {
+        case DT_NEEDED:
+            name = dynstr + dt->d_un.d_val;
+            for(j = 0; j < s1->nb_loaded_dlls; j++) {
+                dllref = s1->loaded_dlls[j];
+                if (!strcmp(name, dllref->name))
+                    goto already_loaded;
+            }
+            if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
+                error_noabort("referenced dll '%s' not found", name);
+                ret = -1;
+                goto the_end;
+            }
+        already_loaded:
+            break;
+        }
+    }
+    ret = 0;
+ the_end:
+    tcc_free(dynstr);
+    tcc_free(dynsym);
+    tcc_free(dynamic);
+    tcc_free(shdr);
+    return ret;
+}
+
+#define LD_TOK_NAME 256
+#define LD_TOK_EOF  (-1)
+
+/* return next ld script token */
+static int ld_next(TCCState *s1, char *name, int name_size)
+{
+    int c;
+    char *q;
+
+ redo:
+    switch(ch) {
+    case ' ':
+    case '\t':
+    case '\f':
+    case '\v':
+    case '\r':
+    case '\n':
+        inp();
+        goto redo;
+    case '/':
+        minp();
+        if (ch == '*') {
+            file->buf_ptr = parse_comment(file->buf_ptr);
+            ch = file->buf_ptr[0];
+            goto redo;
+        } else {
+            q = name;
+            *q++ = '/';
+            goto parse_name;
+        }
+        break;
+    /* case 'a' ... 'z': */
+    case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+       case 'e':
+       case 'f':
+       case 'g':
+       case 'h':
+       case 'i':
+       case 'j':
+       case 'k':
+       case 'l':
+       case 'm':
+       case 'n':
+       case 'o':
+       case 'p':
+       case 'q':
+       case 'r':
+       case 's':
+       case 't':
+       case 'u':
+       case 'v':
+       case 'w':
+       case 'x':
+       case 'y':
+       case 'z':
+    /* case 'A' ... 'z': */
+    case 'A':
+       case 'B':
+       case 'C':
+       case 'D':
+       case 'E':
+       case 'F':
+       case 'G':
+       case 'H':
+       case 'I':
+       case 'J':
+       case 'K':
+       case 'L':
+       case 'M':
+       case 'N':
+       case 'O':
+       case 'P':
+       case 'Q':
+       case 'R':
+       case 'S':
+       case 'T':
+       case 'U':
+       case 'V':
+       case 'W':
+       case 'X':
+       case 'Y':
+       case 'Z':
+    case '_':
+    case '\\':
+    case '.':
+    case '$':
+    case '~':
+        q = name;
+    parse_name:
+        for(;;) {
+            if (!((ch >= 'a' && ch <= 'z') ||
+                  (ch >= 'A' && ch <= 'Z') ||
+                  (ch >= '0' && ch <= '9') ||
+                  strchr("/.-_+=$:\\,~", ch)))
+                break;
+            if ((q - name) < name_size - 1) {
+                *q++ = ch;
+            }
+            minp();
+        }
+        *q = '\0';
+        c = LD_TOK_NAME;
+        break;
+    case CH_EOF:
+        c = LD_TOK_EOF;
+        break;
+    default:
+        c = ch;
+        inp();
+        break;
+    }
+#if 0
+    printf("tok=%c %d\n", c, c);
+    if (c == LD_TOK_NAME)
+        printf("  name=%s\n", name);
+#endif
+    return c;
+}
+
+static int ld_add_file_list(TCCState *s1, int as_needed)
+{
+    char filename[1024];
+    int t, ret;
+
+    t = ld_next(s1, filename, sizeof(filename));
+    if (t != '(')
+        expect("(");
+    t = ld_next(s1, filename, sizeof(filename));
+    for(;;) {
+        if (t == LD_TOK_EOF) {
+            error_noabort("unexpected end of file");
+            return -1;
+        } else if (t == ')') {
+            break;
+        } else if (t != LD_TOK_NAME) {
+            error_noabort("filename expected");
+            return -1;
+        } 
+        if (!strcmp(filename, "AS_NEEDED")) {
+            ret = ld_add_file_list(s1, 1);
+            if (ret)
+                return ret;
+        } else {
+            /* TODO: Implement AS_NEEDED support. Ignore it for now */
+            if (!as_needed)
+                tcc_add_file(s1, filename);
+        }
+        t = ld_next(s1, filename, sizeof(filename));
+        if (t == ',') {
+            t = ld_next(s1, filename, sizeof(filename));
+        }
+    }
+    return 0;
+}
+
+/* interpret a subset of GNU ldscripts to handle the dummy libc.so
+   files */
+static int tcc_load_ldscript(TCCState *s1)
+{
+    char cmd[64];
+    char filename[1024];
+    int t, ret;
+    
+    ch = file->buf_ptr[0];
+    ch = handle_eob();
+    for(;;) {
+        t = ld_next(s1, cmd, sizeof(cmd));
+        if (t == LD_TOK_EOF)
+            return 0;
+        else if (t != LD_TOK_NAME)
+            return -1;
+        if (!strcmp(cmd, "INPUT") ||
+            !strcmp(cmd, "GROUP")) {
+            ret = ld_add_file_list(s1, 0);
+            if (ret)
+                return ret;
+        } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
+                   !strcmp(cmd, "TARGET")) {
+            /* ignore some commands */
+            t = ld_next(s1, cmd, sizeof(cmd));
+            if (t != '(')
+                expect("(");
+            for(;;) {
+                t = ld_next(s1, filename, sizeof(filename));
+                if (t == LD_TOK_EOF) {
+                    error_noabort("unexpected end of file");
+                    return -1;
+                } else if (t == ')') {
+                    break;
+                }
+            }
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+}
diff --git a/tinyc/tccgen.c b/tinyc/tccgen.c
new file mode 100755
index 000000000..942c503c1
--- /dev/null
+++ b/tinyc/tccgen.c
@@ -0,0 +1,5122 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+void swap(int *p, int *q)
+{
+    int t;
+    t = *p;
+    *p = *q;
+    *q = t;
+}
+
+void vsetc(CType *type, int r, CValue *vc)
+{
+    int v;
+
+    if (vtop >= vstack + (VSTACK_SIZE - 1))
+        error("memory full");
+    /* cannot let cpu flags if other instruction are generated. Also
+       avoid leaving VT_JMP anywhere except on the top of the stack
+       because it would complicate the code generator. */
+    if (vtop >= vstack) {
+        v = vtop->r & VT_VALMASK;
+        if (v == VT_CMP || (v & ~1) == VT_JMP)
+            gv(RC_INT);
+    }
+    vtop++;
+    vtop->type = *type;
+    vtop->r = r;
+    vtop->r2 = VT_CONST;
+    vtop->c = *vc;
+}
+
+/* push integer constant */
+void vpushi(int v)
+{
+    CValue cval;
+    cval.i = v;
+    vsetc(&int_type, VT_CONST, &cval);
+}
+
+/* push long long constant */
+void vpushll(long long v)
+{
+    CValue cval;
+    CType ctype;
+    ctype.t = VT_LLONG;
+    cval.ull = v;
+    vsetc(&ctype, VT_CONST, &cval);
+}
+
+/* Return a static symbol pointing to a section */
+static Sym *get_sym_ref(CType *type, Section *sec, 
+                        unsigned long offset, unsigned long size)
+{
+    int v;
+    Sym *sym;
+
+    v = anon_sym++;
+    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
+    sym->type.ref = type->ref;
+    sym->r = VT_CONST | VT_SYM;
+    put_extern_sym(sym, sec, offset, size);
+    return sym;
+}
+
+/* push a reference to a section offset by adding a dummy symbol */
+static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
+{
+    CValue cval;
+
+    cval.ul = 0;
+    vsetc(type, VT_CONST | VT_SYM, &cval);
+    vtop->sym = get_sym_ref(type, sec, offset, size);
+}
+
+/* define a new external reference to a symbol 'v' of type 'u' */
+static Sym *external_global_sym(int v, CType *type, int r)
+{
+    Sym *s;
+
+    s = sym_find(v);
+    if (!s) {
+        /* push forward reference */
+        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
+        s->type.ref = type->ref;
+        s->r = r | VT_CONST | VT_SYM;
+    }
+    return s;
+}
+
+/* define a new external reference to a symbol 'v' of type 'u' */
+static Sym *external_sym(int v, CType *type, int r)
+{
+    Sym *s;
+
+    s = sym_find(v);
+    if (!s) {
+        /* push forward reference */
+        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
+        s->type.t |= VT_EXTERN;
+    } else {
+        if (!is_compatible_types(&s->type, type))
+            error("incompatible types for redefinition of '%s'", 
+                  get_tok_str(v, NULL));
+    }
+    return s;
+}
+
+/* push a reference to global symbol v */
+static void vpush_global_sym(CType *type, int v)
+{
+    Sym *sym;
+    CValue cval;
+
+    sym = external_global_sym(v, type, 0);
+    cval.ul = 0;
+    vsetc(type, VT_CONST | VT_SYM, &cval);
+    vtop->sym = sym;
+}
+
+void vset(CType *type, int r, int v)
+{
+    CValue cval;
+
+    cval.i = v;
+    vsetc(type, r, &cval);
+}
+
+void vseti(int r, int v)
+{
+    CType type;
+    type.t = VT_INT;
+    vset(&type, r, v);
+}
+
+void vswap(void)
+{
+    SValue tmp;
+
+    tmp = vtop[0];
+    vtop[0] = vtop[-1];
+    vtop[-1] = tmp;
+}
+
+void vpushv(SValue *v)
+{
+    if (vtop >= vstack + (VSTACK_SIZE - 1))
+        error("memory full");
+    vtop++;
+    *vtop = *v;
+}
+
+void vdup(void)
+{
+    vpushv(vtop);
+}
+
+/* save r to the memory stack, and mark it as being free */
+void save_reg(int r)
+{
+    int l, saved, size, align;
+    SValue *p, sv;
+    CType *type;
+
+    /* modify all stack values */
+    saved = 0;
+    l = 0;
+    for(p=vstack;p<=vtop;p++) {
+        if ((p->r & VT_VALMASK) == r ||
+            ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
+            /* must save value on stack if not already done */
+            if (!saved) {
+                /* NOTE: must reload 'r' because r might be equal to r2 */
+                r = p->r & VT_VALMASK;
+                /* store register in the stack */
+                type = &p->type;
+                if ((p->r & VT_LVAL) ||
+                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
+#ifdef TCC_TARGET_X86_64
+                    type = &char_pointer_type;
+#else
+                    type = &int_type;
+#endif
+                size = type_size(type, &align);
+                loc = (loc - size) & -align;
+                sv.type.t = type->t;
+                sv.r = VT_LOCAL | VT_LVAL;
+                sv.c.ul = loc;
+                store(r, &sv);
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+                /* x86 specific: need to pop fp register ST0 if saved */
+                if (r == TREG_ST0) {
+                    o(0xd9dd); /* fstp %st(1) */
+                }
+#endif
+#ifndef TCC_TARGET_X86_64
+                /* special long long case */
+                if ((type->t & VT_BTYPE) == VT_LLONG) {
+                    sv.c.ul += 4;
+                    store(p->r2, &sv);
+                }
+#endif
+                l = loc;
+                saved = 1;
+            }
+            /* mark that stack entry as being saved on the stack */
+            if (p->r & VT_LVAL) {
+                /* also clear the bounded flag because the
+                   relocation address of the function was stored in
+                   p->c.ul */
+                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
+            } else {
+                p->r = lvalue_type(p->type.t) | VT_LOCAL;
+            }
+            p->r2 = VT_CONST;
+            p->c.ul = l;
+        }
+    }
+}
+
+/* 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) 
+{
+    int r;
+    SValue *p;
+    
+    for(r=0;r<NB_REGS;r++) {
+        if (reg_classes[r] & rc2) {
+            int n;
+            n=0;
+            for(p = vstack; p <= vtop; p++) {
+                if ((p->r & VT_VALMASK) == r ||
+                    (p->r2 & VT_VALMASK) == r)
+                    n++;
+            }
+            if (n <= 1)
+                return r;
+        }
+    }
+    return get_reg(rc);
+}
+
+/* find a free register of class 'rc'. If none, save one register */
+int get_reg(int rc)
+{
+    int r;
+    SValue *p;
+
+    /* find a free register */
+    for(r=0;r<NB_REGS;r++) {
+        if (reg_classes[r] & rc) {
+            for(p=vstack;p<=vtop;p++) {
+                if ((p->r & VT_VALMASK) == r ||
+                    (p->r2 & VT_VALMASK) == r)
+                    goto notfound;
+            }
+            return r;
+        }
+    notfound: ;
+    }
+    
+    /* no register left : free the first one on the stack (VERY
+       IMPORTANT to start from the bottom to ensure that we don't
+       spill registers used in gen_opi()) */
+    for(p=vstack;p<=vtop;p++) {
+        r = p->r & VT_VALMASK;
+        if (r < VT_CONST && (reg_classes[r] & rc))
+            goto save_found;
+        /* also look at second register (if long long) */
+        r = p->r2 & VT_VALMASK;
+        if (r < VT_CONST && (reg_classes[r] & rc)) {
+        save_found:
+            save_reg(r);
+            return r;
+        }
+    }
+    /* Should never comes here */
+    return -1;
+}
+
+/* save registers up to (vtop - n) stack entry */
+void save_regs(int n)
+{
+    int r;
+    SValue *p, *p1;
+    p1 = vtop - n;
+    for(p = vstack;p <= p1; p++) {
+        r = p->r & VT_VALMASK;
+        if (r < VT_CONST) {
+            save_reg(r);
+        }
+    }
+}
+
+/* move register 's' to 'r', and flush previous value of r to memory
+   if needed */
+void move_reg(int r, int s)
+{
+    SValue sv;
+
+    if (r != s) {
+        save_reg(r);
+        sv.type.t = VT_INT;
+        sv.r = s;
+        sv.c.ul = 0;
+        load(r, &sv);
+    }
+}
+
+/* get address of vtop (vtop MUST BE an lvalue) */
+void gaddrof(void)
+{
+    vtop->r &= ~VT_LVAL;
+    /* tricky: if saved lvalue, then we can go back to lvalue */
+    if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
+        vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
+}
+
+#ifdef CONFIG_TCC_BCHECK
+/* generate lvalue bound code */
+void gbound(void)
+{
+    int lval_type;
+    CType type1;
+
+    vtop->r &= ~VT_MUSTBOUND;
+    /* if lvalue, then use checking code before dereferencing */
+    if (vtop->r & VT_LVAL) {
+        /* if not VT_BOUNDED value, then make one */
+        if (!(vtop->r & VT_BOUNDED)) {
+            lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
+            /* must save type because we must set it to int to get pointer */
+            type1 = vtop->type;
+            vtop->type.t = VT_INT;
+            gaddrof();
+            vpushi(0);
+            gen_bounded_ptr_add();
+            vtop->r |= lval_type;
+            vtop->type = type1;
+        }
+        /* then check for dereferencing */
+        gen_bounded_ptr_deref();
+    }
+}
+#endif
+
+/* 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)
+{
+    int r, rc2, bit_pos, bit_size, size, align, i;
+
+    /* NOTE: get_reg can modify vstack[] */
+    if (vtop->type.t & VT_BITFIELD) {
+        CType type;
+        int bits = 32;
+        bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
+        bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
+        /* remove bit field info to avoid loops */
+        vtop->type.t &= ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
+        /* cast to int to propagate signedness in following ops */
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            type.t = VT_LLONG;
+            bits = 64;
+        } else
+            type.t = VT_INT;
+        if((vtop->type.t & VT_UNSIGNED) ||
+           (vtop->type.t & VT_BTYPE) == VT_BOOL)
+            type.t |= VT_UNSIGNED;
+        gen_cast(&type);
+        /* generate shifts */
+        vpushi(bits - (bit_pos + bit_size));
+        gen_op(TOK_SHL);
+        vpushi(bits - bit_size);
+        /* NOTE: transformed to SHR if unsigned */
+        gen_op(TOK_SAR);
+        r = gv(rc);
+    } else {
+        if (is_float(vtop->type.t) && 
+            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+            Sym *sym;
+            int *ptr;
+            unsigned long offset;
+#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
+            CValue check;
+#endif
+            
+            /* XXX: unify with initializers handling ? */
+            /* CPUs usually cannot use float constants, so we store them
+               generically in data segment */
+            size = type_size(&vtop->type, &align);
+            offset = (data_section->data_offset + align - 1) & -align;
+            data_section->data_offset = offset;
+            /* XXX: not portable yet */
+#if defined(__i386__) || defined(__x86_64__)
+            /* Zero pad x87 tenbyte long doubles */
+            if (size == LDOUBLE_SIZE)
+                vtop->c.tab[2] &= 0xffff;
+#endif
+            ptr = section_ptr_add(data_section, size);
+            size = size >> 2;
+#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
+            check.d = 1;
+            if(check.tab[0])
+                for(i=0;i<size;i++)
+                    ptr[i] = vtop->c.tab[size-1-i];
+            else
+#endif
+            for(i=0;i<size;i++)
+                ptr[i] = vtop->c.tab[i];
+            sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
+            vtop->r |= VT_LVAL | VT_SYM;
+            vtop->sym = sym;
+            vtop->c.ul = 0;
+        }
+#ifdef CONFIG_TCC_BCHECK
+        if (vtop->r & VT_MUSTBOUND) 
+            gbound();
+#endif
+
+        r = vtop->r & VT_VALMASK;
+        rc2 = RC_INT;
+        if (rc == RC_IRET)
+            rc2 = RC_LRET;
+        /* need to reload if:
+           - constant
+           - lvalue (need to dereference pointer)
+           - already a register, but not in the right class */
+        if (r >= VT_CONST || 
+            (vtop->r & VT_LVAL) ||
+            !(reg_classes[r] & rc) ||
+            ((vtop->type.t & VT_BTYPE) == VT_LLONG && 
+             !(reg_classes[vtop->r2] & rc2))) {
+            r = get_reg(rc);
+#ifndef TCC_TARGET_X86_64
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                int r2;
+                unsigned long long ll;
+                /* two register type load : expand to two words
+                   temporarily */
+                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+                    /* load constant */
+                    ll = vtop->c.ull;
+                    vtop->c.ui = ll; /* first word */
+                    load(r, vtop);
+                    vtop->r = r; /* save register value */
+                    vpushi(ll >> 32); /* second word */
+                } else if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
+                           (vtop->r & VT_LVAL)) {
+                    /* We do not want to modifier the long long
+                       pointer here, so the safest (and less
+                       efficient) is to save all the other registers
+                       in the stack. XXX: totally inefficient. */
+                    save_regs(1);
+                    /* load from memory */
+                    load(r, vtop);
+                    vdup();
+                    vtop[-1].r = r; /* save register value */
+                    /* increment pointer to get second word */
+                    vtop->type.t = VT_INT;
+                    gaddrof();
+                    vpushi(4);
+                    gen_op('+');
+                    vtop->r |= VT_LVAL;
+                } else {
+                    /* move registers */
+                    load(r, vtop);
+                    vdup();
+                    vtop[-1].r = r; /* save register value */
+                    vtop->r = vtop[-1].r2;
+                }
+                /* allocate second register */
+                r2 = get_reg(rc2);
+                load(r2, vtop);
+                vpop();
+                /* write second register */
+                vtop->r2 = r2;
+            } else
+#endif
+            if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
+                int t1, t;
+                /* lvalue of scalar type : need to use lvalue type
+                   because of possible cast */
+                t = vtop->type.t;
+                t1 = t;
+                /* compute memory access type */
+                if (vtop->r & VT_LVAL_BYTE)
+                    t = VT_BYTE;
+                else if (vtop->r & VT_LVAL_SHORT)
+                    t = VT_SHORT;
+                if (vtop->r & VT_LVAL_UNSIGNED)
+                    t |= VT_UNSIGNED;
+                vtop->type.t = t;
+                load(r, vtop);
+                /* restore wanted type */
+                vtop->type.t = t1;
+            } else {
+                /* one register type load */
+                load(r, vtop);
+            }
+        }
+        vtop->r = r;
+#ifdef TCC_TARGET_C67
+        /* uses register pairs for doubles */
+        if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
+            vtop->r2 = r+1;
+#endif
+    }
+    return r;
+}
+
+/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
+void gv2(int rc1, int rc2)
+{
+    int v;
+
+    /* generate more generic register first. But VT_JMP or VT_CMP
+       values must be generated first in all cases to avoid possible
+       reload errors */
+    v = vtop[0].r & VT_VALMASK;
+    if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
+        vswap();
+        gv(rc1);
+        vswap();
+        gv(rc2);
+        /* test if reload is needed for first register */
+        if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+            vswap();
+            gv(rc1);
+            vswap();
+        }
+    } else {
+        gv(rc2);
+        vswap();
+        gv(rc1);
+        vswap();
+        /* test if reload is needed for first register */
+        if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
+            gv(rc2);
+        }
+    }
+}
+
+/* wrapper around RC_FRET to return a register by type */
+int rc_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+    if (t == VT_LDOUBLE) {
+        return RC_ST0;
+    }
+#endif
+    return RC_FRET;
+}
+
+/* wrapper around REG_FRET to return a register by type */
+int reg_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+    if (t == VT_LDOUBLE) {
+        return TREG_ST0;
+    }
+#endif
+    return REG_FRET;
+}
+
+/* expand long long on stack in two int registers */
+void lexpand(void)
+{
+    int u;
+
+    u = vtop->type.t & VT_UNSIGNED;
+    gv(RC_INT);
+    vdup();
+    vtop[0].r = vtop[-1].r2;
+    vtop[0].r2 = VT_CONST;
+    vtop[-1].r2 = VT_CONST;
+    vtop[0].type.t = VT_INT | u;
+    vtop[-1].type.t = VT_INT | u;
+}
+
+#ifdef TCC_TARGET_ARM
+/* expand long long on stack */
+void lexpand_nr(void)
+{
+    int u,v;
+
+    u = vtop->type.t & VT_UNSIGNED;
+    vdup();
+    vtop->r2 = VT_CONST;
+    vtop->type.t = VT_INT | u;
+    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
+    if (v == VT_CONST) {
+      vtop[-1].c.ui = vtop->c.ull;
+      vtop->c.ui = vtop->c.ull >> 32;
+      vtop->r = VT_CONST;
+    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+      vtop->c.ui += 4;
+      vtop->r = vtop[-1].r;
+    } else if (v > VT_CONST) {
+      vtop--;
+      lexpand();
+    } else
+      vtop->r = vtop[-1].r2;
+    vtop[-1].r2 = VT_CONST;
+    vtop[-1].type.t = VT_INT | u;
+}
+#endif
+
+/* build a long long from two ints */
+void lbuild(int t)
+{
+    gv2(RC_INT, RC_INT);
+    vtop[-1].r2 = vtop[0].r;
+    vtop[-1].type.t = t;
+    vpop();
+}
+
+/* rotate n first stack elements to the bottom 
+   I1 ... In -> I2 ... In I1 [top is right]
+*/
+void vrotb(int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = vtop[-n + 1];
+    for(i=-n+1;i!=0;i++)
+        vtop[i] = vtop[i+1];
+    vtop[0] = tmp;
+}
+
+/* rotate n first stack elements to the top 
+   I1 ... In -> In I1 ... I(n-1)  [top is right]
+ */
+void vrott(int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = vtop[0];
+    for(i = 0;i < n - 1; i++)
+        vtop[-i] = vtop[-i - 1];
+    vtop[-n + 1] = tmp;
+}
+
+#ifdef TCC_TARGET_ARM
+/* like vrott but in other direction
+   In ... I1 -> I(n-1) ... I1 In  [top is right]
+ */
+void vnrott(int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = vtop[-n + 1];
+    for(i = n - 1; i > 0; i--)
+        vtop[-i] = vtop[-i + 1];
+    vtop[0] = tmp;
+}
+#endif
+
+/* pop stack value */
+void vpop(void)
+{
+    int v;
+    v = vtop->r & VT_VALMASK;
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+    /* for x86, we need to pop the FP stack */
+    if (v == TREG_ST0 && !nocode_wanted) {
+        o(0xd9dd); /* fstp %st(1) */
+    } else
+#endif
+    if (v == VT_JMP || v == VT_JMPI) {
+        /* need to put correct jump if && or || without test */
+        gsym(vtop->c.ul);
+    }
+    vtop--;
+}
+
+/* convert stack entry to register and duplicate its value in another
+   register */
+void gv_dup(void)
+{
+    int rc, t, r, r1;
+    SValue sv;
+
+    t = vtop->type.t;
+    if ((t & VT_BTYPE) == VT_LLONG) {
+        lexpand();
+        gv_dup();
+        vswap();
+        vrotb(3);
+        gv_dup();
+        vrotb(4);
+        /* stack: H L L1 H1 */
+        lbuild(t);
+        vrotb(3);
+        vrotb(3);
+        vswap();
+        lbuild(t);
+        vswap();
+    } else {
+        /* duplicate value */
+        rc = RC_INT;
+        sv.type.t = VT_INT;
+        if (is_float(t)) {
+            rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+            if ((t & VT_BTYPE) == VT_LDOUBLE) {
+                rc = RC_ST0;
+            }
+#endif
+            sv.type.t = t;
+        }
+        r = gv(rc);
+        r1 = get_reg(rc);
+        sv.r = r;
+        sv.c.ul = 0;
+        load(r1, &sv); /* move r to r1 */
+        vdup();
+        /* duplicates value */
+        vtop->r = r1;
+    }
+}
+
+#ifndef TCC_TARGET_X86_64
+/* generate CPU independent (unsigned) long long operations */
+void gen_opl(int op)
+{
+    int t, a, b, op1, c, i;
+    int func;
+    unsigned short reg_iret = REG_IRET;
+    unsigned short reg_lret = REG_LRET;
+    SValue tmp;
+
+    switch(op) {
+    case '/':
+    case TOK_PDIV:
+        func = TOK___divdi3;
+        goto gen_func;
+    case TOK_UDIV:
+        func = TOK___udivdi3;
+        goto gen_func;
+    case '%':
+        func = TOK___moddi3;
+        goto gen_mod_func;
+    case TOK_UMOD:
+        func = TOK___umoddi3;
+    gen_mod_func:
+#ifdef TCC_ARM_EABI
+        reg_iret = TREG_R2;
+        reg_lret = TREG_R3;
+#endif
+    gen_func:
+        /* call generic long long function */
+        vpush_global_sym(&func_old_type, func);
+        vrott(3);
+        gfunc_call(2);
+        vpushi(0);
+        vtop->r = reg_iret;
+        vtop->r2 = reg_lret;
+        break;
+    case '^':
+    case '&':
+    case '|':
+    case '*':
+    case '+':
+    case '-':
+        t = vtop->type.t;
+        vswap();
+        lexpand();
+        vrotb(3);
+        lexpand();
+        /* stack: L1 H1 L2 H2 */
+        tmp = vtop[0];
+        vtop[0] = vtop[-3];
+        vtop[-3] = tmp;
+        tmp = vtop[-2];
+        vtop[-2] = vtop[-3];
+        vtop[-3] = tmp;
+        vswap();
+        /* stack: H1 H2 L1 L2 */
+        if (op == '*') {
+            vpushv(vtop - 1);
+            vpushv(vtop - 1);
+            gen_op(TOK_UMULL);
+            lexpand();
+            /* stack: H1 H2 L1 L2 ML MH */
+            for(i=0;i<4;i++)
+                vrotb(6);
+            /* stack: ML MH H1 H2 L1 L2 */
+            tmp = vtop[0];
+            vtop[0] = vtop[-2];
+            vtop[-2] = tmp;
+            /* stack: ML MH H1 L2 H2 L1 */
+            gen_op('*');
+            vrotb(3);
+            vrotb(3);
+            gen_op('*');
+            /* stack: ML MH M1 M2 */
+            gen_op('+');
+            gen_op('+');
+        } else if (op == '+' || op == '-') {
+            /* XXX: add non carry method too (for MIPS or alpha) */
+            if (op == '+')
+                op1 = TOK_ADDC1;
+            else
+                op1 = TOK_SUBC1;
+            gen_op(op1);
+            /* stack: H1 H2 (L1 op L2) */
+            vrotb(3);
+            vrotb(3);
+            gen_op(op1 + 1); /* TOK_xxxC2 */
+        } else {
+            gen_op(op);
+            /* stack: H1 H2 (L1 op L2) */
+            vrotb(3);
+            vrotb(3);
+            /* stack: (L1 op L2) H1 H2 */
+            gen_op(op);
+            /* stack: (L1 op L2) (H1 op H2) */
+        }
+        /* stack: L H */
+        lbuild(t);
+        break;
+    case TOK_SAR:
+    case TOK_SHR:
+    case TOK_SHL:
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            t = vtop[-1].type.t;
+            vswap();
+            lexpand();
+            vrotb(3);
+            /* stack: L H shift */
+            c = (int)vtop->c.i;
+            /* constant: simpler */
+            /* NOTE: all comments are for SHL. the other cases are
+               done by swaping words */
+            vpop();
+            if (op != TOK_SHL)
+                vswap();
+            if (c >= 32) {
+                /* stack: L H */
+                vpop();
+                if (c > 32) {
+                    vpushi(c - 32);
+                    gen_op(op);
+                }
+                if (op != TOK_SAR) {
+                    vpushi(0);
+                } else {
+                    gv_dup();
+                    vpushi(31);
+                    gen_op(TOK_SAR);
+                }
+                vswap();
+            } else {
+                vswap();
+                gv_dup();
+                /* stack: H L L */
+                vpushi(c);
+                gen_op(op);
+                vswap();
+                vpushi(32 - c);
+                if (op == TOK_SHL)
+                    gen_op(TOK_SHR);
+                else
+                    gen_op(TOK_SHL);
+                vrotb(3);
+                /* stack: L L H */
+                vpushi(c);
+                if (op == TOK_SHL)
+                    gen_op(TOK_SHL);
+                else
+                    gen_op(TOK_SHR);
+                gen_op('|');
+            }
+            if (op != TOK_SHL)
+                vswap();
+            lbuild(t);
+        } else {
+            /* XXX: should provide a faster fallback on x86 ? */
+            switch(op) {
+            case TOK_SAR:
+                func = TOK___ashrdi3;
+                goto gen_func;
+            case TOK_SHR:
+                func = TOK___lshrdi3;
+                goto gen_func;
+            case TOK_SHL:
+                func = TOK___ashldi3;
+                goto gen_func;
+            }
+        }
+        break;
+    default:
+        /* compare operations */
+        t = vtop->type.t;
+        vswap();
+        lexpand();
+        vrotb(3);
+        lexpand();
+        /* stack: L1 H1 L2 H2 */
+        tmp = vtop[-1];
+        vtop[-1] = vtop[-2];
+        vtop[-2] = tmp;
+        /* stack: L1 L2 H1 H2 */
+        /* compare high */
+        op1 = op;
+        /* when values are equal, we need to compare low words. since
+           the jump is inverted, we invert the test too. */
+        if (op1 == TOK_LT)
+            op1 = TOK_LE;
+        else if (op1 == TOK_GT)
+            op1 = TOK_GE;
+        else if (op1 == TOK_ULT)
+            op1 = TOK_ULE;
+        else if (op1 == TOK_UGT)
+            op1 = TOK_UGE;
+        a = 0;
+        b = 0;
+        gen_op(op1);
+        if (op1 != TOK_NE) {
+            a = gtst(1, 0);
+        }
+        if (op != TOK_EQ) {
+            /* generate non equal test */
+            /* XXX: NOT PORTABLE yet */
+            if (a == 0) {
+                b = gtst(0, 0);
+            } else {
+#if defined(TCC_TARGET_I386)
+                b = psym(0x850f, 0);
+#elif defined(TCC_TARGET_ARM)
+                b = ind;
+                o(0x1A000000 | encbranch(ind, 0, 1));
+#elif defined(TCC_TARGET_C67)
+                error("not implemented");
+#else
+#error not supported
+#endif
+            }
+        }
+        /* compare low. Always unsigned */
+        op1 = op;
+        if (op1 == TOK_LT)
+            op1 = TOK_ULT;
+        else if (op1 == TOK_LE)
+            op1 = TOK_ULE;
+        else if (op1 == TOK_GT)
+            op1 = TOK_UGT;
+        else if (op1 == TOK_GE)
+            op1 = TOK_UGE;
+        gen_op(op1);
+        a = gtst(1, a);
+        gsym(b);
+        vseti(VT_JMPI, a);
+        break;
+    }
+}
+#endif
+
+/* handle integer constant optimizations and various machine
+   independent opt */
+void gen_opic(int op)
+{
+    int c1, c2, t1, t2, n;
+    SValue *v1, *v2;
+    long long l1, l2;
+    typedef unsigned long long U;
+
+    v1 = vtop - 1;
+    v2 = vtop;
+    t1 = v1->type.t & VT_BTYPE;
+    t2 = v2->type.t & VT_BTYPE;
+
+    if (t1 == VT_LLONG)
+        l1 = v1->c.ll;
+    else if (v1->type.t & VT_UNSIGNED)
+        l1 = v1->c.ui;
+    else
+        l1 = v1->c.i;
+
+    if (t2 == VT_LLONG)
+        l2 = v2->c.ll;
+    else if (v2->type.t & VT_UNSIGNED)
+        l2 = v2->c.ui;
+    else
+        l2 = v2->c.i;
+
+    /* currently, we cannot do computations with forward symbols */
+    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    if (c1 && c2) {
+        switch(op) {
+        case '+': l1 += l2; break;
+        case '-': l1 -= l2; break;
+        case '&': l1 &= l2; break;
+        case '^': l1 ^= l2; break;
+        case '|': l1 |= l2; break;
+        case '*': l1 *= l2; break;
+
+        case TOK_PDIV:
+        case '/':
+        case '%':
+        case TOK_UDIV:
+        case TOK_UMOD:
+            /* if division by zero, generate explicit division */
+            if (l2 == 0) {
+                if (const_wanted)
+                    error("division by zero in constant");
+                goto general_case;
+            }
+            switch(op) {
+            default: l1 /= l2; break;
+            case '%': l1 %= l2; break;
+            case TOK_UDIV: l1 = (U)l1 / l2; break;
+            case TOK_UMOD: l1 = (U)l1 % l2; break;
+            }
+            break;
+        case TOK_SHL: l1 <<= l2; break;
+        case TOK_SHR: l1 = (U)l1 >> l2; break;
+        case TOK_SAR: l1 >>= l2; break;
+            /* tests */
+        case TOK_ULT: l1 = (U)l1 < (U)l2; break;
+        case TOK_UGE: l1 = (U)l1 >= (U)l2; break;
+        case TOK_EQ: l1 = l1 == l2; break;
+        case TOK_NE: l1 = l1 != l2; break;
+        case TOK_ULE: l1 = (U)l1 <= (U)l2; break;
+        case TOK_UGT: l1 = (U)l1 > (U)l2; break;
+        case TOK_LT: l1 = l1 < l2; break;
+        case TOK_GE: l1 = l1 >= l2; break;
+        case TOK_LE: l1 = l1 <= l2; break;
+        case TOK_GT: l1 = l1 > l2; break;
+            /* logical */
+        case TOK_LAND: l1 = l1 && l2; break;
+        case TOK_LOR: l1 = l1 || l2; break;
+        default:
+            goto general_case;
+        }
+        v1->c.ll = l1;
+        vtop--;
+    } else {
+        /* if commutative ops, put c2 as constant */
+        if (c1 && (op == '+' || op == '&' || op == '^' || 
+                   op == '|' || op == '*')) {
+            vswap();
+            c2 = c1; //c = c1, c1 = c2, c2 = c;
+            l2 = l1; //l = l1, l1 = l2, l2 = l;
+        }
+        /* Filter out NOP operations like x*1, x-0, x&-1... */
+        if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV || 
+                     op == TOK_PDIV) && 
+                    l2 == 1) ||
+                   ((op == '+' || op == '-' || op == '|' || op == '^' || 
+                     op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) && 
+                    l2 == 0) ||
+                   (op == '&' && 
+                    l2 == -1))) {
+            /* nothing to do */
+            vtop--;
+        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
+            /* try to use shifts instead of muls or divs */
+            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
+                n = -1;
+                while (l2) {
+                    l2 >>= 1;
+                    n++;
+                }
+                vtop->c.ll = n;
+                if (op == '*')
+                    op = TOK_SHL;
+                else if (op == TOK_PDIV)
+                    op = TOK_SAR;
+                else
+                    op = TOK_SHR;
+            }
+            goto general_case;
+        } else if (c2 && (op == '+' || op == '-') &&
+                   ((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) ==
+                   (VT_CONST | VT_SYM) ||
+                   (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
+            /* symbol + constant case */
+            if (op == '-')
+                l2 = -l2;
+            vtop--;
+            vtop->c.ll += l2;
+        } else {
+        general_case:
+            if (!nocode_wanted) {
+                /* call low level op generator */
+                if (t1 == VT_LLONG || t2 == VT_LLONG) 
+                    gen_opl(op);
+                else
+                    gen_opi(op);
+            } else {
+                vtop--;
+            }
+        }
+    }
+}
+
+/* generate a floating point operation with constant propagation */
+void gen_opif(int op)
+{
+    int c1, c2;
+    SValue *v1, *v2;
+    long double f1, f2;
+
+    v1 = vtop - 1;
+    v2 = vtop;
+    /* currently, we cannot do computations with forward symbols */
+    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    if (c1 && c2) {
+        if (v1->type.t == VT_FLOAT) {
+            f1 = v1->c.f;
+            f2 = v2->c.f;
+        } else if (v1->type.t == VT_DOUBLE) {
+            f1 = v1->c.d;
+            f2 = v2->c.d;
+        } else {
+            f1 = v1->c.ld;
+            f2 = v2->c.ld;
+        }
+
+        /* NOTE: we only do constant propagation if finite number (not
+           NaN or infinity) (ANSI spec) */
+        if (!ieee_finite(f1) || !ieee_finite(f2))
+            goto general_case;
+
+        switch(op) {
+        case '+': f1 += f2; break;
+        case '-': f1 -= f2; break;
+        case '*': f1 *= f2; break;
+        case '/': 
+            if (f2 == 0.0) {
+                if (const_wanted)
+                    error("division by zero in constant");
+                goto general_case;
+            }
+            f1 /= f2; 
+            break;
+            /* XXX: also handles tests ? */
+        default:
+            goto general_case;
+        }
+        /* XXX: overflow test ? */
+        if (v1->type.t == VT_FLOAT) {
+            v1->c.f = f1;
+        } else if (v1->type.t == VT_DOUBLE) {
+            v1->c.d = f1;
+        } else {
+            v1->c.ld = f1;
+        }
+        vtop--;
+    } else {
+    general_case:
+        if (!nocode_wanted) {
+            gen_opf(op);
+        } else {
+            vtop--;
+        }
+    }
+}
+
+static int pointed_size(CType *type)
+{
+    int align;
+    return type_size(pointed_type(type), &align);
+}
+
+static inline int is_null_pointer(SValue *p)
+{
+    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        return 0;
+    return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) ||
+        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0);
+}
+
+static inline int is_integer_btype(int bt)
+{
+    return (bt == VT_BYTE || bt == VT_SHORT || 
+            bt == VT_INT || bt == VT_LLONG);
+}
+
+/* check types for comparison or substraction of pointers */
+static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
+{
+    CType *type1, *type2, tmp_type1, tmp_type2;
+    int bt1, bt2;
+    
+    /* null pointers are accepted for all comparisons as gcc */
+    if (is_null_pointer(p1) || is_null_pointer(p2))
+        return;
+    type1 = &p1->type;
+    type2 = &p2->type;
+    bt1 = type1->t & VT_BTYPE;
+    bt2 = type2->t & VT_BTYPE;
+    /* accept comparison between pointer and integer with a warning */
+    if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
+        if (op != TOK_LOR && op != TOK_LAND )
+            warning("comparison between pointer and integer");
+        return;
+    }
+
+    /* both must be pointers or implicit function pointers */
+    if (bt1 == VT_PTR) {
+        type1 = pointed_type(type1);
+    } else if (bt1 != VT_FUNC) 
+        goto invalid_operands;
+
+    if (bt2 == VT_PTR) {
+        type2 = pointed_type(type2);
+    } else if (bt2 != VT_FUNC) { 
+    invalid_operands:
+        error("invalid operands to binary %s", get_tok_str(op, NULL));
+    }
+    if ((type1->t & VT_BTYPE) == VT_VOID || 
+        (type2->t & VT_BTYPE) == VT_VOID)
+        return;
+    tmp_type1 = *type1;
+    tmp_type2 = *type2;
+    tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
+        /* gcc-like error if '-' is used */
+        if (op == '-')
+            goto invalid_operands;
+        else
+            warning("comparison of distinct pointer types lacks a cast");
+    }
+}
+
+/* generic gen_op: handles types problems */
+void gen_op(int op)
+{
+    int u, t1, t2, bt1, bt2, t;
+    CType type1;
+
+    t1 = vtop[-1].type.t;
+    t2 = vtop[0].type.t;
+    bt1 = t1 & VT_BTYPE;
+    bt2 = t2 & VT_BTYPE;
+        
+    if (bt1 == VT_PTR || bt2 == VT_PTR) {
+        /* at least one operand is a pointer */
+        /* relationnal op: must be both pointers */
+        if (op >= TOK_ULT && op <= TOK_LOR) {
+            check_comparison_pointer_types(vtop - 1, vtop, op);
+            /* pointers are handled are unsigned */
+#ifdef TCC_TARGET_X86_64
+            t = VT_LLONG | VT_UNSIGNED;
+#else
+            t = VT_INT | VT_UNSIGNED;
+#endif
+            goto std_op;
+        }
+        /* if both pointers, then it must be the '-' op */
+        if (bt1 == VT_PTR && bt2 == VT_PTR) {
+            if (op != '-')
+                error("cannot use pointers here");
+            check_comparison_pointer_types(vtop - 1, vtop, op);
+            /* XXX: check that types are compatible */
+            u = pointed_size(&vtop[-1].type);
+            gen_opic(op);
+            /* set to integer type */
+#ifdef TCC_TARGET_X86_64
+            vtop->type.t = VT_LLONG;
+#else
+            vtop->type.t = VT_INT; 
+#endif
+            vpushi(u);
+            gen_op(TOK_PDIV);
+        } else {
+            /* exactly one pointer : must be '+' or '-'. */
+            if (op != '-' && op != '+')
+                error("cannot use pointers here");
+            /* Put pointer as first operand */
+            if (bt2 == VT_PTR) {
+                vswap();
+                swap(&t1, &t2);
+            }
+            type1 = vtop[-1].type;
+#ifdef TCC_TARGET_X86_64
+            vpushll(pointed_size(&vtop[-1].type));
+#else
+            /* XXX: cast to int ? (long long case) */
+            vpushi(pointed_size(&vtop[-1].type));
+#endif
+            gen_op('*');
+#ifdef CONFIG_TCC_BCHECK
+            /* if evaluating constant expression, no code should be
+               generated, so no bound check */
+            if (tcc_state->do_bounds_check && !const_wanted) {
+                /* if bounded pointers, we generate a special code to
+                   test bounds */
+                if (op == '-') {
+                    vpushi(0);
+                    vswap();
+                    gen_op('-');
+                }
+                gen_bounded_ptr_add();
+            } else
+#endif
+            {
+                gen_opic(op);
+            }
+            /* put again type if gen_opic() swaped operands */
+            vtop->type = type1;
+        }
+    } else if (is_float(bt1) || is_float(bt2)) {
+        /* compute bigger type and do implicit casts */
+        if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+            t = VT_LDOUBLE;
+        } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+            t = VT_DOUBLE;
+        } else {
+            t = VT_FLOAT;
+        }
+        /* floats can only be used for a few operations */
+        if (op != '+' && op != '-' && op != '*' && op != '/' &&
+            (op < TOK_ULT || op > TOK_GT))
+            error("invalid operands for binary operation");
+        goto std_op;
+    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+        /* cast to biggest op */
+        t = VT_LLONG;
+        /* convert to unsigned if it does not fit in a long long */
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
+            t |= VT_UNSIGNED;
+        goto std_op;
+    } else {
+        /* integer operations */
+        t = VT_INT;
+        /* convert to unsigned if it does not fit in an integer */
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
+            t |= VT_UNSIGNED;
+    std_op:
+        /* XXX: currently, some unsigned operations are explicit, so
+           we modify them here */
+        if (t & VT_UNSIGNED) {
+            if (op == TOK_SAR)
+                op = TOK_SHR;
+            else if (op == '/')
+                op = TOK_UDIV;
+            else if (op == '%')
+                op = TOK_UMOD;
+            else if (op == TOK_LT)
+                op = TOK_ULT;
+            else if (op == TOK_GT)
+                op = TOK_UGT;
+            else if (op == TOK_LE)
+                op = TOK_ULE;
+            else if (op == TOK_GE)
+                op = TOK_UGE;
+        }
+        vswap();
+        type1.t = t;
+        gen_cast(&type1);
+        vswap();
+        /* special case for shifts and long long: we keep the shift as
+           an integer */
+        if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
+            type1.t = VT_INT;
+        gen_cast(&type1);
+        if (is_float(t))
+            gen_opif(op);
+        else
+            gen_opic(op);
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* relationnal op: the result is an int */
+            vtop->type.t = VT_INT;
+        } else {
+            vtop->type.t = t;
+        }
+    }
+}
+
+#ifndef TCC_TARGET_ARM
+/* generic itof for unsigned long long case */
+void gen_cvt_itof1(int t)
+{
+    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
+        (VT_LLONG | VT_UNSIGNED)) {
+
+        if (t == VT_FLOAT)
+            vpush_global_sym(&func_old_type, TOK___floatundisf);
+#if LDOUBLE_SIZE != 8
+        else if (t == VT_LDOUBLE)
+            vpush_global_sym(&func_old_type, TOK___floatundixf);
+#endif
+        else
+            vpush_global_sym(&func_old_type, TOK___floatundidf);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->r = reg_fret(t);
+    } else {
+        gen_cvt_itof(t);
+    }
+}
+#endif
+
+/* generic ftoi for unsigned long long case */
+void gen_cvt_ftoi1(int t)
+{
+    int st;
+
+    if (t == (VT_LLONG | VT_UNSIGNED)) {
+        /* not handled natively */
+        st = vtop->type.t & VT_BTYPE;
+        if (st == VT_FLOAT)
+            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
+#if LDOUBLE_SIZE != 8
+        else if (st == VT_LDOUBLE)
+            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
+#endif
+        else
+            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->r = REG_IRET;
+        vtop->r2 = REG_LRET;
+    } else {
+        gen_cvt_ftoi(t);
+    }
+}
+
+/* force char or short cast */
+void force_charshort_cast(int t)
+{
+    int bits, dbt;
+    dbt = t & VT_BTYPE;
+    /* XXX: add optimization if lvalue : just change type and offset */
+    if (dbt == VT_BYTE)
+        bits = 8;
+    else
+        bits = 16;
+    if (t & VT_UNSIGNED) {
+        vpushi((1 << bits) - 1);
+        gen_op('&');
+    } else {
+        bits = 32 - bits;
+        vpushi(bits);
+        gen_op(TOK_SHL);
+        /* result must be signed or the SAR is converted to an SHL
+           This was not the case when "t" was a signed short
+           and the last value on the stack was an unsigned int */
+        vtop->type.t &= ~VT_UNSIGNED;
+        vpushi(bits);
+        gen_op(TOK_SAR);
+    }
+}
+
+/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
+static void gen_cast(CType *type)
+{
+    int sbt, dbt, sf, df, c, p;
+
+    /* special delayed cast for char/short */
+    /* XXX: in some cases (multiple cascaded casts), it may still
+       be incorrect */
+    if (vtop->r & VT_MUSTCAST) {
+        vtop->r &= ~VT_MUSTCAST;
+        force_charshort_cast(vtop->type.t);
+    }
+
+    /* bitfields first get cast to ints */
+    if (vtop->type.t & VT_BITFIELD) {
+        gv(RC_INT);
+    }
+
+    dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
+    sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+
+    if (sbt != dbt) {
+        sf = is_float(sbt);
+        df = is_float(dbt);
+        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+        p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
+        if (c) {
+            /* constant case: we can do it now */
+            /* XXX: in ISOC, cannot do it if error in convert */
+            if (sbt == VT_FLOAT)
+                vtop->c.ld = vtop->c.f;
+            else if (sbt == VT_DOUBLE)
+                vtop->c.ld = vtop->c.d;
+
+            if (df) {
+                if ((sbt & VT_BTYPE) == VT_LLONG) {
+                    if (sbt & VT_UNSIGNED)
+                        vtop->c.ld = vtop->c.ull;
+                    else
+                        vtop->c.ld = vtop->c.ll;
+                } else if(!sf) {
+                    if (sbt & VT_UNSIGNED)
+                        vtop->c.ld = vtop->c.ui;
+                    else
+                        vtop->c.ld = vtop->c.i;
+                }
+
+                if (dbt == VT_FLOAT)
+                    vtop->c.f = (float)vtop->c.ld;
+                else if (dbt == VT_DOUBLE)
+                    vtop->c.d = (double)vtop->c.ld;
+            } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
+                vtop->c.ull = (unsigned long long)vtop->c.ld;
+            } else if (sf && dbt == VT_BOOL) {
+                vtop->c.i = (vtop->c.ld != 0);
+            } else {
+                if(sf)
+                    vtop->c.ll = (long long)vtop->c.ld;
+                else if (sbt == (VT_LLONG|VT_UNSIGNED))
+                    vtop->c.ll = vtop->c.ull;
+                else if (sbt & VT_UNSIGNED)
+                    vtop->c.ll = vtop->c.ui;
+                else if (sbt != VT_LLONG)
+                    vtop->c.ll = vtop->c.i;
+
+                if (dbt == (VT_LLONG|VT_UNSIGNED))
+                    vtop->c.ull = vtop->c.ll;
+                else if (dbt == VT_BOOL)
+                    vtop->c.i = (vtop->c.ll != 0);
+                else if (dbt != VT_LLONG) {
+                    int s = 0;
+                    if ((dbt & VT_BTYPE) == VT_BYTE)
+                        s = 24;
+                    else if ((dbt & VT_BTYPE) == VT_SHORT)
+                        s = 16;
+
+                    if(dbt & VT_UNSIGNED)
+                        vtop->c.ui = ((unsigned int)vtop->c.ll << s) >> s;
+                    else
+                        vtop->c.i = ((int)vtop->c.ll << s) >> s;
+                }
+            }
+        } else if (p && dbt == VT_BOOL) {
+            vtop->r = VT_CONST;
+            vtop->c.i = 1;
+        } else if (!nocode_wanted) {
+            /* non constant case: generate code */
+            if (sf && df) {
+                /* convert from fp to fp */
+                gen_cvt_ftof(dbt);
+            } else if (df) {
+                /* convert int to fp */
+                gen_cvt_itof1(dbt);
+            } else if (sf) {
+                /* convert fp to int */
+                if (dbt == VT_BOOL) {
+                     vpushi(0);
+                     gen_op(TOK_NE);
+                } else {
+                    /* we handle char/short/etc... with generic code */
+                    if (dbt != (VT_INT | VT_UNSIGNED) &&
+                        dbt != (VT_LLONG | VT_UNSIGNED) &&
+                        dbt != VT_LLONG)
+                        dbt = VT_INT;
+                    gen_cvt_ftoi1(dbt);
+                    if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
+                        /* additional cast for char/short... */
+                        vtop->type.t = dbt;
+                        gen_cast(type);
+                    }
+                }
+#ifndef TCC_TARGET_X86_64
+            } else if ((dbt & VT_BTYPE) == VT_LLONG) {
+                if ((sbt & VT_BTYPE) != VT_LLONG) {
+                    /* scalar to long long */
+                    /* machine independent conversion */
+                    gv(RC_INT);
+                    /* generate high word */
+                    if (sbt == (VT_INT | VT_UNSIGNED)) {
+                        vpushi(0);
+                        gv(RC_INT);
+                    } else {
+                        if (sbt == VT_PTR) {
+                            /* cast from pointer to int before we apply
+                               shift operation, which pointers don't support*/
+                            gen_cast(&int_type);
+                        }
+                        gv_dup();
+                        vpushi(31);
+                        gen_op(TOK_SAR);
+                    }
+                    /* patch second register */
+                    vtop[-1].r2 = vtop->r;
+                    vpop();
+                }
+#else
+            } else if ((dbt & VT_BTYPE) == VT_LLONG ||
+                       (dbt & VT_BTYPE) == VT_PTR) {
+                /* XXX: not sure if this is perfect... need more tests */
+                if ((sbt & VT_BTYPE) != VT_LLONG) {
+                    int r = gv(RC_INT);
+                    if (sbt != (VT_INT | VT_UNSIGNED) &&
+                        sbt != VT_PTR && sbt != VT_FUNC) {
+                        /* x86_64 specific: movslq */
+                        o(0x6348);
+                        o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
+                    }
+                }
+#endif
+            } else if (dbt == VT_BOOL) {
+                /* scalar to bool */
+                vpushi(0);
+                gen_op(TOK_NE);
+            } else if ((dbt & VT_BTYPE) == VT_BYTE || 
+                       (dbt & VT_BTYPE) == VT_SHORT) {
+                if (sbt == VT_PTR) {
+                    vtop->type.t = VT_INT;
+                    warning("nonportable conversion from pointer to char/short");
+                }
+                force_charshort_cast(dbt);
+            } else if ((dbt & VT_BTYPE) == VT_INT) {
+                /* scalar to int */
+                if (sbt == VT_LLONG) {
+                    /* from long long: just take low order word */
+                    lexpand();
+                    vpop();
+                } 
+                /* if lvalue and single word type, nothing to do because
+                   the lvalue already contains the real type size (see
+                   VT_LVAL_xxx constants) */
+            }
+        }
+    } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
+        /* if we are casting between pointer types,
+           we must update the VT_LVAL_xxx size */
+        vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+                  | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
+    }
+    vtop->type = *type;
+}
+
+/* return type size. Put alignment at 'a' */
+static int type_size(CType *type, int *a)
+{
+    Sym *s;
+    int bt;
+
+    bt = type->t & VT_BTYPE;
+    if (bt == VT_STRUCT) {
+        /* struct/union */
+        s = type->ref;
+        *a = s->r;
+        return s->c;
+    } else if (bt == VT_PTR) {
+        if (type->t & VT_ARRAY) {
+            int ts;
+
+            s = type->ref;
+            ts = type_size(&s->type, a);
+
+            if (ts < 0 && s->c < 0)
+                ts = -ts;
+
+            return ts * s->c;
+        } else {
+            *a = PTR_SIZE;
+            return PTR_SIZE;
+        }
+    } else if (bt == VT_LDOUBLE) {
+        *a = LDOUBLE_ALIGN;
+        return LDOUBLE_SIZE;
+    } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
+#ifdef TCC_TARGET_I386
+#ifdef TCC_TARGET_PE
+        *a = 8;
+#else
+        *a = 4;
+#endif
+#elif defined(TCC_TARGET_ARM)
+#ifdef TCC_ARM_EABI
+        *a = 8; 
+#else
+        *a = 4;
+#endif
+#else
+        *a = 8;
+#endif
+        return 8;
+    } else if (bt == VT_INT || bt == VT_ENUM || bt == VT_FLOAT) {
+        *a = 4;
+        return 4;
+    } else if (bt == VT_SHORT) {
+        *a = 2;
+        return 2;
+    } else {
+        /* char, void, function, _Bool */
+        *a = 1;
+        return 1;
+    }
+}
+
+/* return the pointed type of t */
+static inline CType *pointed_type(CType *type)
+{
+    return &type->ref->type;
+}
+
+/* modify type so that its it is a pointer to type. */
+static void mk_pointer(CType *type)
+{
+    Sym *s;
+    s = sym_push(SYM_FIELD, type, 0, -1);
+    type->t = VT_PTR | (type->t & ~VT_TYPE);
+    type->ref = s;
+}
+
+/* compare function types. OLD functions match any new functions */
+static int is_compatible_func(CType *type1, CType *type2)
+{
+    Sym *s1, *s2;
+
+    s1 = type1->ref;
+    s2 = type2->ref;
+    if (!is_compatible_types(&s1->type, &s2->type))
+        return 0;
+    /* check func_call */
+    if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
+        return 0;
+    /* XXX: not complete */
+    if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
+        return 1;
+    if (s1->c != s2->c)
+        return 0;
+    while (s1 != NULL) {
+        if (s2 == NULL)
+            return 0;
+        if (!is_compatible_parameter_types(&s1->type, &s2->type))
+            return 0;
+        s1 = s1->next;
+        s2 = s2->next;
+    }
+    if (s2)
+        return 0;
+    return 1;
+}
+
+/* return true if type1 and type2 are the same.  If unqualified is
+   true, qualifiers on the types are ignored.
+
+   - enums are not checked as gcc __builtin_types_compatible_p () 
+ */
+static int compare_types(CType *type1, CType *type2, int unqualified)
+{
+    int bt1, t1, t2;
+
+    t1 = type1->t & VT_TYPE;
+    t2 = type2->t & VT_TYPE;
+    if (unqualified) {
+        /* strip qualifiers before comparing */
+        t1 &= ~(VT_CONSTANT | VT_VOLATILE);
+        t2 &= ~(VT_CONSTANT | VT_VOLATILE);
+    }
+    /* XXX: bitfields ? */
+    if (t1 != t2)
+        return 0;
+    /* test more complicated cases */
+    bt1 = t1 & VT_BTYPE;
+    if (bt1 == VT_PTR) {
+        type1 = pointed_type(type1);
+        type2 = pointed_type(type2);
+        return is_compatible_types(type1, type2);
+    } else if (bt1 == VT_STRUCT) {
+        return (type1->ref == type2->ref);
+    } else if (bt1 == VT_FUNC) {
+        return is_compatible_func(type1, type2);
+    } else {
+        return 1;
+    }
+}
+
+/* return true if type1 and type2 are exactly the same (including
+   qualifiers). 
+*/
+static int is_compatible_types(CType *type1, CType *type2)
+{
+    return compare_types(type1,type2,0);
+}
+
+/* return true if type1 and type2 are the same (ignoring qualifiers).
+*/
+static int is_compatible_parameter_types(CType *type1, CType *type2)
+{
+    return compare_types(type1,type2,1);
+}
+
+/* print a type. If 'varstr' is not NULL, then the variable is also
+   printed in the type */
+/* XXX: union */
+/* XXX: add array and function pointers */
+void type_to_str(char *buf, int buf_size, 
+                 CType *type, const char *varstr)
+{
+    int bt, v, t;
+    Sym *s, *sa;
+    char buf1[256];
+    const char *tstr;
+
+    t = type->t & VT_TYPE;
+    bt = t & VT_BTYPE;
+    buf[0] = '\0';
+    if (t & VT_CONSTANT)
+        pstrcat(buf, buf_size, "const ");
+    if (t & VT_VOLATILE)
+        pstrcat(buf, buf_size, "volatile ");
+    if (t & VT_UNSIGNED)
+        pstrcat(buf, buf_size, "unsigned ");
+    switch(bt) {
+    case VT_VOID:
+        tstr = "void";
+        goto add_tstr;
+    case VT_BOOL:
+        tstr = "_Bool";
+        goto add_tstr;
+    case VT_BYTE:
+        tstr = "char";
+        goto add_tstr;
+    case VT_SHORT:
+        tstr = "short";
+        goto add_tstr;
+    case VT_INT:
+        tstr = "int";
+        goto add_tstr;
+    case VT_LONG:
+        tstr = "long";
+        goto add_tstr;
+    case VT_LLONG:
+        tstr = "long long";
+        goto add_tstr;
+    case VT_FLOAT:
+        tstr = "float";
+        goto add_tstr;
+    case VT_DOUBLE:
+        tstr = "double";
+        goto add_tstr;
+    case VT_LDOUBLE:
+        tstr = "long double";
+    add_tstr:
+        pstrcat(buf, buf_size, tstr);
+        break;
+    case VT_ENUM:
+    case VT_STRUCT:
+        if (bt == VT_STRUCT)
+            tstr = "struct ";
+        else
+            tstr = "enum ";
+        pstrcat(buf, buf_size, tstr);
+        v = type->ref->v & ~SYM_STRUCT;
+        if (v >= SYM_FIRST_ANOM)
+            pstrcat(buf, buf_size, "<anonymous>");
+        else
+            pstrcat(buf, buf_size, get_tok_str(v, NULL));
+        break;
+    case VT_FUNC:
+        s = type->ref;
+        type_to_str(buf, buf_size, &s->type, varstr);
+        pstrcat(buf, buf_size, "(");
+        sa = s->next;
+        while (sa != NULL) {
+            type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
+            pstrcat(buf, buf_size, buf1);
+            sa = sa->next;
+            if (sa)
+                pstrcat(buf, buf_size, ", ");
+        }
+        pstrcat(buf, buf_size, ")");
+        goto no_var;
+    case VT_PTR:
+        s = type->ref;
+        pstrcpy(buf1, sizeof(buf1), "*");
+        if (varstr)
+            pstrcat(buf1, sizeof(buf1), varstr);
+        type_to_str(buf, buf_size, &s->type, buf1);
+        goto no_var;
+    }
+    if (varstr) {
+        pstrcat(buf, buf_size, " ");
+        pstrcat(buf, buf_size, varstr);
+    }
+ no_var: ;
+}
+
+/* verify type compatibility to store vtop in 'dt' type, and generate
+   casts if needed. */
+static void gen_assign_cast(CType *dt)
+{
+    CType *st, *type1, *type2, tmp_type1, tmp_type2;
+    char buf1[256], buf2[256];
+    int dbt, sbt;
+
+    st = &vtop->type; /* source type */
+    dbt = dt->t & VT_BTYPE;
+    sbt = st->t & VT_BTYPE;
+    if (dt->t & VT_CONSTANT)
+        warning("assignment of read-only location");
+    switch(dbt) {
+    case VT_PTR:
+        /* special cases for pointers */
+        /* '0' can also be a pointer */
+        if (is_null_pointer(vtop))
+            goto type_ok;
+        /* accept implicit pointer to integer cast with warning */
+        if (is_integer_btype(sbt)) {
+            warning("assignment makes pointer from integer without a cast");
+            goto type_ok;
+        }
+        type1 = pointed_type(dt);
+        /* a function is implicitely a function pointer */
+        if (sbt == VT_FUNC) {
+            if ((type1->t & VT_BTYPE) != VT_VOID &&
+                !is_compatible_types(pointed_type(dt), st))
+                goto error;
+            else
+                goto type_ok;
+        }
+        if (sbt != VT_PTR)
+            goto error;
+        type2 = pointed_type(st);
+        if ((type1->t & VT_BTYPE) == VT_VOID || 
+            (type2->t & VT_BTYPE) == VT_VOID) {
+            /* void * can match anything */
+        } else {
+            /* exact type match, except for unsigned */
+            tmp_type1 = *type1;
+            tmp_type2 = *type2;
+            tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+            tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+            if (!is_compatible_types(&tmp_type1, &tmp_type2))
+                warning("assignment from incompatible pointer type");
+        }
+        /* check const and volatile */
+        if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
+            (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
+            warning("assignment discards qualifiers from pointer target type");
+        break;
+    case VT_BYTE:
+    case VT_SHORT:
+    case VT_INT:
+    case VT_LLONG:
+        if (sbt == VT_PTR || sbt == VT_FUNC) {
+            warning("assignment makes integer from pointer without a cast");
+        }
+        /* XXX: more tests */
+        break;
+    case VT_STRUCT:
+        tmp_type1 = *dt;
+        tmp_type2 = *st;
+        tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
+        tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
+        if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
+        error:
+            type_to_str(buf1, sizeof(buf1), st, NULL);
+            type_to_str(buf2, sizeof(buf2), dt, NULL);
+            error("cannot cast '%s' to '%s'", buf1, buf2);
+        }
+        break;
+    }
+ type_ok:
+    gen_cast(dt);
+}
+
+/* store vtop in lvalue pushed on stack */
+void vstore(void)
+{
+    int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
+
+    ft = vtop[-1].type.t;
+    sbt = vtop->type.t & VT_BTYPE;
+    dbt = ft & VT_BTYPE;
+    if (((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
+        (sbt == VT_INT && dbt == VT_SHORT)) {
+        /* optimize char/short casts */
+        delayed_cast = VT_MUSTCAST;
+        vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)));
+        /* XXX: factorize */
+        if (ft & VT_CONSTANT)
+            warning("assignment of read-only location");
+    } else {
+        delayed_cast = 0;
+        if (!(ft & VT_BITFIELD))
+            gen_assign_cast(&vtop[-1].type);
+    }
+
+    if (sbt == VT_STRUCT) {
+        /* if structure, only generate pointer */
+        /* structure assignment : generate memcpy */
+        /* XXX: optimize if small size */
+        if (!nocode_wanted) {
+            size = type_size(&vtop->type, &align);
+
+#ifdef TCC_ARM_EABI
+            if(!(align & 7))
+                vpush_global_sym(&func_old_type, TOK_memcpy8);
+            else if(!(align & 3))
+                vpush_global_sym(&func_old_type, TOK_memcpy4);
+            else
+#endif
+            vpush_global_sym(&func_old_type, TOK_memcpy);
+
+            /* destination */
+            vpushv(vtop - 2);
+            vtop->type.t = VT_PTR;
+            gaddrof();
+            /* source */
+            vpushv(vtop - 2);
+            vtop->type.t = VT_PTR;
+            gaddrof();
+            /* type size */
+            vpushi(size);
+            gfunc_call(3);
+            
+            vswap();
+            vpop();
+        } else {
+            vswap();
+            vpop();
+        }
+        /* leave source on stack */
+    } else if (ft & VT_BITFIELD) {
+        /* bitfield store handling */
+        bit_pos = (ft >> VT_STRUCT_SHIFT) & 0x3f;
+        bit_size = (ft >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
+        /* remove bit field info to avoid loops */
+        vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
+
+        /* duplicate source into other register */
+        gv_dup();
+        vswap();
+        vrott(3);
+
+        if((ft & VT_BTYPE) == VT_BOOL) {
+            gen_cast(&vtop[-1].type);
+            vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
+        }
+
+        /* duplicate destination */
+        vdup();
+        vtop[-1] = vtop[-2];
+
+        /* mask and shift source */
+        if((ft & VT_BTYPE) != VT_BOOL) {
+            if((ft & VT_BTYPE) == VT_LLONG) {
+                vpushll((1ULL << bit_size) - 1ULL);
+            } else {
+                vpushi((1 << bit_size) - 1);
+            }
+            gen_op('&');
+        }
+        vpushi(bit_pos);
+        gen_op(TOK_SHL);
+        /* load destination, mask and or with source */
+        vswap();
+        if((ft & VT_BTYPE) == VT_LLONG) {
+            vpushll(~(((1ULL << bit_size) - 1ULL) << bit_pos));
+        } else {
+            vpushi(~(((1 << bit_size) - 1) << bit_pos));
+        }
+        gen_op('&');
+        gen_op('|');
+        /* store result */
+        vstore();
+
+        /* pop off shifted source from "duplicate source..." above */
+        vpop();
+
+    } else {
+#ifdef CONFIG_TCC_BCHECK
+        /* bound check case */
+        if (vtop[-1].r & VT_MUSTBOUND) {
+            vswap();
+            gbound();
+            vswap();
+        }
+#endif
+        if (!nocode_wanted) {
+            rc = RC_INT;
+            if (is_float(ft)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                }
+#endif
+            }
+            r = gv(rc);  /* generate value */
+            /* if lvalue was saved on stack, must read it */
+            if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
+                SValue sv;
+                t = get_reg(RC_INT);
+#ifdef TCC_TARGET_X86_64
+                sv.type.t = VT_PTR;
+#else
+                sv.type.t = VT_INT;
+#endif
+                sv.r = VT_LOCAL | VT_LVAL;
+                sv.c.ul = vtop[-1].c.ul;
+                load(t, &sv);
+                vtop[-1].r = t | VT_LVAL;
+            }
+            store(r, vtop - 1);
+#ifndef TCC_TARGET_X86_64
+            /* two word case handling : store second register at word + 4 */
+            if ((ft & VT_BTYPE) == VT_LLONG) {
+                vswap();
+                /* convert to int to increment easily */
+                vtop->type.t = VT_INT;
+                gaddrof();
+                vpushi(4);
+                gen_op('+');
+                vtop->r |= VT_LVAL;
+                vswap();
+                /* XXX: it works because r2 is spilled last ! */
+                store(vtop->r2, vtop - 1);
+            }
+#endif
+        }
+        vswap();
+        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+        vtop->r |= delayed_cast;
+    }
+}
+
+/* post defines POST/PRE add. c is the token ++ or -- */
+void inc(int post, int c)
+{
+    test_lvalue();
+    vdup(); /* save lvalue */
+    if (post) {
+        gv_dup(); /* duplicate value */
+        vrotb(3);
+        vrotb(3);
+    }
+    /* add constant */
+    vpushi(c - TOK_MID); 
+    gen_op('+');
+    vstore(); /* store value */
+    if (post)
+        vpop(); /* if post op, return saved value */
+}
+
+/* Parse GNUC __attribute__ extension. Currently, the following
+   extensions are recognized:
+   - aligned(n) : set data/function alignment.
+   - packed : force data alignment to 1
+   - section(x) : generate data/code in this section.
+   - unused : currently ignored, but may be used someday.
+   - regparm(n) : pass function parameters in registers (i386 only)
+ */
+static void parse_attribute(AttributeDef *ad)
+{
+    int t, n;
+    
+    while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
+    next();
+    skip('(');
+    skip('(');
+    while (tok != ')') {
+        if (tok < TOK_IDENT)
+            expect("attribute name");
+        t = tok;
+        next();
+        switch(t) {
+        case TOK_SECTION1:
+        case TOK_SECTION2:
+            skip('(');
+            if (tok != TOK_STR)
+                expect("section name");
+            ad->section = find_section(tcc_state, (char *)tokc.cstr->data);
+            next();
+            skip(')');
+            break;
+        case TOK_ALIGNED1:
+        case TOK_ALIGNED2:
+            if (tok == '(') {
+                next();
+                n = expr_const();
+                if (n <= 0 || (n & (n - 1)) != 0) 
+                    error("alignment must be a positive power of two");
+                skip(')');
+            } else {
+                n = MAX_ALIGN;
+            }
+            ad->aligned = n;
+            break;
+        case TOK_PACKED1:
+        case TOK_PACKED2:
+            ad->packed = 1;
+            break;
+        case TOK_UNUSED1:
+        case TOK_UNUSED2:
+            /* currently, no need to handle it because tcc does not
+               track unused objects */
+            break;
+        case TOK_NORETURN1:
+        case TOK_NORETURN2:
+            /* currently, no need to handle it because tcc does not
+               track unused objects */
+            break;
+        case TOK_CDECL1:
+        case TOK_CDECL2:
+        case TOK_CDECL3:
+            FUNC_CALL(ad->func_attr) = FUNC_CDECL;
+            break;
+        case TOK_STDCALL1:
+        case TOK_STDCALL2:
+        case TOK_STDCALL3:
+            FUNC_CALL(ad->func_attr) = FUNC_STDCALL;
+            break;
+#ifdef TCC_TARGET_I386
+        case TOK_REGPARM1:
+        case TOK_REGPARM2:
+            skip('(');
+            n = expr_const();
+            if (n > 3) 
+                n = 3;
+            else if (n < 0)
+                n = 0;
+            if (n > 0)
+                FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1;
+            skip(')');
+            break;
+        case TOK_FASTCALL1:
+        case TOK_FASTCALL2:
+        case TOK_FASTCALL3:
+            FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW;
+            break;            
+#endif
+        case TOK_DLLEXPORT:
+            FUNC_EXPORT(ad->func_attr) = 1;
+            break;
+        default:
+            if (tcc_state->warn_unsupported)
+                warning("'%s' attribute ignored", get_tok_str(t, NULL));
+            /* skip parameters */
+            if (tok == '(') {
+                int parenthesis = 0;
+                do {
+                    if (tok == '(') 
+                        parenthesis++;
+                    else if (tok == ')') 
+                        parenthesis--;
+                    next();
+                } while (parenthesis && tok != -1);
+            }
+            break;
+        }
+        if (tok != ',')
+            break;
+        next();
+    }
+    skip(')');
+    skip(')');
+    }
+}
+
+/* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */
+static void struct_decl(CType *type, int u)
+{
+    int a, v, size, align, maxalign, c, offset;
+    int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt;
+    Sym *s, *ss, *ass, **ps;
+    AttributeDef ad;
+    CType type1, btype;
+
+    a = tok; /* save decl type */
+    next();
+    if (tok != '{') {
+        v = tok;
+        next();
+        /* struct already defined ? return it */
+        if (v < TOK_IDENT)
+            expect("struct/union/enum name");
+        s = struct_find(v);
+        if (s) {
+            if (s->type.t != a)
+                error("invalid type");
+            goto do_decl;
+        }
+    } else {
+        v = anon_sym++;
+    }
+    type1.t = a;
+    /* we put an undefined size for struct/union */
+    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
+    s->r = 0; /* default alignment is zero as gcc */
+    /* put struct/union/enum name in type */
+ do_decl:
+    type->t = u;
+    type->ref = s;
+    
+    if (tok == '{') {
+        next();
+        if (s->c != -1)
+            error("struct/union/enum already defined");
+        /* cannot be empty */
+        c = 0;
+        /* non empty enums are not allowed */
+        if (a == TOK_ENUM) {
+            for(;;) {
+                v = tok;
+                if (v < TOK_UIDENT)
+                    expect("identifier");
+                next();
+                if (tok == '=') {
+                    next();
+                    c = expr_const();
+                }
+                /* enum symbols have static storage */
+                ss = sym_push(v, &int_type, VT_CONST, c);
+                ss->type.t |= VT_STATIC;
+                if (tok != ',')
+                    break;
+                next();
+                c++;
+                /* NOTE: we accept a trailing comma */
+                if (tok == '}')
+                    break;
+            }
+            skip('}');
+        } else {
+            maxalign = 1;
+            ps = &s->next;
+            prevbt = VT_INT;
+            bit_pos = 0;
+            offset = 0;
+            while (tok != '}') {
+                parse_btype(&btype, &ad);
+                while (1) {
+                    bit_size = -1;
+                    v = 0;
+                    type1 = btype;
+                    if (tok != ':') {
+                        type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT);
+                        if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT)
+                            expect("identifier");
+                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
+                            (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
+                            error("invalid type for '%s'", 
+                                  get_tok_str(v, NULL));
+                    }
+                    if (tok == ':') {
+                        next();
+                        bit_size = expr_const();
+                        /* XXX: handle v = 0 case for messages */
+                        if (bit_size < 0)
+                            error("negative width in bit-field '%s'", 
+                                  get_tok_str(v, NULL));
+                        if (v && bit_size == 0)
+                            error("zero width for bit-field '%s'", 
+                                  get_tok_str(v, NULL));
+                    }
+                    size = type_size(&type1, &align);
+                    if (ad.aligned) {
+                        if (align < ad.aligned)
+                            align = ad.aligned;
+                    } else if (ad.packed) {
+                        align = 1;
+                    } else if (*tcc_state->pack_stack_ptr) {
+                        if (align > *tcc_state->pack_stack_ptr)
+                            align = *tcc_state->pack_stack_ptr;
+                    }
+                    lbit_pos = 0;
+                    if (bit_size >= 0) {
+                        bt = type1.t & VT_BTYPE;
+                        if (bt != VT_INT && 
+                            bt != VT_BYTE && 
+                            bt != VT_SHORT &&
+                            bt != VT_BOOL &&
+                            bt != VT_ENUM &&
+                            bt != VT_LLONG)
+                            error("bitfields must have scalar type");
+                        bsize = size * 8;
+                        if (bit_size > bsize) {
+                            error("width of '%s' exceeds its type",
+                                  get_tok_str(v, NULL));
+                        } else if (bit_size == bsize) {
+                            /* no need for bit fields */
+                            bit_pos = 0;
+                        } else if (bit_size == 0) {
+                            /* XXX: what to do if only padding in a
+                               structure ? */
+                            /* zero size: means to pad */
+                            bit_pos = 0;
+                        } else {
+                            /* we do not have enough room ?
+                               did the type change?
+                               is it a union? */
+                            if ((bit_pos + bit_size) > bsize ||
+                                bt != prevbt || a == TOK_UNION)
+                                bit_pos = 0;
+                            lbit_pos = bit_pos;
+                            /* XXX: handle LSB first */
+                            type1.t |= VT_BITFIELD | 
+                                (bit_pos << VT_STRUCT_SHIFT) |
+                                (bit_size << (VT_STRUCT_SHIFT + 6));
+                            bit_pos += bit_size;
+                        }
+                        prevbt = bt;
+                    } else {
+                        bit_pos = 0;
+                    }
+                    if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
+                        /* add new memory data only if starting
+                           bit field */
+                        if (lbit_pos == 0) {
+                            if (a == TOK_STRUCT) {
+                                c = (c + align - 1) & -align;
+                                offset = c;
+                                if (size > 0)
+                                    c += size;
+                            } else {
+                                offset = 0;
+                                if (size > c)
+                                    c = size;
+                            }
+                            if (align > maxalign)
+                                maxalign = align;
+                        }
+#if 0
+                        printf("add field %s offset=%d", 
+                               get_tok_str(v, NULL), offset);
+                        if (type1.t & VT_BITFIELD) {
+                            printf(" pos=%d size=%d", 
+                                   (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
+                                   (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
+                        }
+                        printf("\n");
+#endif
+                    }
+                    if (v == 0 && (type1.t & VT_BTYPE) == VT_STRUCT) {
+                        ass = type1.ref;
+                        while ((ass = ass->next) != NULL) {
+                           ss = sym_push(ass->v, &ass->type, 0, offset + ass->c);
+                           *ps = ss;
+                           ps = &ss->next;
+                        }
+                    } else if (v) {
+                        ss = sym_push(v | SYM_FIELD, &type1, 0, offset);
+                        *ps = ss;
+                        ps = &ss->next;
+                    }
+                    if (tok == ';' || tok == TOK_EOF)
+                        break;
+                    skip(',');
+                }
+                skip(';');
+            }
+            skip('}');
+            /* store size and alignment */
+            s->c = (c + maxalign - 1) & -maxalign; 
+            s->r = maxalign;
+        }
+    }
+}
+
+/* return 0 if no type declaration. otherwise, return the basic type
+   and skip it. 
+ */
+static int parse_btype(CType *type, AttributeDef *ad)
+{
+    int t, u, type_found, typespec_found, typedef_found;
+    Sym *s;
+    CType type1;
+
+    memset(ad, 0, sizeof(AttributeDef));
+    type_found = 0;
+    typespec_found = 0;
+    typedef_found = 0;
+    t = 0;
+    while(1) {
+        switch(tok) {
+        case TOK_EXTENSION:
+            /* currently, we really ignore extension */
+            next();
+            continue;
+
+            /* basic types */
+        case TOK_CHAR:
+            u = VT_BYTE;
+        basic_type:
+            next();
+        basic_type1:
+            if ((t & VT_BTYPE) != 0)
+                error("too many basic types");
+            t |= u;
+            typespec_found = 1;
+            break;
+        case TOK_VOID:
+            u = VT_VOID;
+            goto basic_type;
+        case TOK_SHORT:
+            u = VT_SHORT;
+            goto basic_type;
+        case TOK_INT:
+            next();
+            typespec_found = 1;
+            break;
+        case TOK_LONG:
+            next();
+            if ((t & VT_BTYPE) == VT_DOUBLE) {
+                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
+            } else if ((t & VT_BTYPE) == VT_LONG) {
+                t = (t & ~VT_BTYPE) | VT_LLONG;
+            } else {
+                u = VT_LONG;
+                goto basic_type1;
+            }
+            break;
+        case TOK_BOOL:
+            u = VT_BOOL;
+            goto basic_type;
+        case TOK_FLOAT:
+            u = VT_FLOAT;
+            goto basic_type;
+        case TOK_DOUBLE:
+            next();
+            if ((t & VT_BTYPE) == VT_LONG) {
+                t = (t & ~VT_BTYPE) | VT_LDOUBLE;
+            } else {
+                u = VT_DOUBLE;
+                goto basic_type1;
+            }
+            break;
+        case TOK_ENUM:
+            struct_decl(&type1, VT_ENUM);
+        basic_type2:
+            u = type1.t;
+            type->ref = type1.ref;
+            goto basic_type1;
+        case TOK_STRUCT:
+        case TOK_UNION:
+            struct_decl(&type1, VT_STRUCT);
+            goto basic_type2;
+
+            /* type modifiers */
+        case TOK_CONST1:
+        case TOK_CONST2:
+        case TOK_CONST3:
+            t |= VT_CONSTANT;
+            next();
+            break;
+        case TOK_VOLATILE1:
+        case TOK_VOLATILE2:
+        case TOK_VOLATILE3:
+            t |= VT_VOLATILE;
+            next();
+            break;
+        case TOK_SIGNED1:
+        case TOK_SIGNED2:
+        case TOK_SIGNED3:
+            typespec_found = 1;
+            t |= VT_SIGNED;
+            next();
+            break;
+        case TOK_REGISTER:
+        case TOK_AUTO:
+        case TOK_RESTRICT1:
+        case TOK_RESTRICT2:
+        case TOK_RESTRICT3:
+            next();
+            break;
+        case TOK_UNSIGNED:
+            t |= VT_UNSIGNED;
+            next();
+            typespec_found = 1;
+            break;
+
+            /* storage */
+        case TOK_EXTERN:
+            t |= VT_EXTERN;
+            next();
+            break;
+        case TOK_STATIC:
+            t |= VT_STATIC;
+            next();
+            break;
+        case TOK_TYPEDEF:
+            t |= VT_TYPEDEF;
+            next();
+            break;
+        case TOK_INLINE1:
+        case TOK_INLINE2:
+        case TOK_INLINE3:
+            t |= VT_INLINE;
+            next();
+            break;
+
+            /* GNUC attribute */
+        case TOK_ATTRIBUTE1:
+        case TOK_ATTRIBUTE2:
+            parse_attribute(ad);
+            break;
+            /* GNUC typeof */
+        case TOK_TYPEOF1:
+        case TOK_TYPEOF2:
+        case TOK_TYPEOF3:
+            next();
+            parse_expr_type(&type1);
+            goto basic_type2;
+        default:
+            if (typespec_found || typedef_found)
+                goto the_end;
+            s = sym_find(tok);
+            if (!s || !(s->type.t & VT_TYPEDEF))
+                goto the_end;
+            typedef_found = 1;
+            t |= (s->type.t & ~VT_TYPEDEF);
+            type->ref = s->type.ref;
+            next();
+            typespec_found = 1;
+            break;
+        }
+        type_found = 1;
+    }
+the_end:
+    if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
+        error("signed and unsigned modifier");
+    if (tcc_state->char_is_unsigned) {
+        if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
+            t |= VT_UNSIGNED;
+    }
+    t &= ~VT_SIGNED;
+
+    /* long is never used as type */
+    if ((t & VT_BTYPE) == VT_LONG)
+#ifndef TCC_TARGET_X86_64
+        t = (t & ~VT_BTYPE) | VT_INT;
+#else
+        t = (t & ~VT_BTYPE) | VT_LLONG;
+#endif
+    type->t = t;
+    return type_found;
+}
+
+/* convert a function parameter type (array to pointer and function to
+   function pointer) */
+static inline void convert_parameter_type(CType *pt)
+{
+    /* remove const and volatile qualifiers (XXX: const could be used
+       to indicate a const function parameter */
+    pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
+    /* array must be transformed to pointer according to ANSI C */
+    pt->t &= ~VT_ARRAY;
+    if ((pt->t & VT_BTYPE) == VT_FUNC) {
+        mk_pointer(pt);
+    }
+}
+
+static void post_type(CType *type, AttributeDef *ad)
+{
+    int n, l, t1, arg_size, align;
+    Sym **plast, *s, *first;
+    AttributeDef ad1;
+    CType pt;
+
+    if (tok == '(') {
+        /* function declaration */
+        next();
+        l = 0;
+        first = NULL;
+        plast = &first;
+        arg_size = 0;
+        if (tok != ')') {
+            for(;;) {
+                /* read param name and compute offset */
+                if (l != FUNC_OLD) {
+                    if (!parse_btype(&pt, &ad1)) {
+                        if (l) {
+                            error("invalid type");
+                        } else {
+                            l = FUNC_OLD;
+                            goto old_proto;
+                        }
+                    }
+                    l = FUNC_NEW;
+                    if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
+                        break;
+                    type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
+                    if ((pt.t & VT_BTYPE) == VT_VOID)
+                        error("parameter declared as void");
+                    arg_size += (type_size(&pt, &align) + 3) & ~3;
+                } else {
+                old_proto:
+                    n = tok;
+                    if (n < TOK_UIDENT)
+                        expect("identifier");
+                    pt.t = VT_INT;
+                    next();
+                }
+                convert_parameter_type(&pt);
+                s = sym_push(n | SYM_FIELD, &pt, 0, 0);
+                *plast = s;
+                plast = &s->next;
+                if (tok == ')')
+                    break;
+                skip(',');
+                if (l == FUNC_NEW && tok == TOK_DOTS) {
+                    l = FUNC_ELLIPSIS;
+                    next();
+                    break;
+                }
+            }
+        }
+        /* if no parameters, then old type prototype */
+        if (l == 0)
+            l = FUNC_OLD;
+        skip(')');
+        t1 = type->t & VT_STORAGE;
+        /* NOTE: const is ignored in returned type as it has a special
+           meaning in gcc / C++ */
+        type->t &= ~(VT_STORAGE | VT_CONSTANT); 
+        post_type(type, ad);
+        /* we push a anonymous symbol which will contain the function prototype */
+        FUNC_ARGS(ad->func_attr) = arg_size;
+        s = sym_push(SYM_FIELD, type, ad->func_attr, l);
+        s->next = first;
+        type->t = t1 | VT_FUNC;
+        type->ref = s;
+    } else if (tok == '[') {
+        /* array definition */
+        next();
+        if (tok == TOK_RESTRICT1)
+            next();
+        n = -1;
+        if (tok != ']') {
+            n = expr_const();
+            if (n < 0)
+                error("invalid array size");    
+        }
+        skip(']');
+        /* parse next post type */
+        t1 = type->t & VT_STORAGE;
+        type->t &= ~VT_STORAGE;
+        post_type(type, ad);
+        
+        /* we push a anonymous symbol which will contain the array
+           element type */
+        s = sym_push(SYM_FIELD, type, 0, n);
+        type->t = t1 | VT_ARRAY | VT_PTR;
+        type->ref = s;
+    }
+}
+
+/* Parse a type declaration (except basic type), and return the type
+   in 'type'. 'td' is a bitmask indicating which kind of type decl is
+   expected. 'type' should contain the basic type. 'ad' is the
+   attribute definition of the basic type. It can be modified by
+   type_decl(). 
+ */
+static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
+{
+    Sym *s;
+    CType type1, *type2;
+    int qualifiers;
+    
+    while (tok == '*') {
+        qualifiers = 0;
+    redo:
+        next();
+        switch(tok) {
+        case TOK_CONST1:
+        case TOK_CONST2:
+        case TOK_CONST3:
+            qualifiers |= VT_CONSTANT;
+            goto redo;
+        case TOK_VOLATILE1:
+        case TOK_VOLATILE2:
+        case TOK_VOLATILE3:
+            qualifiers |= VT_VOLATILE;
+            goto redo;
+        case TOK_RESTRICT1:
+        case TOK_RESTRICT2:
+        case TOK_RESTRICT3:
+            goto redo;
+        }
+        mk_pointer(type);
+        type->t |= qualifiers;
+    }
+    
+    /* XXX: clarify attribute handling */
+    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
+        parse_attribute(ad);
+
+    /* recursive type */
+    /* XXX: incorrect if abstract type for functions (e.g. 'int ()') */
+    type1.t = 0; /* XXX: same as int */
+    if (tok == '(') {
+        next();
+        /* XXX: this is not correct to modify 'ad' at this point, but
+           the syntax is not clear */
+        if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
+            parse_attribute(ad);
+        type_decl(&type1, ad, v, td);
+        skip(')');
+    } else {
+        /* type identifier */
+        if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
+            *v = tok;
+            next();
+        } else {
+            if (!(td & TYPE_ABSTRACT))
+                expect("identifier");
+            *v = 0;
+        }
+    }
+    post_type(type, ad);
+    if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
+        parse_attribute(ad);
+    if (!type1.t)
+        return;
+    /* append type at the end of type1 */
+    type2 = &type1;
+    for(;;) {
+        s = type2->ref;
+        type2 = &s->type;
+        if (!type2->t) {
+            *type2 = *type;
+            break;
+        }
+    }
+    *type = type1;
+}
+
+/* compute the lvalue VT_LVAL_xxx needed to match type t. */
+static int lvalue_type(int t)
+{
+    int bt, r;
+    r = VT_LVAL;
+    bt = t & VT_BTYPE;
+    if (bt == VT_BYTE || bt == VT_BOOL)
+        r |= VT_LVAL_BYTE;
+    else if (bt == VT_SHORT)
+        r |= VT_LVAL_SHORT;
+    else
+        return r;
+    if (t & VT_UNSIGNED)
+        r |= VT_LVAL_UNSIGNED;
+    return r;
+}
+
+/* indirection with full error checking and bound check */
+static void indir(void)
+{
+    if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
+        if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
+            return;
+        expect("pointer");
+    }
+    if ((vtop->r & VT_LVAL) && !nocode_wanted)
+        gv(RC_INT);
+    vtop->type = *pointed_type(&vtop->type);
+    /* Arrays and functions are never lvalues */
+    if (!(vtop->type.t & VT_ARRAY)
+        && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
+        vtop->r |= lvalue_type(vtop->type.t);
+        /* if bound checking, the referenced pointer must be checked */
+        if (tcc_state->do_bounds_check)
+            vtop->r |= VT_MUSTBOUND;
+    }
+}
+
+/* pass a parameter to a function and do type checking and casting */
+static void gfunc_param_typed(Sym *func, Sym *arg)
+{
+    int func_type;
+    CType type;
+
+    func_type = func->c;
+    if (func_type == FUNC_OLD ||
+        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
+        /* default casting : only need to convert float to double */
+        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
+            type.t = VT_DOUBLE;
+            gen_cast(&type);
+        }
+    } else if (arg == NULL) {
+        error("too many arguments to function");
+    } else {
+        type = arg->type;
+        type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+        gen_assign_cast(&type);
+    }
+}
+
+/* parse an expression of the form '(type)' or '(expr)' and return its
+   type */
+static void parse_expr_type(CType *type)
+{
+    int n;
+    AttributeDef ad;
+
+    skip('(');
+    if (parse_btype(type, &ad)) {
+        type_decl(type, &ad, &n, TYPE_ABSTRACT);
+    } else {
+        expr_type(type);
+    }
+    skip(')');
+}
+
+static void parse_type(CType *type)
+{
+    AttributeDef ad;
+    int n;
+
+    if (!parse_btype(type, &ad)) {
+        expect("type");
+    }
+    type_decl(type, &ad, &n, TYPE_ABSTRACT);
+}
+
+static void vpush_tokc(int t)
+{
+    CType type;
+    type.t = t;
+    vsetc(&type, VT_CONST, &tokc);
+}
+
+static void unary(void)
+{
+    int n, t, align, size, r;
+    CType type;
+    Sym *s;
+    AttributeDef ad;
+
+    /* XXX: GCC 2.95.3 does not generate a table although it should be
+       better here */
+ tok_next:
+    switch(tok) {
+    case TOK_EXTENSION:
+        next();
+        goto tok_next;
+    case TOK_CINT:
+    case TOK_CCHAR: 
+    case TOK_LCHAR:
+        vpushi(tokc.i);
+        next();
+        break;
+    case TOK_CUINT:
+        vpush_tokc(VT_INT | VT_UNSIGNED);
+        next();
+        break;
+    case TOK_CLLONG:
+        vpush_tokc(VT_LLONG);
+        next();
+        break;
+    case TOK_CULLONG:
+        vpush_tokc(VT_LLONG | VT_UNSIGNED);
+        next();
+        break;
+    case TOK_CFLOAT:
+        vpush_tokc(VT_FLOAT);
+        next();
+        break;
+    case TOK_CDOUBLE:
+        vpush_tokc(VT_DOUBLE);
+        next();
+        break;
+    case TOK_CLDOUBLE:
+        vpush_tokc(VT_LDOUBLE);
+        next();
+        break;
+    case TOK___FUNCTION__:
+        if (!gnu_ext)
+            goto tok_identifier;
+        /* fall thru */
+    case TOK___FUNC__:
+        {
+            void *ptr;
+            int len;
+            /* special function name identifier */
+            len = strlen(funcname) + 1;
+            /* generate char[len] type */
+            type.t = VT_BYTE;
+            mk_pointer(&type);
+            type.t |= VT_ARRAY;
+            type.ref->c = len;
+            vpush_ref(&type, data_section, data_section->data_offset, len);
+            ptr = section_ptr_add(data_section, len);
+            memcpy(ptr, funcname, len);
+            next();
+        }
+        break;
+    case TOK_LSTR:
+#ifdef TCC_TARGET_PE
+        t = VT_SHORT | VT_UNSIGNED;
+#else
+        t = VT_INT;
+#endif
+        goto str_init;
+    case TOK_STR:
+        /* string parsing */
+        t = VT_BYTE;
+    str_init:
+        if (tcc_state->warn_write_strings)
+            t |= VT_CONSTANT;
+        type.t = t;
+        mk_pointer(&type);
+        type.t |= VT_ARRAY;
+        memset(&ad, 0, sizeof(AttributeDef));
+        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
+        break;
+    case '(':
+        next();
+        /* cast ? */
+        if (parse_btype(&type, &ad)) {
+            type_decl(&type, &ad, &n, TYPE_ABSTRACT);
+            skip(')');
+            /* check ISOC99 compound literal */
+            if (tok == '{') {
+                    /* data is allocated locally by default */
+                if (global_expr)
+                    r = VT_CONST;
+                else
+                    r = VT_LOCAL;
+                /* all except arrays are lvalues */
+                if (!(type.t & VT_ARRAY))
+                    r |= lvalue_type(type.t);
+                memset(&ad, 0, sizeof(AttributeDef));
+                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
+            } else {
+                unary();
+                gen_cast(&type);
+            }
+        } else if (tok == '{') {
+            /* save all registers */
+            save_regs(0); 
+            /* statement expression : we do not accept break/continue
+               inside as GCC does */
+            block(NULL, NULL, NULL, NULL, 0, 1);
+            skip(')');
+        } else {
+            gexpr();
+            skip(')');
+        }
+        break;
+    case '*':
+        next();
+        unary();
+        indir();
+        break;
+    case '&':
+        next();
+        unary();
+        /* functions names must be treated as function pointers,
+           except for unary '&' and sizeof. Since we consider that
+           functions are not lvalues, we only have to handle it
+           there and in function calls. */
+        /* arrays can also be used although they are not lvalues */
+        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
+            !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
+            test_lvalue();
+        mk_pointer(&vtop->type);
+        gaddrof();
+        break;
+    case '!':
+        next();
+        unary();
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            CType boolean;
+            boolean.t = VT_BOOL;
+            gen_cast(&boolean);
+            vtop->c.i = !vtop->c.i;
+        } else if ((vtop->r & VT_VALMASK) == VT_CMP)
+            vtop->c.i = vtop->c.i ^ 1;
+        else {
+            save_regs(1);
+            vseti(VT_JMP, gtst(1, 0));
+        }
+        break;
+    case '~':
+        next();
+        unary();
+        vpushi(-1);
+        gen_op('^');
+        break;
+    case '+':
+        next();
+        /* in order to force cast, we add zero */
+        unary();
+        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
+            error("pointer not accepted for unary plus");
+        vpushi(0);
+        gen_op('+');
+        break;
+    case TOK_SIZEOF:
+    case TOK_ALIGNOF1:
+    case TOK_ALIGNOF2:
+        t = tok;
+        next();
+        if (tok == '(') {
+            parse_expr_type(&type);
+        } else {
+            unary_type(&type);
+        }
+        size = type_size(&type, &align);
+        if (t == TOK_SIZEOF) {
+            if (size < 0)
+                error("sizeof applied to an incomplete type");
+            vpushi(size);
+        } else {
+            vpushi(align);
+        }
+        vtop->type.t |= VT_UNSIGNED;
+        break;
+
+    case TOK_builtin_types_compatible_p:
+        {
+            CType type1, type2;
+            next();
+            skip('(');
+            parse_type(&type1);
+            skip(',');
+            parse_type(&type2);
+            skip(')');
+            type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
+            type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
+            vpushi(is_compatible_types(&type1, &type2));
+        }
+        break;
+    case TOK_builtin_constant_p:
+        {
+            int saved_nocode_wanted, res;
+            next();
+            skip('(');
+            saved_nocode_wanted = nocode_wanted;
+            nocode_wanted = 1;
+            gexpr();
+            res = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+            vpop();
+            nocode_wanted = saved_nocode_wanted;
+            skip(')');
+            vpushi(res);
+        }
+        break;
+    case TOK_builtin_frame_address:
+        {
+            CType type;
+            next();
+            skip('(');
+            if (tok != TOK_CINT) {
+                error("__builtin_frame_address only takes integers");
+            }
+            if (tokc.i != 0) {
+                error("TCC only supports __builtin_frame_address(0)");
+            }
+            next();
+            skip(')');
+            type.t = VT_VOID;
+            mk_pointer(&type);
+            vset(&type, VT_LOCAL, 0);
+        }
+        break;
+#ifdef TCC_TARGET_X86_64
+    case TOK_builtin_malloc:
+        tok = TOK_malloc;
+        goto tok_identifier;
+    case TOK_builtin_free:
+        tok = TOK_free;
+        goto tok_identifier;
+#endif
+    case TOK_INC:
+    case TOK_DEC:
+        t = tok;
+        next();
+        unary();
+        inc(0, t);
+        break;
+    case '-':
+        next();
+        vpushi(0);
+        unary();
+        gen_op('-');
+        break;
+    case TOK_LAND:
+        if (!gnu_ext)
+            goto tok_identifier;
+        next();
+        /* allow to take the address of a label */
+        if (tok < TOK_UIDENT)
+            expect("label identifier");
+        s = label_find(tok);
+        if (!s) {
+            s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+        } else {
+            if (s->r == LABEL_DECLARED)
+                s->r = LABEL_FORWARD;
+        }
+        if (!s->type.t) {
+            s->type.t = VT_VOID;
+            mk_pointer(&s->type);
+            s->type.t |= VT_STATIC;
+        }
+        vset(&s->type, VT_CONST | VT_SYM, 0);
+        vtop->sym = s;
+        next();
+        break;
+    default:
+    tok_identifier:
+        t = tok;
+        next();
+        if (t < TOK_UIDENT)
+            expect("identifier");
+        s = sym_find(t);
+        if (!s) {
+            if (tok != '(')
+                error("'%s' undeclared", get_tok_str(t, NULL));
+            /* for simple function calls, we tolerate undeclared
+               external reference to int() function */
+            if (tcc_state->warn_implicit_function_declaration)
+                warning("implicit declaration of function '%s'",
+                        get_tok_str(t, NULL));
+            s = external_global_sym(t, &func_old_type, 0); 
+        }
+        if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
+            (VT_STATIC | VT_INLINE | VT_FUNC)) {
+            /* if referencing an inline function, then we generate a
+               symbol to it if not already done. It will have the
+               effect to generate code for it at the end of the
+               compilation unit. Inline function as always
+               generated in the text section. */
+            if (!s->c)
+                put_extern_sym(s, text_section, 0, 0);
+            r = VT_SYM | VT_CONST;
+        } else {
+            r = s->r;
+        }
+        vset(&s->type, r, s->c);
+        /* if forward reference, we must point to s */
+        if (vtop->r & VT_SYM) {
+            vtop->sym = s;
+            vtop->c.ul = 0;
+        }
+        break;
+    }
+    
+    /* post operations */
+    while (1) {
+        if (tok == TOK_INC || tok == TOK_DEC) {
+            inc(1, tok);
+            next();
+        } else if (tok == '.' || tok == TOK_ARROW) {
+            /* field */ 
+            if (tok == TOK_ARROW) 
+                indir();
+            test_lvalue();
+            gaddrof();
+            next();
+            /* expect pointer on structure */
+            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
+                expect("struct or union");
+            s = vtop->type.ref;
+            /* find field */
+            tok |= SYM_FIELD;
+            while ((s = s->next) != NULL) {
+                if (s->v == tok)
+                    break;
+            }
+            if (!s)
+                error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, NULL));
+            /* add field offset to pointer */
+            vtop->type = char_pointer_type; /* change type to 'char *' */
+            vpushi(s->c);
+            gen_op('+');
+            /* change type to field type, and set to lvalue */
+            vtop->type = s->type;
+            /* an array is never an lvalue */
+            if (!(vtop->type.t & VT_ARRAY)) {
+                vtop->r |= lvalue_type(vtop->type.t);
+                /* if bound checking, the referenced pointer must be checked */
+                if (tcc_state->do_bounds_check)
+                    vtop->r |= VT_MUSTBOUND;
+            }
+            next();
+        } else if (tok == '[') {
+            next();
+            gexpr();
+            gen_op('+');
+            indir();
+            skip(']');
+        } else if (tok == '(') {
+            SValue ret;
+            Sym *sa;
+            int nb_args;
+
+            /* function call  */
+            if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
+                /* pointer test (no array accepted) */
+                if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
+                    vtop->type = *pointed_type(&vtop->type);
+                    if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
+                        goto error_func;
+                } else {
+                error_func:
+                    expect("function pointer");
+                }
+            } else {
+                vtop->r &= ~VT_LVAL; /* no lvalue */
+            }
+            /* get return type */
+            s = vtop->type.ref;
+            next();
+            sa = s->next; /* first parameter */
+            nb_args = 0;
+            ret.r2 = VT_CONST;
+            /* compute first implicit argument if a structure is returned */
+            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
+                /* get some space for the returned structure */
+                size = type_size(&s->type, &align);
+                loc = (loc - size) & -align;
+                ret.type = s->type;
+                ret.r = VT_LOCAL | VT_LVAL;
+                /* pass it as 'int' to avoid structure arg passing
+                   problems */
+                vseti(VT_LOCAL, loc);
+                ret.c = vtop->c;
+                nb_args++;
+            } else {
+                ret.type = s->type; 
+                /* return in register */
+                if (is_float(ret.type.t)) {
+                    ret.r = reg_fret(ret.type.t);
+                } else {
+                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
+                        ret.r2 = REG_LRET;
+                    ret.r = REG_IRET;
+                }
+                ret.c.i = 0;
+            }
+            if (tok != ')') {
+                for(;;) {
+                    expr_eq();
+                    gfunc_param_typed(s, sa);
+                    nb_args++;
+                    if (sa)
+                        sa = sa->next;
+                    if (tok == ')')
+                        break;
+                    skip(',');
+                }
+            }
+            if (sa)
+                error("too few arguments to function");
+            skip(')');
+            if (!nocode_wanted) {
+                gfunc_call(nb_args);
+            } else {
+                vtop -= (nb_args + 1);
+            }
+            /* return value */
+            vsetc(&ret.type, ret.r, &ret.c);
+            vtop->r2 = ret.r2;
+        } else {
+            break;
+        }
+    }
+}
+
+static void uneq(void)
+{
+    int t;
+    
+    unary();
+    if (tok == '=' ||
+        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
+        tok == TOK_A_XOR || tok == TOK_A_OR ||
+        tok == TOK_A_SHL || tok == TOK_A_SAR) {
+        test_lvalue();
+        t = tok;
+        next();
+        if (t == '=') {
+            expr_eq();
+        } else {
+            vdup();
+            expr_eq();
+            gen_op(t & 0x7f);
+        }
+        vstore();
+    }
+}
+
+static void expr_prod(void)
+{
+    int t;
+
+    uneq();
+    while (tok == '*' || tok == '/' || tok == '%') {
+        t = tok;
+        next();
+        uneq();
+        gen_op(t);
+    }
+}
+
+static void expr_sum(void)
+{
+    int t;
+
+    expr_prod();
+    while (tok == '+' || tok == '-') {
+        t = tok;
+        next();
+        expr_prod();
+        gen_op(t);
+    }
+}
+
+static void expr_shift(void)
+{
+    int t;
+
+    expr_sum();
+    while (tok == TOK_SHL || tok == TOK_SAR) {
+        t = tok;
+        next();
+        expr_sum();
+        gen_op(t);
+    }
+}
+
+static void expr_cmp(void)
+{
+    int t;
+
+    expr_shift();
+    while ((tok >= TOK_ULE && tok <= TOK_GT) ||
+           tok == TOK_ULT || tok == TOK_UGE) {
+        t = tok;
+        next();
+        expr_shift();
+        gen_op(t);
+    }
+}
+
+static void expr_cmpeq(void)
+{
+    int t;
+
+    expr_cmp();
+    while (tok == TOK_EQ || tok == TOK_NE) {
+        t = tok;
+        next();
+        expr_cmp();
+        gen_op(t);
+    }
+}
+
+static void expr_and(void)
+{
+    expr_cmpeq();
+    while (tok == '&') {
+        next();
+        expr_cmpeq();
+        gen_op('&');
+    }
+}
+
+static void expr_xor(void)
+{
+    expr_and();
+    while (tok == '^') {
+        next();
+        expr_and();
+        gen_op('^');
+    }
+}
+
+static void expr_or(void)
+{
+    expr_xor();
+    while (tok == '|') {
+        next();
+        expr_xor();
+        gen_op('|');
+    }
+}
+
+/* XXX: fix this mess */
+static void expr_land_const(void)
+{
+    expr_or();
+    while (tok == TOK_LAND) {
+        next();
+        expr_or();
+        gen_op(TOK_LAND);
+    }
+}
+
+/* XXX: fix this mess */
+static void expr_lor_const(void)
+{
+    expr_land_const();
+    while (tok == TOK_LOR) {
+        next();
+        expr_land_const();
+        gen_op(TOK_LOR);
+    }
+}
+
+/* only used if non constant */
+static void expr_land(void)
+{
+    int t;
+
+    expr_or();
+    if (tok == TOK_LAND) {
+        t = 0;
+        save_regs(1);
+        for(;;) {
+            t = gtst(1, t);
+            if (tok != TOK_LAND) {
+                vseti(VT_JMPI, t);
+                break;
+            }
+            next();
+            expr_or();
+        }
+    }
+}
+
+static void expr_lor(void)
+{
+    int t;
+
+    expr_land();
+    if (tok == TOK_LOR) {
+        t = 0;
+        save_regs(1);
+        for(;;) {
+            t = gtst(0, t);
+            if (tok != TOK_LOR) {
+                vseti(VT_JMP, t);
+                break;
+            }
+            next();
+            expr_land();
+        }
+    }
+}
+
+/* XXX: better constant handling */
+static void expr_eq(void)
+{
+    int tt, u, r1, r2, rc, t1, t2, bt1, bt2;
+    SValue sv;
+    CType type, type1, type2;
+
+    if (const_wanted) {
+        expr_lor_const();
+        if (tok == '?') {
+            CType boolean;
+            int c;
+            boolean.t = VT_BOOL;
+            vdup();
+            gen_cast(&boolean);
+            c = vtop->c.i;
+            vpop();
+            next();
+            if (tok != ':' || !gnu_ext) {
+                vpop();
+                gexpr();
+            }
+            if (!c)
+                vpop();
+            skip(':');
+            expr_eq();
+            if (c)
+                vpop();
+        }
+    } else {
+        expr_lor();
+        if (tok == '?') {
+            next();
+            if (vtop != vstack) {
+                /* needed to avoid having different registers saved in
+                   each branch */
+                if (is_float(vtop->type.t)) {
+                    rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+                        rc = RC_ST0;
+                    }
+#endif
+                }
+                else
+                    rc = RC_INT;
+                    gv(rc);
+                    save_regs(1);
+            }
+            if (tok == ':' && gnu_ext) {
+                gv_dup();
+                tt = gtst(1, 0);
+            } else {
+                tt = gtst(1, 0);
+                gexpr();
+            }
+            type1 = vtop->type;
+            sv = *vtop; /* save value to handle it later */
+            vtop--; /* no vpop so that FP stack is not flushed */
+            skip(':');
+            u = gjmp(0);
+            gsym(tt);
+            expr_eq();
+            type2 = vtop->type;
+
+            t1 = type1.t;
+            bt1 = t1 & VT_BTYPE;
+            t2 = type2.t;
+            bt2 = t2 & VT_BTYPE;
+            /* cast operands to correct type according to ISOC rules */
+            if (is_float(bt1) || is_float(bt2)) {
+                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+                    type.t = VT_LDOUBLE;
+                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+                    type.t = VT_DOUBLE;
+                } else {
+                    type.t = VT_FLOAT;
+                }
+            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+                /* cast to biggest op */
+                type.t = VT_LLONG;
+                /* convert to unsigned if it does not fit in a long long */
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
+                    type.t |= VT_UNSIGNED;
+            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
+                /* XXX: test pointer compatibility */
+                type = type1;
+            } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+                /* XXX: test function pointer compatibility */
+                type = type1;
+            } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+                /* XXX: test structure compatibility */
+                type = type1;
+            } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
+                /* NOTE: as an extension, we accept void on only one side */
+                type.t = VT_VOID;
+            } else {
+                /* integer operations */
+                type.t = VT_INT;
+                /* convert to unsigned if it does not fit in an integer */
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
+                    type.t |= VT_UNSIGNED;
+            }
+                
+            /* now we convert second operand */
+            gen_cast(&type);
+            if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                gaddrof();
+            rc = RC_INT;
+            if (is_float(type.t)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                }
+#endif
+            } else if ((type.t & VT_BTYPE) == VT_LLONG) {
+                /* for long longs, we use fixed registers to avoid having
+                   to handle a complicated move */
+                rc = RC_IRET; 
+            }
+            
+            r2 = gv(rc);
+            /* this is horrible, but we must also convert first
+               operand */
+            tt = gjmp(0);
+            gsym(u);
+            /* put again first value and cast it */
+            *vtop = sv;
+            gen_cast(&type);
+            if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                gaddrof();
+            r1 = gv(rc);
+            move_reg(r2, r1);
+            vtop->r = r2;
+            gsym(tt);
+        }
+    }
+}
+
+static void gexpr(void)
+{
+    while (1) {
+        expr_eq();
+        if (tok != ',')
+            break;
+        vpop();
+        next();
+    }
+}
+
+/* parse an expression and return its type without any side effect. */
+static void expr_type(CType *type)
+{
+    int saved_nocode_wanted;
+
+    saved_nocode_wanted = nocode_wanted;
+    nocode_wanted = 1;
+    gexpr();
+    *type = vtop->type;
+    vpop();
+    nocode_wanted = saved_nocode_wanted;
+}
+
+/* parse a unary expression and return its type without any side
+   effect. */
+static void unary_type(CType *type)
+{
+    int a;
+
+    a = nocode_wanted;
+    nocode_wanted = 1;
+    unary();
+    *type = vtop->type;
+    vpop();
+    nocode_wanted = a;
+}
+
+/* parse a constant expression and return value in vtop.  */
+static void expr_const1(void)
+{
+    int a;
+    a = const_wanted;
+    const_wanted = 1;
+    expr_eq();
+    const_wanted = a;
+}
+
+/* parse an integer constant and return its value. */
+static int expr_const(void)
+{
+    int c;
+    expr_const1();
+    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        expect("constant expression");
+    c = vtop->c.i;
+    vpop();
+    return c;
+}
+
+/* return the label token if current token is a label, otherwise
+   return zero */
+static int is_label(void)
+{
+    int last_tok;
+
+    /* fast test first */
+    if (tok < TOK_UIDENT)
+        return 0;
+    /* no need to save tokc because tok is an identifier */
+    last_tok = tok;
+    next();
+    if (tok == ':') {
+        next();
+        return last_tok;
+    } else {
+        unget_tok(last_tok);
+        return 0;
+    }
+}
+
+static void block(int *bsym, int *csym, int *case_sym, int *def_sym, 
+                  int case_reg, int is_expr)
+{
+    int a, b, c, d;
+    Sym *s;
+
+    /* generate line number info */
+    if (tcc_state->do_debug &&
+        (last_line_num != file->line_num || last_ind != ind)) {
+        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
+        last_ind = ind;
+        last_line_num = file->line_num;
+    }
+
+    if (is_expr) {
+        /* default return value is (void) */
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+    }
+
+    if (tok == TOK_IF) {
+        /* if test */
+        next();
+        skip('(');
+        gexpr();
+        skip(')');
+        a = gtst(1, 0);
+        block(bsym, csym, case_sym, def_sym, case_reg, 0);
+        c = tok;
+        if (c == TOK_ELSE) {
+            next();
+            d = gjmp(0);
+            gsym(a);
+            block(bsym, csym, case_sym, def_sym, case_reg, 0);
+            gsym(d); /* patch else jmp */
+        } else
+            gsym(a);
+    } else if (tok == TOK_WHILE) {
+        next();
+        d = ind;
+        skip('(');
+        gexpr();
+        skip(')');
+        a = gtst(1, 0);
+        b = 0;
+        block(&a, &b, case_sym, def_sym, case_reg, 0);
+        gjmp_addr(d);
+        gsym(a);
+        gsym_addr(b, d);
+    } else if (tok == '{') {
+        Sym *llabel;
+        
+        next();
+        /* record local declaration stack position */
+        s = local_stack;
+        llabel = local_label_stack;
+        /* handle local labels declarations */
+        if (tok == TOK_LABEL) {
+            next();
+            for(;;) {
+                if (tok < TOK_UIDENT)
+                    expect("label identifier");
+                label_push(&local_label_stack, tok, LABEL_DECLARED);
+                next();
+                if (tok == ',') {
+                    next();
+                } else {
+                    skip(';');
+                    break;
+                }
+            }
+        }
+        while (tok != '}') {
+            decl(VT_LOCAL);
+            if (tok != '}') {
+                if (is_expr)
+                    vpop();
+                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
+            }
+        }
+        /* pop locally defined labels */
+        label_pop(&local_label_stack, llabel);
+        /* pop locally defined symbols */
+        if(is_expr) {
+            /* XXX: this solution makes only valgrind happy...
+               triggered by gcc.c-torture/execute/20000917-1.c */
+            Sym *p;
+            switch(vtop->type.t & VT_BTYPE) {
+            case VT_PTR:
+            case VT_STRUCT:
+            case VT_ENUM:
+            case VT_FUNC:
+                for(p=vtop->type.ref;p;p=p->prev)
+                    if(p->prev==s)
+                        error("unsupported expression type");
+            }
+        }
+        sym_pop(&local_stack, s);
+        next();
+    } else if (tok == TOK_RETURN) {
+        next();
+        if (tok != ';') {
+            gexpr();
+            gen_assign_cast(&func_vt);
+            if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+                CType type;
+                /* if returning structure, must copy it to implicit
+                   first pointer arg location */
+#ifdef TCC_ARM_EABI
+                int align, size;
+                size = type_size(&func_vt,&align);
+                if(size <= 4)
+                {
+                    if((vtop->r != (VT_LOCAL | VT_LVAL) || (vtop->c.i & 3))
+                       && (align & 3))
+                    {
+                        int addr;
+                        loc = (loc - size) & -4;
+                        addr = loc;
+                        type = func_vt;
+                        vset(&type, VT_LOCAL | VT_LVAL, addr);
+                        vswap();
+                        vstore();
+                        vset(&int_type, VT_LOCAL | VT_LVAL, addr);
+                    }
+                    vtop->type = int_type;
+                    gv(RC_IRET);
+                } else {
+#endif
+                type = func_vt;
+                mk_pointer(&type);
+                vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+                indir();
+                vswap();
+                /* copy structure value to pointer */
+                vstore();
+#ifdef TCC_ARM_EABI
+                }
+#endif
+            } else if (is_float(func_vt.t)) {
+                gv(rc_fret(func_vt.t));
+            } else {
+                gv(RC_IRET);
+            }
+            vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+        }
+        skip(';');
+        rsym = gjmp(rsym); /* jmp */
+    } else if (tok == TOK_BREAK) {
+        /* compute jump */
+        if (!bsym)
+            error("cannot break");
+        *bsym = gjmp(*bsym);
+        next();
+        skip(';');
+    } else if (tok == TOK_CONTINUE) {
+        /* compute jump */
+        if (!csym)
+            error("cannot continue");
+        *csym = gjmp(*csym);
+        next();
+        skip(';');
+    } else if (tok == TOK_FOR) {
+        int e;
+        next();
+        skip('(');
+        if (tok != ';') {
+            gexpr();
+            vpop();
+        }
+        skip(';');
+        d = ind;
+        c = ind;
+        a = 0;
+        b = 0;
+        if (tok != ';') {
+            gexpr();
+            a = gtst(1, 0);
+        }
+        skip(';');
+        if (tok != ')') {
+            e = gjmp(0);
+            c = ind;
+            gexpr();
+            vpop();
+            gjmp_addr(d);
+            gsym(e);
+        }
+        skip(')');
+        block(&a, &b, case_sym, def_sym, case_reg, 0);
+        gjmp_addr(c);
+        gsym(a);
+        gsym_addr(b, c);
+    } else 
+    if (tok == TOK_DO) {
+        next();
+        a = 0;
+        b = 0;
+        d = ind;
+        block(&a, &b, case_sym, def_sym, case_reg, 0);
+        skip(TOK_WHILE);
+        skip('(');
+        gsym(b);
+        gexpr();
+        c = gtst(0, 0);
+        gsym_addr(c, d);
+        skip(')');
+        gsym(a);
+        skip(';');
+    } else
+    if (tok == TOK_SWITCH) {
+        next();
+        skip('(');
+        gexpr();
+        /* XXX: other types than integer */
+        case_reg = gv(RC_INT);
+        vpop();
+        skip(')');
+        a = 0;
+        b = gjmp(0); /* jump to first case */
+        c = 0;
+        block(&a, csym, &b, &c, case_reg, 0);
+        /* if no default, jmp after switch */
+        if (c == 0)
+            c = ind;
+        /* default label */
+        gsym_addr(b, c);
+        /* break label */
+        gsym(a);
+    } else
+    if (tok == TOK_CASE) {
+        int v1, v2;
+        if (!case_sym)
+            expect("switch");
+        next();
+        v1 = expr_const();
+        v2 = v1;
+        if (gnu_ext && tok == TOK_DOTS) {
+            next();
+            v2 = expr_const();
+            if (v2 < v1)
+                warning("empty case range");
+        }
+        /* since a case is like a label, we must skip it with a jmp */
+        b = gjmp(0);
+        gsym(*case_sym);
+        vseti(case_reg, 0);
+        vpushi(v1);
+        if (v1 == v2) {
+            gen_op(TOK_EQ);
+            *case_sym = gtst(1, 0);
+        } else {
+            gen_op(TOK_GE);
+            *case_sym = gtst(1, 0);
+            vseti(case_reg, 0);
+            vpushi(v2);
+            gen_op(TOK_LE);
+            *case_sym = gtst(1, *case_sym);
+        }
+        gsym(b);
+        skip(':');
+        is_expr = 0;
+        goto block_after_label;
+    } else 
+    if (tok == TOK_DEFAULT) {
+        next();
+        skip(':');
+        if (!def_sym)
+            expect("switch");
+        if (*def_sym)
+            error("too many 'default'");
+        *def_sym = ind;
+        is_expr = 0;
+        goto block_after_label;
+    } else
+    if (tok == TOK_GOTO) {
+        next();
+        if (tok == '*' && gnu_ext) {
+            /* computed goto */
+            next();
+            gexpr();
+            if ((vtop->type.t & VT_BTYPE) != VT_PTR)
+                expect("pointer");
+            ggoto();
+        } else if (tok >= TOK_UIDENT) {
+            s = label_find(tok);
+            /* put forward definition if needed */
+            if (!s) {
+                s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+            } else {
+                if (s->r == LABEL_DECLARED)
+                    s->r = LABEL_FORWARD;
+            }
+            /* label already defined */
+            if (s->r & LABEL_FORWARD) 
+                s->next = (void *)gjmp((long)s->next);
+            else
+                gjmp_addr((long)s->next);
+            next();
+        } else {
+            expect("label identifier");
+        }
+        skip(';');
+    } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
+        asm_instr();
+    } else {
+        b = is_label();
+        if (b) {
+            /* label case */
+            s = label_find(b);
+            if (s) {
+                if (s->r == LABEL_DEFINED)
+                    error("duplicate label '%s'", get_tok_str(s->v, NULL));
+                gsym((long)s->next);
+                s->r = LABEL_DEFINED;
+            } else {
+                s = label_push(&global_label_stack, b, LABEL_DEFINED);
+            }
+            s->next = (void *)ind;
+            /* we accept this, but it is a mistake */
+        block_after_label:
+            if (tok == '}') {
+                warning("deprecated use of label at end of compound statement");
+            } else {
+                if (is_expr)
+                    vpop();
+                block(bsym, csym, case_sym, def_sym, case_reg, is_expr);
+            }
+        } else {
+            /* expression case */
+            if (tok != ';') {
+                if (is_expr) {
+                    vpop();
+                    gexpr();
+                } else {
+                    gexpr();
+                    vpop();
+                }
+            }
+            skip(';');
+        }
+    }
+}
+
+/* t is the array or struct type. c is the array or struct
+   address. cur_index/cur_field is the pointer to the current
+   value. 'size_only' is true if only size info is needed (only used
+   in arrays) */
+static void decl_designator(CType *type, Section *sec, unsigned long c, 
+                            int *cur_index, Sym **cur_field, 
+                            int size_only)
+{
+    Sym *s, *f;
+    int notfirst, index, index_last, align, l, nb_elems, elem_size;
+    CType type1;
+
+    notfirst = 0;
+    elem_size = 0;
+    nb_elems = 1;
+    if (gnu_ext && (l = is_label()) != 0)
+        goto struct_field;
+    while (tok == '[' || tok == '.') {
+        if (tok == '[') {
+            if (!(type->t & VT_ARRAY))
+                expect("array type");
+            s = type->ref;
+            next();
+            index = expr_const();
+            if (index < 0 || (s->c >= 0 && index >= s->c))
+                expect("invalid index");
+            if (tok == TOK_DOTS && gnu_ext) {
+                next();
+                index_last = expr_const();
+                if (index_last < 0 || 
+                    (s->c >= 0 && index_last >= s->c) ||
+                    index_last < index)
+                    expect("invalid index");
+            } else {
+                index_last = index;
+            }
+            skip(']');
+            if (!notfirst)
+                *cur_index = index_last;
+            type = pointed_type(type);
+            elem_size = type_size(type, &align);
+            c += index * elem_size;
+            /* NOTE: we only support ranges for last designator */
+            nb_elems = index_last - index + 1;
+            if (nb_elems != 1) {
+                notfirst = 1;
+                break;
+            }
+        } else {
+            next();
+            l = tok;
+            next();
+        struct_field:
+            if ((type->t & VT_BTYPE) != VT_STRUCT)
+                expect("struct/union type");
+            s = type->ref;
+            l |= SYM_FIELD;
+            f = s->next;
+            while (f) {
+                if (f->v == l)
+                    break;
+                f = f->next;
+            }
+            if (!f)
+                expect("field");
+            if (!notfirst)
+                *cur_field = f;
+            /* XXX: fix this mess by using explicit storage field */
+            type1 = f->type;
+            type1.t |= (type->t & ~VT_TYPE);
+            type = &type1;
+            c += f->c;
+        }
+        notfirst = 1;
+    }
+    if (notfirst) {
+        if (tok == '=') {
+            next();
+        } else {
+            if (!gnu_ext)
+                expect("=");
+        }
+    } else {
+        if (type->t & VT_ARRAY) {
+            index = *cur_index;
+            type = pointed_type(type);
+            c += index * type_size(type, &align);
+        } else {
+            f = *cur_field;
+            if (!f)
+                error("too many field init");
+            /* XXX: fix this mess by using explicit storage field */
+            type1 = f->type;
+            type1.t |= (type->t & ~VT_TYPE);
+            type = &type1;
+            c += f->c;
+        }
+    }
+    decl_initializer(type, sec, c, 0, size_only);
+
+    /* XXX: make it more general */
+    if (!size_only && nb_elems > 1) {
+        unsigned long c_end;
+        uint8_t *src, *dst;
+        int i;
+
+        if (!sec)
+            error("range init not supported yet for dynamic storage");
+        c_end = c + nb_elems * elem_size;
+        if (c_end > sec->data_allocated)
+            section_realloc(sec, c_end);
+        src = sec->data + c;
+        dst = src;
+        for(i = 1; i < nb_elems; i++) {
+            dst += elem_size;
+            memcpy(dst, src, elem_size);
+        }
+    }
+}
+
+#define EXPR_VAL   0
+#define EXPR_CONST 1
+#define EXPR_ANY   2
+
+/* store a value or an expression directly in global data or in local array */
+static void init_putv(CType *type, Section *sec, unsigned long c, 
+                      int v, int expr_type)
+{
+    int saved_global_expr, bt, bit_pos, bit_size;
+    void *ptr;
+    unsigned long long bit_mask;
+    CType dtype;
+
+    switch(expr_type) {
+    case EXPR_VAL:
+        vpushi(v);
+        break;
+    case EXPR_CONST:
+        /* compound literals must be allocated globally in this case */
+        saved_global_expr = global_expr;
+        global_expr = 1;
+        expr_const1();
+        global_expr = saved_global_expr;
+        /* NOTE: symbols are accepted */
+        if ((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST)
+            error("initializer element is not constant");
+        break;
+    case EXPR_ANY:
+        expr_eq();
+        break;
+    }
+    
+    dtype = *type;
+    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+
+    if (sec) {
+        /* XXX: not portable */
+        /* XXX: generate error if incorrect relocation */
+        gen_assign_cast(&dtype);
+        bt = type->t & VT_BTYPE;
+        /* we'll write at most 12 bytes */
+        if (c + 12 > sec->data_allocated) {
+            section_realloc(sec, c + 12);
+        }
+        ptr = sec->data + c;
+        /* XXX: make code faster ? */
+        if (!(type->t & VT_BITFIELD)) {
+            bit_pos = 0;
+            bit_size = 32;
+            bit_mask = -1LL;
+        } else {
+            bit_pos = (vtop->type.t >> VT_STRUCT_SHIFT) & 0x3f;
+            bit_size = (vtop->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f;
+            bit_mask = (1LL << bit_size) - 1;
+        }
+        if ((vtop->r & VT_SYM) &&
+            (bt == VT_BYTE ||
+             bt == VT_SHORT ||
+             bt == VT_DOUBLE ||
+             bt == VT_LDOUBLE ||
+             bt == VT_LLONG ||
+             (bt == VT_INT && bit_size != 32)))
+            error("initializer element is not computable at load time");
+        switch(bt) {
+        case VT_BOOL:
+            vtop->c.i = (vtop->c.i != 0);
+        case VT_BYTE:
+            *(char *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
+            break;
+        case VT_SHORT:
+            *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
+            break;
+        case VT_DOUBLE:
+            *(double *)ptr = vtop->c.d;
+            break;
+        case VT_LDOUBLE:
+            *(long double *)ptr = vtop->c.ld;
+            break;
+        case VT_LLONG:
+            *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
+            break;
+        default:
+            if (vtop->r & VT_SYM) {
+                greloc(sec, vtop->sym, c, R_DATA_32);
+            }
+            *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
+            break;
+        }
+        vtop--;
+    } else {
+        vset(&dtype, VT_LOCAL|VT_LVAL, c);
+        vswap();
+        vstore();
+        vpop();
+    }
+}
+
+/* put zeros for variable based init */
+static void init_putz(CType *t, Section *sec, unsigned long c, int size)
+{
+    if (sec) {
+        /* nothing to do because globals are already set to zero */
+    } else {
+        vpush_global_sym(&func_old_type, TOK_memset);
+        vseti(VT_LOCAL, c);
+        vpushi(0);
+        vpushi(size);
+        gfunc_call(3);
+    }
+}
+
+/* 't' contains the type and storage info. 'c' is the offset of the
+   object in section 'sec'. If 'sec' is NULL, it means stack based
+   allocation. 'first' is true if array '{' must be read (multi
+   dimension implicit array init handling). 'size_only' is true if
+   size only evaluation is wanted (only for arrays). */
+static void decl_initializer(CType *type, Section *sec, unsigned long c, 
+                             int first, int size_only)
+{
+    int index, array_length, n, no_oblock, nb, parlevel, i;
+    int size1, align1, expr_type;
+    Sym *s, *f;
+    CType *t1;
+
+    if (type->t & VT_ARRAY) {
+        s = type->ref;
+        n = s->c;
+        array_length = 0;
+        t1 = pointed_type(type);
+        size1 = type_size(t1, &align1);
+
+        no_oblock = 1;
+        if ((first && tok != TOK_LSTR && tok != TOK_STR) || 
+            tok == '{') {
+            skip('{');
+            no_oblock = 0;
+        }
+
+        /* only parse strings here if correct type (otherwise: handle
+           them as ((w)char *) expressions */
+        if ((tok == TOK_LSTR && 
+#ifdef TCC_TARGET_PE
+             (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
+#else
+             (t1->t & VT_BTYPE) == VT_INT
+#endif
+            ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
+            while (tok == TOK_STR || tok == TOK_LSTR) {
+                int cstr_len, ch;
+                CString *cstr;
+
+                cstr = tokc.cstr;
+                /* compute maximum number of chars wanted */
+                if (tok == TOK_STR)
+                    cstr_len = cstr->size;
+                else
+                    cstr_len = cstr->size / sizeof(nwchar_t);
+                cstr_len--;
+                nb = cstr_len;
+                if (n >= 0 && nb > (n - array_length))
+                    nb = n - array_length;
+                if (!size_only) {
+                    if (cstr_len > nb)
+                        warning("initializer-string for array is too long");
+                    /* in order to go faster for common case (char
+                       string in global variable, we handle it
+                       specifically */
+                    if (sec && tok == TOK_STR && size1 == 1) {
+                        memcpy(sec->data + c + array_length, cstr->data, nb);
+                    } else {
+                        for(i=0;i<nb;i++) {
+                            if (tok == TOK_STR)
+                                ch = ((unsigned char *)cstr->data)[i];
+                            else
+                                ch = ((nwchar_t *)cstr->data)[i];
+                            init_putv(t1, sec, c + (array_length + i) * size1,
+                                      ch, EXPR_VAL);
+                        }
+                    }
+                }
+                array_length += nb;
+                next();
+            }
+            /* only add trailing zero if enough storage (no
+               warning in this case since it is standard) */
+            if (n < 0 || array_length < n) {
+                if (!size_only) {
+                    init_putv(t1, sec, c + (array_length * size1), 0, EXPR_VAL);
+                }
+                array_length++;
+            }
+        } else {
+            index = 0;
+            while (tok != '}') {
+                decl_designator(type, sec, c, &index, NULL, size_only);
+                if (n >= 0 && index >= n)
+                    error("index too large");
+                /* must put zero in holes (note that doing it that way
+                   ensures that it even works with designators) */
+                if (!size_only && array_length < index) {
+                    init_putz(t1, sec, c + array_length * size1, 
+                              (index - array_length) * size1);
+                }
+                index++;
+                if (index > array_length)
+                    array_length = index;
+                /* special test for multi dimensional arrays (may not
+                   be strictly correct if designators are used at the
+                   same time) */
+                if (index >= n && no_oblock)
+                    break;
+                if (tok == '}')
+                    break;
+                skip(',');
+            }
+        }
+        if (!no_oblock)
+            skip('}');
+        /* put zeros at the end */
+        if (!size_only && n >= 0 && array_length < n) {
+            init_putz(t1, sec, c + array_length * size1, 
+                      (n - array_length) * size1);
+        }
+        /* patch type size if needed */
+        if (n < 0)
+            s->c = array_length;
+    } else if ((type->t & VT_BTYPE) == VT_STRUCT &&
+               (sec || !first || tok == '{')) {
+        int par_count;
+
+        /* NOTE: the previous test is a specific case for automatic
+           struct/union init */
+        /* XXX: union needs only one init */
+
+        /* XXX: this test is incorrect for local initializers
+           beginning with ( without {. It would be much more difficult
+           to do it correctly (ideally, the expression parser should
+           be used in all cases) */
+        par_count = 0;
+        if (tok == '(') {
+            AttributeDef ad1;
+            CType type1;
+            next();
+            while (tok == '(') {
+                par_count++;
+                next();
+            }
+            if (!parse_btype(&type1, &ad1))
+                expect("cast");
+            type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
+#if 0
+            if (!is_assignable_types(type, &type1))
+                error("invalid type for cast");
+#endif
+            skip(')');
+        }
+        no_oblock = 1;
+        if (first || tok == '{') {
+            skip('{');
+            no_oblock = 0;
+        }
+        s = type->ref;
+        f = s->next;
+        array_length = 0;
+        index = 0;
+        n = s->c;
+        while (tok != '}') {
+            decl_designator(type, sec, c, NULL, &f, size_only);
+            index = f->c;
+            if (!size_only && array_length < index) {
+                init_putz(type, sec, c + array_length, 
+                          index - array_length);
+            }
+            index = index + type_size(&f->type, &align1);
+            if (index > array_length)
+                array_length = index;
+            f = f->next;
+            if (no_oblock && f == NULL)
+                break;
+            if (tok == '}')
+                break;
+            skip(',');
+        }
+        /* put zeros at the end */
+        if (!size_only && array_length < n) {
+            init_putz(type, sec, c + array_length, 
+                      n - array_length);
+        }
+        if (!no_oblock)
+            skip('}');
+        while (par_count) {
+            skip(')');
+            par_count--;
+        }
+    } else if (tok == '{') {
+        next();
+        decl_initializer(type, sec, c, first, size_only);
+        skip('}');
+    } else if (size_only) {
+        /* just skip expression */
+        parlevel = 0;
+        while ((parlevel > 0 || (tok != '}' && tok != ',')) && 
+               tok != -1) {
+            if (tok == '(')
+                parlevel++;
+            else if (tok == ')')
+                parlevel--;
+            next();
+        }
+    } else {
+        /* currently, we always use constant expression for globals
+           (may change for scripting case) */
+        expr_type = EXPR_CONST;
+        if (!sec)
+            expr_type = EXPR_ANY;
+        init_putv(type, sec, c, 0, expr_type);
+    }
+}
+
+/* parse an initializer for type 't' if 'has_init' is non zero, and
+   allocate space in local or global data space ('r' is either
+   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
+   variable 'v' of scope 'scope' is declared before initializers are
+   parsed. If 'v' is zero, then a reference to the new object is put
+   in the value stack. If 'has_init' is 2, a special parsing is done
+   to handle string constants. */
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
+                                   int has_init, int v, int scope)
+{
+    int size, align, addr, data_offset;
+    int level;
+    ParseState saved_parse_state = {0};
+    TokenString init_str;
+    Section *sec;
+
+    size = type_size(type, &align);
+    /* If unknown size, we must evaluate it before
+       evaluating initializers because
+       initializers can generate global data too
+       (e.g. string pointers or ISOC99 compound
+       literals). It also simplifies local
+       initializers handling */
+    tok_str_new(&init_str);
+    if (size < 0) {
+        if (!has_init) 
+            error("unknown type size");
+        /* get all init string */
+        if (has_init == 2) {
+            /* only get strings */
+            while (tok == TOK_STR || tok == TOK_LSTR) {
+                tok_str_add_tok(&init_str);
+                next();
+            }
+        } else {
+            level = 0;
+            while (level > 0 || (tok != ',' && tok != ';')) {
+                if (tok < 0)
+                    error("unexpected end of file in initializer");
+                tok_str_add_tok(&init_str);
+                if (tok == '{')
+                    level++;
+                else if (tok == '}') {
+                    level--;
+                    if (level <= 0) {
+                        next();
+                        break;
+                    }
+                }
+                next();
+            }
+        }
+        tok_str_add(&init_str, -1);
+        tok_str_add(&init_str, 0);
+        
+        /* compute size */
+        save_parse_state(&saved_parse_state);
+
+        macro_ptr = init_str.str;
+        next();
+        decl_initializer(type, NULL, 0, 1, 1);
+        /* prepare second initializer parsing */
+        macro_ptr = init_str.str;
+        next();
+        
+        /* if still unknown size, error */
+        size = type_size(type, &align);
+        if (size < 0) 
+            error("unknown type size");
+    }
+    /* take into account specified alignment if bigger */
+    if (ad->aligned) {
+        if (ad->aligned > align)
+            align = ad->aligned;
+    } else if (ad->packed) {
+        align = 1;
+    }
+    if ((r & VT_VALMASK) == VT_LOCAL) {
+        sec = NULL;
+        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY))
+            loc--;
+        loc = (loc - size) & -align;
+        addr = loc;
+        /* handles bounds */
+        /* XXX: currently, since we do only one pass, we cannot track
+           '&' operators, so we add only arrays */
+        if (tcc_state->do_bounds_check && (type->t & VT_ARRAY)) {
+            unsigned long *bounds_ptr;
+            /* add padding between regions */
+            loc--;
+            /* then add local bound info */
+            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(unsigned long));
+            bounds_ptr[0] = addr;
+            bounds_ptr[1] = size;
+        }
+        if (v) {
+            /* local variable */
+            sym_push(v, type, r, addr);
+        } else {
+            /* push local reference */
+            vset(type, r, addr);
+        }
+    } else {
+        Sym *sym;
+
+        sym = NULL;
+        if (v && scope == VT_CONST) {
+            /* see if the symbol was already defined */
+            sym = sym_find(v);
+            if (sym) {
+                if (!is_compatible_types(&sym->type, type))
+                    error("incompatible types for redefinition of '%s'", 
+                          get_tok_str(v, NULL));
+                if (sym->type.t & VT_EXTERN) {
+                    /* if the variable is extern, it was not allocated */
+                    sym->type.t &= ~VT_EXTERN;
+                    /* set array size if it was ommited in extern
+                       declaration */
+                    if ((sym->type.t & VT_ARRAY) && 
+                        sym->type.ref->c < 0 &&
+                        type->ref->c >= 0)
+                        sym->type.ref->c = type->ref->c;
+                } else {
+                    /* we accept several definitions of the same
+                       global variable. this is tricky, because we
+                       must play with the SHN_COMMON type of the symbol */
+                    /* XXX: should check if the variable was already
+                       initialized. It is incorrect to initialized it
+                       twice */
+                    /* no init data, we won't add more to the symbol */
+                    if (!has_init)
+                        goto no_alloc;
+                }
+            }
+        }
+
+        /* allocate symbol in corresponding section */
+        sec = ad->section;
+        if (!sec) {
+            if (has_init)
+                sec = data_section;
+            else if (tcc_state->nocommon)
+                sec = bss_section;
+        }
+        if (sec) {
+            data_offset = sec->data_offset;
+            data_offset = (data_offset + align - 1) & -align;
+            addr = data_offset;
+            /* very important to increment global pointer at this time
+               because initializers themselves can create new initializers */
+            data_offset += size;
+            /* add padding if bound check */
+            if (tcc_state->do_bounds_check)
+                data_offset++;
+            sec->data_offset = data_offset;
+            /* allocate section space to put the data */
+            if (sec->sh_type != SHT_NOBITS && 
+                data_offset > sec->data_allocated)
+                section_realloc(sec, data_offset);
+            /* align section if needed */
+            if (align > sec->sh_addralign)
+                sec->sh_addralign = align;
+        } else {
+            addr = 0; /* avoid warning */
+        }
+
+        if (v) {
+            if (scope != VT_CONST || !sym) {
+                sym = sym_push(v, type, r | VT_SYM, 0);
+            }
+            /* update symbol definition */
+            if (sec) {
+                put_extern_sym(sym, sec, addr, size);
+            } else {
+                ElfW(Sym) *esym;
+                /* put a common area */
+                put_extern_sym(sym, NULL, align, size);
+                /* XXX: find a nicer way */
+                esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
+                esym->st_shndx = SHN_COMMON;
+            }
+        } else {
+            CValue cval;
+
+            /* push global reference */
+            sym = get_sym_ref(type, sec, addr, size);
+            cval.ul = 0;
+            vsetc(type, VT_CONST | VT_SYM, &cval);
+            vtop->sym = sym;
+        }
+
+        /* handles bounds now because the symbol must be defined
+           before for the relocation */
+        if (tcc_state->do_bounds_check) {
+            unsigned long *bounds_ptr;
+
+            greloc(bounds_section, sym, bounds_section->data_offset, R_DATA_32);
+            /* then add global bound info */
+            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(long));
+            bounds_ptr[0] = 0; /* relocated */
+            bounds_ptr[1] = size;
+        }
+    }
+    if (has_init) {
+        decl_initializer(type, sec, addr, 1, 0);
+        /* restore parse state if needed */
+        if (init_str.str) {
+            tok_str_free(init_str.str);
+            restore_parse_state(&saved_parse_state);
+        }
+    }
+ no_alloc: ;
+}
+
+void put_func_debug(Sym *sym)
+{
+    char buf[512];
+
+    /* stabs info */
+    /* XXX: we put here a dummy type */
+    snprintf(buf, sizeof(buf), "%s:%c1", 
+             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
+    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
+                cur_text_section, sym->c);
+    /* //gr gdb wants a line at the function */
+    put_stabn(N_SLINE, 0, file->line_num, 0); 
+    last_ind = 0;
+    last_line_num = 0;
+}
+
+/* parse an old style function declaration list */
+/* XXX: check multiple parameter */
+static void func_decl_list(Sym *func_sym)
+{
+    AttributeDef ad;
+    int v;
+    Sym *s;
+    CType btype, type;
+
+    /* parse each declaration */
+    while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) {
+        if (!parse_btype(&btype, &ad)) 
+            expect("declaration list");
+        if (((btype.t & VT_BTYPE) == VT_ENUM ||
+             (btype.t & VT_BTYPE) == VT_STRUCT) && 
+            tok == ';') {
+            /* we accept no variable after */
+        } else {
+            for(;;) {
+                type = btype;
+                type_decl(&type, &ad, &v, TYPE_DIRECT);
+                /* find parameter in function parameter list */
+                s = func_sym->next;
+                while (s != NULL) {
+                    if ((s->v & ~SYM_FIELD) == v)
+                        goto found;
+                    s = s->next;
+                }
+                error("declaration for parameter '%s' but no such parameter",
+                      get_tok_str(v, NULL));
+            found:
+                /* check that no storage specifier except 'register' was given */
+                if (type.t & VT_STORAGE)
+                    error("storage class specified for '%s'", get_tok_str(v, NULL)); 
+                convert_parameter_type(&type);
+                /* we can add the type (NOTE: it could be local to the function) */
+                s->type = type;
+                /* accept other parameters */
+                if (tok == ',')
+                    next();
+                else
+                    break;
+            }
+        }
+        skip(';');
+    }
+}
+
+/* parse a function defined by symbol 'sym' and generate its code in
+   'cur_text_section' */
+static void gen_function(Sym *sym)
+{
+    int saved_nocode_wanted = nocode_wanted;
+    nocode_wanted = 0;
+    ind = cur_text_section->data_offset;
+    /* NOTE: we patch the symbol size later */
+    put_extern_sym(sym, cur_text_section, ind, 0);
+    funcname = get_tok_str(sym->v, NULL);
+    func_ind = ind;
+    /* put debug symbol */
+    if (tcc_state->do_debug)
+        put_func_debug(sym);
+    /* push a dummy symbol to enable local sym storage */
+    sym_push2(&local_stack, SYM_FIELD, 0, 0);
+    gfunc_prolog(&sym->type);
+    rsym = 0;
+    block(NULL, NULL, NULL, NULL, 0, 0);
+    gsym(rsym);
+    gfunc_epilog();
+    cur_text_section->data_offset = ind;
+    label_pop(&global_label_stack, NULL);
+    sym_pop(&local_stack, NULL); /* reset local stack */
+    /* end of function */
+    /* patch symbol size */
+    ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = 
+        ind - func_ind;
+    if (tcc_state->do_debug) {
+        put_stabn(N_FUN, 0, 0, ind - func_ind);
+    }
+    /* It's better to crash than to generate wrong code */
+    cur_text_section = NULL;
+    funcname = ""; /* for safety */
+    func_vt.t = VT_VOID; /* for safety */
+    ind = 0; /* for safety */
+    nocode_wanted = saved_nocode_wanted;
+}
+
+static void gen_inline_functions(void)
+{
+    Sym *sym;
+    CType *type;
+    int *str, inline_generated;
+
+    /* iterate while inline function are referenced */
+    for(;;) {
+        inline_generated = 0;
+        for(sym = global_stack; sym != NULL; sym = sym->prev) {
+            type = &sym->type;
+            if (((type->t & VT_BTYPE) == VT_FUNC) &&
+                (type->t & (VT_STATIC | VT_INLINE)) == 
+                (VT_STATIC | VT_INLINE) &&
+                sym->c != 0) {
+                /* the function was used: generate its code and
+                   convert it to a normal function */
+                str = INLINE_DEF(sym->r);
+                sym->r = VT_SYM | VT_CONST;
+                sym->type.t &= ~VT_INLINE;
+
+                macro_ptr = str;
+                next();
+                cur_text_section = text_section;
+                gen_function(sym);
+                macro_ptr = NULL; /* fail safe */
+
+                tok_str_free(str);
+                inline_generated = 1;
+            }
+        }
+        if (!inline_generated)
+            break;
+    }
+
+    /* free all remaining inline function tokens */
+    for(sym = global_stack; sym != NULL; sym = sym->prev) {
+        type = &sym->type;
+        if (((type->t & VT_BTYPE) == VT_FUNC) &&
+            (type->t & (VT_STATIC | VT_INLINE)) == 
+            (VT_STATIC | VT_INLINE)) {
+            //gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL));
+            if (sym->r == (VT_SYM | VT_CONST)) //gr beware!
+                continue;
+            str = INLINE_DEF(sym->r);
+            tok_str_free(str);
+            sym->r = 0; /* fail safe */
+        }
+    }
+}
+
+/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
+static void decl(int l)
+{
+    int v, has_init, r;
+    CType type, btype;
+    Sym *sym;
+    AttributeDef ad;
+    
+    while (1) {
+        if (!parse_btype(&btype, &ad)) {
+            /* skip redundant ';' */
+            /* XXX: find more elegant solution */
+            if (tok == ';') {
+                next();
+                continue;
+            }
+            if (l == VT_CONST &&
+                (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+                /* global asm block */
+                asm_global_instr();
+                continue;
+            }
+            /* special test for old K&R protos without explicit int
+               type. Only accepted when defining global data */
+            if (l == VT_LOCAL || tok < TOK_DEFINE)
+                break;
+            btype.t = VT_INT;
+        }
+        if (((btype.t & VT_BTYPE) == VT_ENUM ||
+             (btype.t & VT_BTYPE) == VT_STRUCT) && 
+            tok == ';') {
+            /* we accept no variable after */
+            next();
+            continue;
+        }
+        while (1) { /* iterate thru each declaration */
+            type = btype;
+            type_decl(&type, &ad, &v, TYPE_DIRECT);
+#if 0
+            {
+                char buf[500];
+                type_to_str(buf, sizeof(buf), t, get_tok_str(v, NULL));
+                printf("type = '%s'\n", buf);
+            }
+#endif
+            if ((type.t & VT_BTYPE) == VT_FUNC) {
+                /* if old style function prototype, we accept a
+                   declaration list */
+                sym = type.ref;
+                if (sym->c == FUNC_OLD)
+                    func_decl_list(sym);
+            }
+
+            if (tok == '{') {
+                if (l == VT_LOCAL)
+                    error("cannot use local functions");
+                if ((type.t & VT_BTYPE) != VT_FUNC)
+                    expect("function definition");
+
+                /* reject abstract declarators in function definition */
+                sym = type.ref;
+                while ((sym = sym->next) != NULL)
+                    if (!(sym->v & ~SYM_FIELD))
+                       expect("identifier");
+                
+                /* XXX: cannot do better now: convert extern line to static inline */
+                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
+                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
+                
+                sym = sym_find(v);
+                if (sym) {
+                    if ((sym->type.t & VT_BTYPE) != VT_FUNC)
+                        goto func_error1;
+                    /* specific case: if not func_call defined, we put
+                       the one of the prototype */
+                    /* XXX: should have default value */
+                    r = sym->type.ref->r;
+                    if (FUNC_CALL(r) != FUNC_CDECL
+                     && FUNC_CALL(type.ref->r) == FUNC_CDECL)
+                        FUNC_CALL(type.ref->r) = FUNC_CALL(r);
+                    if (FUNC_EXPORT(r))
+                        FUNC_EXPORT(type.ref->r) = 1;
+
+                    if (!is_compatible_types(&sym->type, &type)) {
+                    func_error1:
+                        error("incompatible types for redefinition of '%s'", 
+                              get_tok_str(v, NULL));
+                    }
+                    /* if symbol is already defined, then put complete type */
+                    sym->type = type;
+                } else {
+                    /* put function symbol */
+                    sym = global_identifier_push(v, type.t, 0);
+                    sym->type.ref = type.ref;
+                }
+
+                /* static inline functions are just recorded as a kind
+                   of macro. Their code will be emitted at the end of
+                   the compilation unit only if they are used */
+                if ((type.t & (VT_INLINE | VT_STATIC)) == 
+                    (VT_INLINE | VT_STATIC)) {
+                    TokenString func_str;
+                    int block_level;
+                           
+                    tok_str_new(&func_str);
+                    
+                    block_level = 0;
+                    for(;;) {
+                        int t;
+                        if (tok == TOK_EOF)
+                            error("unexpected end of file");
+                        tok_str_add_tok(&func_str);
+                        t = tok;
+                        next();
+                        if (t == '{') {
+                            block_level++;
+                        } else if (t == '}') {
+                            block_level--;
+                            if (block_level == 0)
+                                break;
+                        }
+                    }
+                    tok_str_add(&func_str, -1);
+                    tok_str_add(&func_str, 0);
+                    INLINE_DEF(sym->r) = func_str.str;
+                } else {
+                    /* compute text section */
+                    cur_text_section = ad.section;
+                    if (!cur_text_section)
+                        cur_text_section = text_section;
+                    sym->r = VT_SYM | VT_CONST;
+                    gen_function(sym);
+                }
+                break;
+            } else {
+                if (btype.t & VT_TYPEDEF) {
+                    /* save typedefed type  */
+                    /* XXX: test storage specifiers ? */
+                    sym = sym_push(v, &type, 0, 0);
+                    sym->type.t |= VT_TYPEDEF;
+                } else if ((type.t & VT_BTYPE) == VT_FUNC) {
+                    /* external function definition */
+                    /* specific case for func_call attribute */
+                    if (ad.func_attr)
+                        type.ref->r = ad.func_attr;
+                    external_sym(v, &type, 0);
+                } else {
+                    /* not lvalue if array */
+                    r = 0;
+                    if (!(type.t & VT_ARRAY))
+                        r |= lvalue_type(type.t);
+                    has_init = (tok == '=');
+                    if ((btype.t & VT_EXTERN) || 
+                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
+                         !has_init && l == VT_CONST && type.ref->c < 0)) {
+                        /* external variable */
+                        /* NOTE: as GCC, uninitialized global static
+                           arrays of null size are considered as
+                           extern */
+                        external_sym(v, &type, r);
+                    } else {
+                        type.t |= (btype.t & VT_STATIC); /* Retain "static". */
+                        if (type.t & VT_STATIC)
+                            r |= VT_CONST;
+                        else
+                            r |= l;
+                        if (has_init)
+                            next();
+                        decl_initializer_alloc(&type, &ad, r, 
+                                               has_init, v, l);
+                    }
+                }
+                if (tok != ',') {
+                    skip(';');
+                    break;
+                }
+                next();
+            }
+        }
+    }
+}
+
diff --git a/tinyc/tccpe.c b/tinyc/tccpe.c
new file mode 100755
index 000000000..1e3fdb369
--- /dev/null
+++ b/tinyc/tccpe.c
@@ -0,0 +1,1559 @@
+/*
+ *  TCCPE.C - PE file output for the Tiny C Compiler
+ *
+ *  Copyright (c) 2005-2007 grischka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TCC_TARGET_PE
+
+#define ST_FN static
+#define ST_DATA static
+#define PUB_FN
+
+#ifndef _WIN32
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif
+
+#define PE_MERGE_DATA
+// #define PE_PRINT_SECTIONS
+
+/* ----------------------------------------------------------- */
+#ifndef IMAGE_NT_SIGNATURE
+/* ----------------------------------------------------------- */
+/* definitions below are from winnt.h */
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+#pragma pack(push, 1)
+
+typedef struct _IMAGE_DOS_HEADER {  /* DOS .EXE header */
+    WORD e_magic;         /* Magic number */
+    WORD e_cblp;          /* Bytes on last page of file */
+    WORD e_cp;            /* Pages in file */
+    WORD e_crlc;          /* Relocations */
+    WORD e_cparhdr;       /* Size of header in paragraphs */
+    WORD e_minalloc;      /* Minimum extra paragraphs needed */
+    WORD e_maxalloc;      /* Maximum extra paragraphs needed */
+    WORD e_ss;            /* Initial (relative) SS value */
+    WORD e_sp;            /* Initial SP value */
+    WORD e_csum;          /* Checksum */
+    WORD e_ip;            /* Initial IP value */
+    WORD e_cs;            /* Initial (relative) CS value */
+    WORD e_lfarlc;        /* File address of relocation table */
+    WORD e_ovno;          /* Overlay number */
+    WORD e_res[4];        /* Reserved words */
+    WORD e_oemid;         /* OEM identifier (for e_oeminfo) */
+    WORD e_oeminfo;       /* OEM information; e_oemid specific */
+    WORD e_res2[10];      /* Reserved words */
+    DWORD e_lfanew;        /* File address of new exe header */
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+#define IMAGE_NT_SIGNATURE  0x00004550  /* PE00 */
+#define SIZE_OF_NT_SIGNATURE 4
+
+typedef struct _IMAGE_FILE_HEADER {
+    WORD    Machine;
+    WORD    NumberOfSections;
+    DWORD   TimeDateStamp;
+    DWORD   PointerToSymbolTable;
+    DWORD   NumberOfSymbols;
+    WORD    SizeOfOptionalHeader;
+    WORD    Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+    DWORD   VirtualAddress;
+    DWORD   Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+    /* Standard fields. */
+    WORD    Magic;
+    BYTE    MajorLinkerVersion;
+    BYTE    MinorLinkerVersion;
+    DWORD   SizeOfCode;
+    DWORD   SizeOfInitializedData;
+    DWORD   SizeOfUninitializedData;
+    DWORD   AddressOfEntryPoint;
+    DWORD   BaseOfCode;
+    DWORD   BaseOfData;
+
+    /* NT additional fields. */
+    DWORD   ImageBase;
+    DWORD   SectionAlignment;
+    DWORD   FileAlignment;
+    WORD    MajorOperatingSystemVersion;
+    WORD    MinorOperatingSystemVersion;
+    WORD    MajorImageVersion;
+    WORD    MinorImageVersion;
+    WORD    MajorSubsystemVersion;
+    WORD    MinorSubsystemVersion;
+    DWORD   Win32VersionValue;
+    DWORD   SizeOfImage;
+    DWORD   SizeOfHeaders;
+    DWORD   CheckSum;
+    WORD    Subsystem;
+    WORD    DllCharacteristics;
+    DWORD   SizeOfStackReserve;
+    DWORD   SizeOfStackCommit;
+    DWORD   SizeOfHeapReserve;
+    DWORD   SizeOfHeapCommit;
+    DWORD   LoaderFlags;
+    DWORD   NumberOfRvaAndSizes;
+    IMAGE_DATA_DIRECTORY DataDirectory[16];
+
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   /* Export Directory */
+#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   /* Import Directory */
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   /* Resource Directory */
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   /* Exception Directory */
+#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   /* Security Directory */
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   /* Base Relocation Table */
+#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   /* Debug Directory */
+/*      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7      (X86 usage) */
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   /* Architecture Specific Data */
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   /* RVA of GP */
+#define IMAGE_DIRECTORY_ENTRY_TLS             9   /* TLS Directory */
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   /* Load Configuration Directory */
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   /* Bound Import Directory in headers */
+#define IMAGE_DIRECTORY_ENTRY_IAT            12   /* Import Address Table */
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   /* Delay Load Import Descriptors */
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   /* COM Runtime descriptor */
+
+/* Section header format. */
+#define IMAGE_SIZEOF_SHORT_NAME         8
+
+typedef struct _IMAGE_SECTION_HEADER {
+    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
+    union {
+            DWORD   PhysicalAddress;
+            DWORD   VirtualSize;
+    } Misc;
+    DWORD   VirtualAddress;
+    DWORD   SizeOfRawData;
+    DWORD   PointerToRawData;
+    DWORD   PointerToRelocations;
+    DWORD   PointerToLinenumbers;
+    WORD    NumberOfRelocations;
+    WORD    NumberOfLinenumbers;
+    DWORD   Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER     40
+
+typedef struct _IMAGE_BASE_RELOCATION {
+    DWORD   VirtualAddress;
+    DWORD   SizeOfBlock;
+//  WORD    TypeOffset[1];
+} IMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION     8
+
+#define IMAGE_REL_BASED_ABSOLUTE         0
+#define IMAGE_REL_BASED_HIGH             1
+#define IMAGE_REL_BASED_LOW              2
+#define IMAGE_REL_BASED_HIGHLOW          3
+#define IMAGE_REL_BASED_HIGHADJ          4
+#define IMAGE_REL_BASED_MIPS_JMPADDR     5
+#define IMAGE_REL_BASED_SECTION          6
+#define IMAGE_REL_BASED_REL32            7
+
+#pragma pack(pop)
+
+/* ----------------------------------------------------------- */
+#endif /* ndef IMAGE_NT_SIGNATURE */
+/* ----------------------------------------------------------- */
+
+#pragma pack(push, 1)
+
+struct pe_header
+{
+    IMAGE_DOS_HEADER doshdr;
+    BYTE dosstub[0x40];
+    DWORD nt_sig;
+    IMAGE_FILE_HEADER filehdr;
+    IMAGE_OPTIONAL_HEADER opthdr;
+};
+
+struct pe_import_header {
+    DWORD first_entry;
+    DWORD time_date;
+    DWORD forwarder;
+    DWORD lib_name_offset;
+    DWORD first_thunk;
+};
+
+struct pe_export_header {
+    DWORD Characteristics;
+    DWORD TimeDateStamp;
+    DWORD Version;
+    DWORD Name;
+    DWORD Base;
+    DWORD NumberOfFunctions;
+    DWORD NumberOfNames;
+    DWORD AddressOfFunctions;
+    DWORD AddressOfNames;
+    DWORD AddressOfNameOrdinals;
+};
+
+struct pe_reloc_header {
+    DWORD offset;
+    DWORD size;
+};
+
+struct pe_rsrc_header {
+    struct _IMAGE_FILE_HEADER filehdr;
+    struct _IMAGE_SECTION_HEADER sectionhdr;
+};
+
+struct pe_rsrc_reloc {
+    DWORD offset;
+    DWORD size;
+    WORD type;
+};
+
+#pragma pack(pop)
+
+/* ----------------------------------------------------------- */
+ST_DATA struct pe_header pe_header = {
+{
+    /* IMAGE_DOS_HEADER doshdr */
+    0x5A4D, /*WORD e_magic;         Magic number */
+    0x0090, /*WORD e_cblp;          Bytes on last page of file */
+    0x0003, /*WORD e_cp;            Pages in file */
+    0x0000, /*WORD e_crlc;          Relocations */
+
+    0x0004, /*WORD e_cparhdr;       Size of header in paragraphs */
+    0x0000, /*WORD e_minalloc;      Minimum extra paragraphs needed */
+    0xFFFF, /*WORD e_maxalloc;      Maximum extra paragraphs needed */
+    0x0000, /*WORD e_ss;            Initial (relative) SS value */
+
+    0x00B8, /*WORD e_sp;            Initial SP value */
+    0x0000, /*WORD e_csum;          Checksum */
+    0x0000, /*WORD e_ip;            Initial IP value */
+    0x0000, /*WORD e_cs;            Initial (relative) CS value */
+    0x0040, /*WORD e_lfarlc;        File address of relocation table */
+    0x0000, /*WORD e_ovno;          Overlay number */
+    {0,0,0,0}, /*WORD e_res[4];     Reserved words */
+    0x0000, /*WORD e_oemid;         OEM identifier (for e_oeminfo) */
+    0x0000, /*WORD e_oeminfo;       OEM information; e_oemid specific */
+    {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10];      Reserved words */
+    0x00000080  /*DWORD   e_lfanew;        File address of new exe header */
+},{
+    /* BYTE dosstub[0x40] */
+    /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */
+    0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
+    0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
+    0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
+    0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+},
+    0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */
+{
+    /* IMAGE_FILE_HEADER filehdr */
+    0x014C, /*WORD    Machine; */
+    0x0003, /*WORD    NumberOfSections; */
+    0x00000000, /*DWORD   TimeDateStamp; */
+    0x00000000, /*DWORD   PointerToSymbolTable; */
+    0x00000000, /*DWORD   NumberOfSymbols; */
+    0x00E0, /*WORD    SizeOfOptionalHeader; */
+    0x030F  /*WORD    Characteristics; */
+},{
+    /* IMAGE_OPTIONAL_HEADER opthdr */
+    /* Standard fields. */
+    0x010B, /*WORD    Magic; */
+    0x06, /*BYTE    MajorLinkerVersion; */
+    0x00, /*BYTE    MinorLinkerVersion; */
+    0x00000000, /*DWORD   SizeOfCode; */
+    0x00000000, /*DWORD   SizeOfInitializedData; */
+    0x00000000, /*DWORD   SizeOfUninitializedData; */
+    0x00000000, /*DWORD   AddressOfEntryPoint; */
+    0x00000000, /*DWORD   BaseOfCode; */
+    0x00000000, /*DWORD   BaseOfData; */
+
+    /* NT additional fields. */
+    0x00400000, /*DWORD   ImageBase; */
+    0x00001000, /*DWORD   SectionAlignment; */
+    0x00000200, /*DWORD   FileAlignment; */
+    0x0004, /*WORD    MajorOperatingSystemVersion; */
+    0x0000, /*WORD    MinorOperatingSystemVersion; */
+    0x0000, /*WORD    MajorImageVersion; */
+    0x0000, /*WORD    MinorImageVersion; */
+    0x0004, /*WORD    MajorSubsystemVersion; */
+    0x0000, /*WORD    MinorSubsystemVersion; */
+    0x00000000, /*DWORD   Win32VersionValue; */
+    0x00000000, /*DWORD   SizeOfImage; */
+    0x00000200, /*DWORD   SizeOfHeaders; */
+    0x00000000, /*DWORD   CheckSum; */
+    0x0002, /*WORD    Subsystem; */
+    0x0000, /*WORD    DllCharacteristics; */
+    0x00100000, /*DWORD   SizeOfStackReserve; */
+    0x00001000, /*DWORD   SizeOfStackCommit; */
+    0x00100000, /*DWORD   SizeOfHeapReserve; */
+    0x00001000, /*DWORD   SizeOfHeapCommit; */
+    0x00000000, /*DWORD   LoaderFlags; */
+    0x00000010, /*DWORD   NumberOfRvaAndSizes; */
+
+    /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */
+    {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+     {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
+}};
+
+/* ------------------------------------------------------------- */
+/* internal temporary structures */
+
+/*
+#define IMAGE_SCN_CNT_CODE                  0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA      0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA    0x00000080
+#define IMAGE_SCN_MEM_DISCARDABLE           0x02000000
+#define IMAGE_SCN_MEM_SHARED                0x10000000
+#define IMAGE_SCN_MEM_EXECUTE               0x20000000
+#define IMAGE_SCN_MEM_READ                  0x40000000
+#define IMAGE_SCN_MEM_WRITE                 0x80000000
+*/
+
+enum {
+    sec_text = 0,
+    sec_data ,
+    sec_bss ,
+    sec_idata ,
+    sec_other ,
+    sec_rsrc ,
+    sec_stab ,
+    sec_reloc ,
+    sec_last
+};
+
+ST_DATA DWORD pe_sec_flags[] = {
+    0x60000020, /* ".text"     , */
+    0xC0000040, /* ".data"     , */
+    0xC0000080, /* ".bss"      , */
+    0x40000040, /* ".idata"    , */
+    0xE0000060, /* < other >   , */
+    0x40000040, /* ".rsrc"     , */
+    0x42000802, /* ".stab"     , */
+    0x42000040, /* ".reloc"    , */
+};
+
+struct section_info {
+    int cls, ord;
+    char name[32];
+    DWORD sh_addr;
+    DWORD sh_size;
+    DWORD sh_flags;
+    unsigned char *data;
+    DWORD data_size;
+    IMAGE_SECTION_HEADER ish;
+};
+
+struct import_symbol {
+    int sym_index;
+    int iat_index;
+    int thk_offset;
+};
+
+struct pe_import_info {
+    int dll_index;
+    int sym_count;
+    struct import_symbol **symbols;
+};
+
+struct pe_info {
+    TCCState *s1;
+    Section *reloc;
+    Section *thunk;
+    const char *filename;
+    int type;
+    DWORD sizeofheaders;
+    DWORD imagebase;
+    DWORD start_addr;
+    DWORD imp_offs;
+    DWORD imp_size;
+    DWORD iat_offs;
+    DWORD iat_size;
+    DWORD exp_offs;
+    DWORD exp_size;
+    struct section_info *sec_info;
+    int sec_count;
+    struct pe_import_info **imp_info;
+    int imp_count;
+};
+
+/* ------------------------------------------------------------- */
+
+#define PE_NUL 0
+#define PE_DLL 1
+#define PE_GUI 2
+#define PE_EXE 3
+
+void error_noabort(const char *, ...);
+
+#ifdef _WIN32
+void dbg_printf (const char *fmt, ...)
+{
+    char buffer[4000];
+    va_list arg;
+    int x;
+    va_start(arg, fmt);
+    x = vsprintf (buffer, fmt, arg);
+    strcpy(buffer+x, "\n");
+    OutputDebugString(buffer);
+}
+#endif
+
+/* --------------------------------------------*/
+
+ST_FN const char* get_alt_symbol(char *buffer, const char *symbol)
+{
+    const char *p;
+    p = strrchr(symbol, '@');
+    if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */
+        strcpy(buffer, symbol+1)[p-symbol-1] = 0;
+    } else if (symbol[0] != '_') { /* try non-ansi function */
+        buffer[0] = '_', strcpy(buffer + 1, symbol);
+    } else if (0 == memcmp(symbol, "__imp__", 7)) { /* mingw 2.0 */
+        strcpy(buffer, symbol + 6);
+    } else if (0 == memcmp(symbol, "_imp___", 7)) { /* mingw 3.7 */
+        strcpy(buffer, symbol + 6);
+    } else {
+        return symbol;
+    }
+    return buffer;
+}
+
+ST_FN int pe_find_import(TCCState * s1, const char *symbol)
+{
+    char buffer[200];
+    const char *s;
+    int sym_index, n = 0;
+    do {
+        s = n ? get_alt_symbol(buffer, symbol) : symbol;
+        sym_index = find_elf_sym(s1->dynsymtab_section, s);
+        // printf("find %d %s\n", sym_index, s);
+    } while (0 == sym_index && ++n < 2);
+    return sym_index;
+}
+
+#if defined _WIN32 || defined __CYGWIN__
+
+#ifdef __CYGWIN__
+# include <dlfcn.h>
+# define LoadLibrary(s) dlopen(s, RTLD_NOW)
+# define GetProcAddress(h,s) dlsym(h, s)
+#else
+# define dlclose(h) FreeLibrary(h)
+#endif
+
+/* for the -run option: dynamically load symbol from dll */
+void *resolve_sym(struct TCCState *s1, const char *symbol, int type)
+{
+    char buffer[100];
+    int sym_index, dll_index;
+    void *addr, **m;
+    DLLReference *dllref;
+
+    sym_index = pe_find_import(s1, symbol);
+    if (0 == sym_index)
+        return NULL;
+    dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value;
+    dllref = s1->loaded_dlls[dll_index-1];
+    if ( !dllref->handle )
+    {
+        dllref->handle = LoadLibrary(dllref->name);
+    }
+    addr = GetProcAddress(dllref->handle, symbol);
+    if (NULL == addr)
+        addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol));
+
+    if (addr && STT_OBJECT == type) {
+        /* need to return a pointer to the address for data objects */
+        m = (void**)tcc_malloc(sizeof addr), *m = addr, addr = m;
+#ifdef MEM_DEBUG
+        /* yep, we don't free it */
+        mem_cur_size -= sizeof (void*);
+#endif
+    }
+    return addr;
+}
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+ST_FN int dynarray_assoc(void **pp, int n, int key)
+{
+    int i;
+    for (i = 0; i < n; ++i, ++pp)
+    if (key == **(int **) pp)
+        return i;
+    return -1;
+}
+
+#if 0
+ST_FN DWORD umin(DWORD a, DWORD b)
+{
+    return a < b ? a : b;
+}
+#endif
+
+ST_FN DWORD umax(DWORD a, DWORD b)
+{
+    return a < b ? b : a;
+}
+
+ST_FN void pe_fpad(FILE *fp, DWORD new_pos)
+{
+    DWORD pos = ftell(fp);
+    while (++pos <= new_pos)
+        fputc(0, fp);
+}
+
+ST_FN DWORD pe_file_align(DWORD n)
+{
+    return (n + (0x200 - 1)) & ~(0x200 - 1);
+}
+
+ST_FN DWORD pe_virtual_align(DWORD n)
+{
+    return (n + (0x1000 - 1)) & ~(0x1000 - 1);
+}
+
+ST_FN 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(int dir, DWORD addr, DWORD size)
+{
+    pe_header.opthdr.DataDirectory[dir].VirtualAddress = addr;
+    pe_header.opthdr.DataDirectory[dir].Size = size;
+}
+
+/*----------------------------------------------------------------------------*/
+ST_FN int pe_write(struct pe_info *pe)
+{
+    int i;
+    FILE *op;
+    DWORD file_offset, r;
+
+    op = fopen(pe->filename, "wb");
+    if (NULL == op) {
+        error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
+        return 1;
+    }
+
+    pe->sizeofheaders = pe_file_align(
+        sizeof pe_header
+        + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
+        );
+
+    file_offset = pe->sizeofheaders;
+    pe_fpad(op, file_offset);
+
+    if (2 == pe->s1->verbose)
+        printf("-------------------------------"
+               "\n  virt   file   size  section" "\n");
+
+    for (i = 0; i < pe->sec_count; ++i) {
+        struct section_info *si = pe->sec_info + i;
+        const char *sh_name = si->name;
+        unsigned long addr = si->sh_addr - pe->imagebase;
+        unsigned long size = si->sh_size;
+        IMAGE_SECTION_HEADER *psh = &si->ish;
+
+        if (2 == pe->s1->verbose)
+            printf("%6lx %6lx %6lx  %s\n",
+                addr, file_offset, size, sh_name);
+
+        switch (si->cls) {
+            case sec_text:
+                pe_header.opthdr.BaseOfCode = addr;
+                pe_header.opthdr.AddressOfEntryPoint = addr + pe->start_addr;
+                break;
+
+            case sec_data:
+                pe_header.opthdr.BaseOfData = addr;
+                break;
+
+            case sec_bss:
+                break;
+
+            case sec_reloc:
+                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
+                break;
+
+            case sec_rsrc:
+                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
+                break;
+
+            case sec_stab:
+                break;
+        }
+
+        if (pe->thunk == pe->s1->sections[si->ord]) {
+            if (pe->imp_size) {
+                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IMPORT,
+                    pe->imp_offs + addr, pe->imp_size);
+                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_IAT,
+                    pe->iat_offs + addr, pe->iat_size);
+            }
+            if (pe->exp_size) {
+                pe_set_datadir(IMAGE_DIRECTORY_ENTRY_EXPORT,
+                    pe->exp_offs + addr, pe->exp_size);
+            }
+        }
+
+        strcpy((char*)psh->Name, sh_name);
+
+        psh->Characteristics = pe_sec_flags[si->cls];
+        psh->VirtualAddress = addr;
+        psh->Misc.VirtualSize = size;
+        pe_header.opthdr.SizeOfImage =
+            umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage); 
+
+        if (si->data_size) {
+            psh->PointerToRawData = r = file_offset;
+            fwrite(si->data, 1, si->data_size, op);
+            file_offset = pe_file_align(file_offset + si->data_size);
+            psh->SizeOfRawData = file_offset - r;
+            pe_fpad(op, file_offset);
+        }
+    }
+
+    // pe_header.filehdr.TimeDateStamp = time(NULL);
+    pe_header.filehdr.NumberOfSections = pe->sec_count;
+    pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
+    pe_header.opthdr.ImageBase = pe->imagebase;
+    if (PE_DLL == pe->type)
+        pe_header.filehdr.Characteristics = 0x230E;
+    else if (PE_GUI != pe->type)
+        pe_header.opthdr.Subsystem = 3;
+
+    fseek(op, SEEK_SET, 0);
+    fwrite(&pe_header,  1, sizeof pe_header, op);
+    for (i = 0; i < pe->sec_count; ++i)
+        fwrite(&pe->sec_info[i].ish, 1, sizeof(IMAGE_SECTION_HEADER), op);
+    fclose (op);
+
+    if (2 == pe->s1->verbose)
+        printf("-------------------------------\n");
+    if (pe->s1->verbose)
+        printf("<- %s (%lu bytes)\n", pe->filename, file_offset);
+
+    return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+ST_FN struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
+{
+    int i;
+    int dll_index;
+    struct pe_import_info *p;
+    struct import_symbol *s;
+
+    dll_index = ((Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index)->st_value;
+    if (0 == dll_index)
+        return NULL;
+
+    i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index);
+    if (-1 != i) {
+        p = pe->imp_info[i];
+        goto found_dll;
+    }
+    p = tcc_mallocz(sizeof *p);
+    p->dll_index = dll_index;
+    dynarray_add((void***)&pe->imp_info, &pe->imp_count, p);
+
+found_dll:
+    i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index);
+    if (-1 != i)
+        return p->symbols[i];
+
+    s = tcc_mallocz(sizeof *s);
+    dynarray_add((void***)&p->symbols, &p->sym_count, s);
+    s->sym_index = sym_index;
+    return s;
+}
+
+/*----------------------------------------------------------------------------*/
+ST_FN 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;
+    int ndlls = pe->imp_count;
+
+    for (sym_cnt = i = 0; i < ndlls; ++i)
+        sym_cnt += pe->imp_info[i]->sym_count;
+
+    if (0 == sym_cnt)
+        return;
+
+    pe_align_section(pe->thunk, 16);
+
+    pe->imp_offs = dll_ptr = pe->thunk->data_offset;
+    pe->imp_size = (ndlls + 1) * sizeof(struct pe_import_header);
+    pe->iat_offs = dll_ptr + pe->imp_size;
+    pe->iat_size = (sym_cnt + ndlls) * sizeof(DWORD);
+    section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size);
+
+    thk_ptr = pe->iat_offs;
+    ent_ptr = pe->iat_offs + pe->iat_size;
+
+    for (i = 0; i < pe->imp_count; ++i) {
+        struct pe_import_header *hdr;
+        int k, n, v;
+        struct pe_import_info *p = pe->imp_info[i];
+        const char *name = pe->s1->loaded_dlls[p->dll_index-1]->name;
+
+        /* put the dll name into the import header */
+        v = put_elf_str(pe->thunk, name);
+
+        hdr = (struct pe_import_header*)(pe->thunk->data + dll_ptr);
+        hdr->first_thunk     = thk_ptr + rva_base;
+        hdr->first_entry     = ent_ptr + rva_base;
+        hdr->lib_name_offset = v + rva_base;
+
+        for (k = 0, n = p->sym_count; k <= n; ++k) {
+            if (k < n) {
+                DWORD iat_index = p->symbols[k]->iat_index;
+                int sym_index = p->symbols[k]->sym_index;
+                Elf32_Sym *imp_sym = (Elf32_Sym *)pe->s1->dynsymtab_section->data + sym_index;
+                Elf32_Sym *org_sym = (Elf32_Sym *)symtab_section->data + iat_index;
+                const char *name = pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
+
+                org_sym->st_value = thk_ptr;
+                org_sym->st_shndx = pe->thunk->sh_num;
+                v = pe->thunk->data_offset + rva_base;
+                section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
+                put_elf_str(pe->thunk, name);
+
+            } else {
+                v = 0; /* last entry is zero */
+            }
+            *(DWORD*)(pe->thunk->data+thk_ptr) =
+            *(DWORD*)(pe->thunk->data+ent_ptr) = v;
+            thk_ptr += sizeof (DWORD);
+            ent_ptr += sizeof (DWORD);
+        }
+        dll_ptr += sizeof(struct pe_import_header);
+        dynarray_reset(&p->symbols, &p->sym_count);
+    }
+    dynarray_reset(&pe->imp_info, &pe->imp_count);
+}
+
+/* ------------------------------------------------------------- */
+/*
+    For now only functions are exported. Export of data
+    would work, but import requires compiler support to
+    do an additional indirection.
+
+    For instance:
+        __declspec(dllimport) extern int something;
+
+    needs to be translated to:
+
+        *(int*)something
+*/
+
+ST_FN int sym_cmp(const void *va, const void *vb)
+{
+    const char *ca = ((const char **)va)[1];
+    const char *cb = ((const char **)vb)[1];
+    return strcmp(ca, cb);
+}
+
+ST_FN void pe_build_exports(struct pe_info *pe)
+{
+    Elf32_Sym *sym;
+    int sym_index, sym_end;
+    DWORD rva_base, func_o, name_o, ord_o, str_o;
+    struct pe_export_header *hdr;
+    int sym_count, n, ord, *sorted, *sp;
+
+    FILE *op;
+    char buf[MAX_PATH];
+    const char *dllname;
+    const char *name;
+
+    rva_base = pe->thunk->sh_addr - pe->imagebase;
+    sym_count = 0, n = 1, sorted = NULL, op = NULL;
+
+    sym_end = symtab_section->data_offset / sizeof(Elf32_Sym);
+    for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+        sym = (Elf32_Sym*)symtab_section->data + sym_index;
+        name = symtab_section->link->data + sym->st_name;
+        if ((sym->st_other & 1)
+            /* export only symbols from actually written sections */
+            && pe->s1->sections[sym->st_shndx]->sh_addr) {
+            dynarray_add((void***)&sorted, &sym_count, (void*)n);
+            dynarray_add((void***)&sorted, &sym_count, (void*)name);
+        }
+        ++n;
+#if 0
+        if (sym->st_other & 1)
+            printf("export: %s\n", name);
+        if (sym->st_other & 2)
+            printf("stdcall: %s\n", name);
+#endif
+    }
+
+    if (0 == sym_count)
+        return;
+    sym_count /= 2;
+
+    qsort (sorted, sym_count, 2 * sizeof sorted[0], sym_cmp);
+    pe_align_section(pe->thunk, 16);
+    dllname = tcc_basename(pe->filename);
+
+    pe->exp_offs = pe->thunk->data_offset;
+    func_o = pe->exp_offs + sizeof(struct pe_export_header);
+    name_o = func_o + sym_count * sizeof (DWORD);
+    ord_o = name_o + sym_count * sizeof (DWORD);
+    str_o = ord_o + sym_count * sizeof(WORD);
+
+    hdr = section_ptr_add(pe->thunk, str_o - pe->exp_offs);
+    hdr->Characteristics        = 0;
+    hdr->Base                   = 1;
+    hdr->NumberOfFunctions      = sym_count;
+    hdr->NumberOfNames          = sym_count;
+    hdr->AddressOfFunctions     = func_o + rva_base;
+    hdr->AddressOfNames         = name_o + rva_base;
+    hdr->AddressOfNameOrdinals  = ord_o + rva_base;
+    hdr->Name                   = str_o + rva_base;
+    put_elf_str(pe->thunk, dllname);
+
+#if 1
+    /* automatically write exports to <output-filename>.def */
+    strcpy(buf, pe->filename);
+    strcpy(tcc_fileextension(buf), ".def");
+    op = fopen(buf, "w");
+    if (NULL == op) {
+        error_noabort("could not create '%s': %s", buf, strerror(errno));
+    } else {
+        fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
+        if (pe->s1->verbose)
+            printf("<- %s (%d symbols)\n", buf, sym_count);
+    }
+#endif
+
+    for (sp = sorted, ord = 0; ord < sym_count; ++ord, sp += 2)
+    {
+        sym_index = sp[0], name = (const char *)sp[1];
+        /* insert actual address later in pe_relocate_rva */
+        put_elf_reloc(symtab_section, pe->thunk,
+            func_o, R_386_RELATIVE, sym_index);
+        *(DWORD*)(pe->thunk->data + name_o)
+            = pe->thunk->data_offset + rva_base;
+        *(WORD*)(pe->thunk->data + ord_o)
+            = ord;
+        put_elf_str(pe->thunk, name);
+        func_o += sizeof (DWORD);
+        name_o += sizeof (DWORD);
+        ord_o += sizeof (WORD);
+
+        if (op)
+            fprintf(op, "%s\n", name);
+    }
+    pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
+    tcc_free(sorted);
+}
+
+/* ------------------------------------------------------------- */
+ST_FN void pe_build_reloc (struct pe_info *pe)
+{
+    DWORD offset, block_ptr, addr;
+    int count, i;
+    Elf32_Rel *rel, *rel_end;
+    Section *s = NULL, *sr;
+
+    offset = addr = block_ptr = count = i = 0;
+    rel = rel_end = NULL;
+
+    for(;;) {
+        if (rel < rel_end) {
+            int type = ELF32_R_TYPE(rel->r_info);
+            addr = rel->r_offset + s->sh_addr;
+            ++ rel;
+            if (type != R_386_32)
+                continue;
+            if (count == 0) { /* new block */
+                block_ptr = pe->reloc->data_offset;
+                section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header));
+                offset = addr & 0xFFFFFFFF<<12;
+            }
+            if ((addr -= offset)  < (1<<12)) { /* one block spans 4k addresses */
+                WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
+                *wp = addr | IMAGE_REL_BASED_HIGHLOW<<12;
+                ++count;
+                continue;
+            }
+            -- rel;
+
+        } else if (i < pe->sec_count) {
+            sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc;
+            if (sr) {
+                rel = (Elf32_Rel *)sr->data;
+                rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
+            }
+            continue;
+        }
+
+        if (count) {
+            /* store the last block and ready for a new one */
+            struct pe_reloc_header *hdr;
+            if (count & 1) /* align for DWORDS */
+                section_ptr_add(pe->reloc, sizeof(WORD)), ++count;
+            hdr = (struct pe_reloc_header *)(pe->reloc->data + block_ptr);
+            hdr -> offset = offset - pe->imagebase;
+            hdr -> size = count * sizeof(WORD) + sizeof(struct pe_reloc_header);
+            count = 0;
+        }
+
+        if (rel >= rel_end)
+            break;
+    }
+}
+
+/* ------------------------------------------------------------- */
+ST_FN int pe_section_class(Section *s)
+{
+    int type, flags;
+    const char *name;
+
+    type = s->sh_type;
+    flags = s->sh_flags;
+    name = s->name;
+    if (flags & SHF_ALLOC) {
+        if (type == SHT_PROGBITS) {
+            if (flags & SHF_EXECINSTR)
+                return sec_text;
+            if (flags & SHF_WRITE)
+                return sec_data;
+            if (0 == strcmp(name, ".rsrc"))
+                return sec_rsrc;
+            if (0 == strcmp(name, ".iedat"))
+                return sec_idata;
+            return sec_other;
+        } else if (type == SHT_NOBITS) {
+            if (flags & SHF_WRITE)
+                return sec_bss;
+        }
+    } else {
+        if (0 == strcmp(name, ".reloc"))
+            return sec_reloc;
+        if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */
+            return sec_stab;
+    }
+    return -1;
+}
+
+ST_FN int pe_assign_addresses (struct pe_info *pe)
+{
+    int i, k, o, c;
+    DWORD addr;
+    int *section_order;
+    struct section_info *si;
+    Section *s;
+
+    // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
+
+    section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int));
+    for (o = k = 0 ; k < sec_last; ++k) {
+        for (i = 1; i < pe->s1->nb_sections; ++i) {
+            s = pe->s1->sections[i];
+            if (k == pe_section_class(s)) {
+                // printf("%s %d\n", s->name, k);
+                s->sh_addr = pe->imagebase;
+                section_order[o++] = i;
+            }
+        }
+    }
+
+    pe->sec_info = tcc_mallocz(o * sizeof (struct section_info));
+    addr = pe->imagebase + 1;
+
+    for (i = 0; i < o; ++i)
+    {
+        k = section_order[i];
+        s = pe->s1->sections[k];
+        c = pe_section_class(s);
+        si = &pe->sec_info[pe->sec_count];
+
+#ifdef PE_MERGE_DATA
+        if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) {
+            /* append .bss to .data */
+            s->sh_addr = addr = ((addr-1) | 15) + 1;
+            addr += s->data_offset;
+            si[-1].sh_size = addr - si[-1].sh_addr;
+            continue;
+        }
+#endif
+        strcpy(si->name, s->name);
+        si->cls = c;
+        si->ord = k;
+        si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr);
+        si->sh_flags = s->sh_flags;
+
+        if (c == sec_data && NULL == pe->thunk)
+            pe->thunk = s;
+
+        if (s == pe->thunk) {
+            pe_build_imports(pe);
+            pe_build_exports(pe);
+        }
+
+        if (c == sec_reloc)
+            pe_build_reloc (pe);
+
+        if (s->data_offset)
+        {
+            if (s->sh_type != SHT_NOBITS) {
+                si->data = s->data;
+                si->data_size = s->data_offset;
+            }
+
+            addr += s->data_offset;
+            si->sh_size = s->data_offset;
+            ++pe->sec_count;
+        }
+        // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name);
+    }
+
+#if 0
+    for (i = 1; i < pe->s1->nb_sections; ++i) {
+        Section *s = pe->s1->sections[i];
+        int type = s->sh_type;
+        int flags = s->sh_flags;
+        printf("section %-16s %-10s %5x %s,%s,%s\n",
+            s->name,
+            type == SHT_PROGBITS ? "progbits" :
+            type == SHT_NOBITS ? "nobits" :
+            type == SHT_SYMTAB ? "symtab" :
+            type == SHT_STRTAB ? "strtab" :
+            type == SHT_REL ? "rel" : "???",
+            s->data_offset,
+            flags & SHF_ALLOC ? "alloc" : "",
+            flags & SHF_WRITE ? "write" : "",
+            flags & SHF_EXECINSTR ? "exec" : ""
+            );
+    }
+    pe->s1->verbose = 2;
+#endif
+
+    tcc_free(section_order);
+    return 0;
+}
+
+/* ------------------------------------------------------------- */
+ST_FN void pe_relocate_rva (struct pe_info *pe, Section *s)
+{
+    Section *sr = s->reloc;
+    Elf32_Rel *rel, *rel_end;
+    rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
+    for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++)
+        if (ELF32_R_TYPE(rel->r_info) == R_386_RELATIVE) {
+            int sym_index = ELF32_R_SYM(rel->r_info);
+            DWORD addr = s->sh_addr;
+            if (sym_index) {
+                Elf32_Sym *sym = (Elf32_Sym *)symtab_section->data + sym_index;
+                addr = sym->st_value;
+            }
+            *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
+        }
+}
+
+/*----------------------------------------------------------------------------*/
+ST_FN int pe_check_symbols(struct pe_info *pe)
+{
+    Elf32_Sym *sym;
+    int sym_index, sym_end;
+    int ret = 0;
+
+    pe_align_section(text_section, 8);
+
+    sym_end = symtab_section->data_offset / sizeof(Elf32_Sym);
+    for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+
+        sym = (Elf32_Sym*)symtab_section->data + sym_index;
+        if (sym->st_shndx == SHN_UNDEF) {
+
+            const char *name = symtab_section->link->data + sym->st_name;
+            unsigned type = ELF32_ST_TYPE(sym->st_info);
+            int imp_sym = pe_find_import(pe->s1, name);
+            struct import_symbol *is;
+
+            if (0 == imp_sym)
+                goto not_found;
+            is = pe_add_import(pe, imp_sym);
+            if (!is)
+                goto not_found;
+
+            if (type == STT_FUNC) {
+                unsigned long offset = is->thk_offset;
+                if (offset) {
+                    /* got aliased symbol, like stricmp and _stricmp */
+
+                } else {
+                    char buffer[100];
+
+                    offset = text_section->data_offset;
+                    /* add the 'jmp IAT[x]' instruction */
+                    *(WORD*)section_ptr_add(text_section, 8) = 0x25FF;
+
+                    /* add a helper symbol, will be patched later in
+                       pe_build_imports */
+                    sprintf(buffer, "IAT.%s", name);
+                    is->iat_index = put_elf_sym(
+                        symtab_section, 0, sizeof(DWORD),
+                        ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
+                        0, SHN_UNDEF, buffer);
+                    put_elf_reloc(symtab_section, text_section, 
+                        offset + 2, R_386_32, is->iat_index);
+                    is->thk_offset = offset;
+                }
+
+                /* tcc_realloc might have altered sym's address */
+                sym = (Elf32_Sym*)symtab_section->data + sym_index;
+
+                /* patch the original symbol */
+                sym->st_value = offset;
+                sym->st_shndx = text_section->sh_num;
+                sym->st_other &= ~1; /* do not export */
+                continue;
+            }
+
+            if (type == STT_OBJECT) { /* data, ptr to that should be */
+                if (0 == is->iat_index) {
+                    /* original symbol will be patched later in pe_build_imports */
+                    is->iat_index = sym_index;
+                    continue;
+                }
+            }
+
+        not_found:
+            error_noabort("undefined symbol '%s'", name);
+            ret = 1;
+
+        } else if (pe->s1->rdynamic
+                   && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
+            /* if -rdynamic option, then export all non local symbols */
+            sym->st_other |= 1;
+        }
+    }
+    return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+#ifdef PE_PRINT_SECTIONS
+ST_FN void pe_print_section(FILE * f, Section * s)
+{
+    /* just if you'r curious */
+    BYTE *p, *e, b;
+    int i, n, l, m;
+    p = s->data;
+    e = s->data + s->data_offset;
+    l = e - p;
+
+    fprintf(f, "section  \"%s\"", s->name);
+    if (s->link)
+        fprintf(f, "\nlink     \"%s\"", s->link->name);
+    if (s->reloc)
+        fprintf(f, "\nreloc    \"%s\"", s->reloc->name);
+    fprintf(f, "\nv_addr   %08X", s->sh_addr);
+    fprintf(f, "\ncontents %08X", l);
+    fprintf(f, "\n\n");
+
+    if (s->sh_type == SHT_NOBITS)
+        return;
+
+    if (0 == l)
+        return;
+
+    if (s->sh_type == SHT_SYMTAB)
+        m = sizeof(Elf32_Sym);
+    if (s->sh_type == SHT_REL)
+        m = sizeof(Elf32_Rel);
+    else
+        m = 16;
+
+    fprintf(f, "%-8s", "offset");
+    for (i = 0; i < m; ++i)
+        fprintf(f, " %02x", i);
+    n = 56;
+
+    if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_REL) {
+        const char *fields1[] = {
+            "name",
+            "value",
+            "size",
+            "bind",
+            "type",
+            "other",
+            "shndx",
+            NULL
+        };
+
+        const char *fields2[] = {
+            "offs",
+            "type",
+            "symb",
+            NULL
+        };
+
+        const char **p;
+
+        if (s->sh_type == SHT_SYMTAB)
+            p = fields1, n = 106;
+        else
+            p = fields2, n = 58;
+
+        for (i = 0; p[i]; ++i)
+            fprintf(f, "%6s", p[i]);
+        fprintf(f, "  symbol");
+    }
+
+    fprintf(f, "\n");
+    for (i = 0; i < n; ++i)
+        fprintf(f, "-");
+    fprintf(f, "\n");
+
+    for (i = 0; i < l;)
+    {
+        fprintf(f, "%08X", i);
+        for (n = 0; n < m; ++n) {
+            if (n + i < l)
+                fprintf(f, " %02X", p[i + n]);
+            else
+                fprintf(f, "   ");
+        }
+
+        if (s->sh_type == SHT_SYMTAB) {
+            Elf32_Sym *sym = (Elf32_Sym *) (p + i);
+            const char *name = s->link->data + sym->st_name;
+            fprintf(f, "  %04X  %04X  %04X   %02X    %02X    %02X   %04X  \"%s\"",
+                    sym->st_name,
+                    sym->st_value,
+                    sym->st_size,
+                    ELF32_ST_BIND(sym->st_info),
+                    ELF32_ST_TYPE(sym->st_info),
+                    sym->st_other, sym->st_shndx, name);
+
+        } else if (s->sh_type == SHT_REL) {
+            Elf32_Rel *rel = (Elf32_Rel *) (p + i);
+            Elf32_Sym *sym =
+                (Elf32_Sym *) s->link->data + ELF32_R_SYM(rel->r_info);
+            const char *name = s->link->link->data + sym->st_name;
+            fprintf(f, "  %04X   %02X   %04X  \"%s\"",
+                    rel->r_offset,
+                    ELF32_R_TYPE(rel->r_info),
+                    ELF32_R_SYM(rel->r_info), name);
+        } else {
+            fprintf(f, "   ");
+            for (n = 0; n < m; ++n) {
+                if (n + i < l) {
+                    b = p[i + n];
+                    if (b < 32 || b >= 127)
+                        b = '.';
+                    fprintf(f, "%c", b);
+                }
+            }
+        }
+        i += m;
+        fprintf(f, "\n");
+    }
+    fprintf(f, "\n\n");
+}
+
+ST_FN void pe_print_sections(TCCState *s1, const char *fname)
+{
+    Section *s;
+    FILE *f;
+    int i;
+    f = fopen(fname, "wt");
+    for (i = 1; i < s1->nb_sections; ++i) {
+        s = s1->sections[i];
+        pe_print_section(f, s);
+    }
+    pe_print_section(f, s1->dynsymtab_section);
+    fclose(f);
+}
+#endif
+
+/* -------------------------------------------------------------
+ *  This is for compiled windows resources in 'coff' format
+ *  as generated by 'windres.exe -O coff ...'.
+ */
+
+PUB_FN int pe_test_res_file(void *v, int size)
+{
+    struct pe_rsrc_header *p = (struct pe_rsrc_header *)v;
+    return
+        size >= IMAGE_SIZEOF_FILE_HEADER + IMAGE_SIZEOF_SHORT_NAME /* = 28 */
+        && p->filehdr.Machine == 0x014C
+        && 1 == p->filehdr.NumberOfSections
+        && 0 == strcmp(p->sectionhdr.Name, ".rsrc")
+        ;
+}
+
+ST_FN int read_n(int fd, void *ptr, unsigned size)
+{
+    return size == read(fd, ptr, size);
+}
+
+PUB_FN int pe_load_res_file(TCCState *s1, int fd)
+{
+    struct pe_rsrc_header hdr;
+    Section *rsrc_section;
+    int i, ret = -1;
+    BYTE *ptr;
+
+    lseek (fd, 0, SEEK_SET);
+    if (!read_n(fd, &hdr, sizeof hdr))
+        goto quit;
+    if (!pe_test_res_file(&hdr, sizeof hdr))
+        goto quit;
+
+    rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC);
+    ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData);
+    lseek (fd, hdr.sectionhdr.PointerToRawData, SEEK_SET);
+    if (!read_n(fd, ptr, hdr.sectionhdr.SizeOfRawData))
+        goto quit;
+
+    lseek (fd, hdr.sectionhdr.PointerToRelocations, SEEK_SET);
+    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
+    {
+        struct pe_rsrc_reloc rel;
+        if (!read_n(fd, &rel, sizeof rel))
+            goto quit;
+        // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
+        if (rel.type != 7) /* DIR32NB */
+            goto quit;
+        put_elf_reloc(symtab_section, rsrc_section,
+            rel.offset, R_386_RELATIVE, 0);
+    }
+    ret = 0;
+quit:
+    if (ret)
+        error_noabort("unrecognized resource file format");
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+ST_FN char *trimfront(char *p)
+{
+    while (*p && (unsigned char)*p <= ' ')
+        ++p;
+    return p;
+}
+
+ST_FN char *trimback(char *a, char *e)
+{
+    while (e > a && (unsigned char)e[-1] <= ' ')
+        --e;
+    *e = 0;;
+    return a;
+}
+
+ST_FN char *get_line(char *line, int size, FILE *fp)
+{
+    if (NULL == fgets(line, size, fp))
+        return NULL;
+    trimback(line, strchr(line, 0));
+    return trimfront(line);
+}
+
+/* ------------------------------------------------------------- */
+PUB_FN int pe_load_def_file(TCCState *s1, int fd)
+{
+    DLLReference *dllref;
+    int state = 0, ret = -1;
+    char line[400], dllname[80], *p;
+    FILE *fp = fdopen(dup(fd), "rb");
+
+    if (NULL == fp)
+        goto quit;
+
+    for (;;) {
+        p = get_line(line, sizeof line, fp);
+        if (NULL == p)
+            break;
+        if (0 == *p || ';' == *p)
+            continue;
+        switch (state) {
+        case 0:
+            if (0 != strnicmp(p, "LIBRARY", 7))
+                goto quit;
+            strcpy(dllname, trimfront(p+7));
+            ++state;
+            continue;
+
+        case 1:
+            if (0 != stricmp(p, "EXPORTS"))
+                goto quit;
+            ++state;
+            continue;
+
+        case 2:
+            dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
+            strcpy(dllref->name, dllname);
+            dynarray_add((void ***) &s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+            ++state;
+
+        default:
+            add_elf_sym(s1->dynsymtab_section,
+                s1->nb_loaded_dlls, 0,
+                ELF32_ST_INFO(STB_GLOBAL, STT_FUNC), 0,
+                text_section->sh_num, p);
+            continue;
+        }
+    }
+    ret = 0;
+quit:
+    if (fp)
+        fclose(fp);
+    if (ret)
+        error_noabort("unrecognized export definition file format");
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+
+ST_FN void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
+{
+    const char *start_symbol;
+    unsigned long addr = 0;
+    int pe_type = 0;
+
+    if (find_elf_sym(symtab_section, "_WinMain@16"))
+        pe_type = PE_GUI;
+    else
+    if (TCC_OUTPUT_DLL == s1->output_type) {
+        pe_type = PE_DLL;
+        /* need this for 'tccelf.c:relocate_section()' */
+        s1->output_type = TCC_OUTPUT_EXE;
+    }
+
+    start_symbol =
+        TCC_OUTPUT_MEMORY == s1->output_type
+        ? PE_GUI == pe_type ? "_runwinmain" : NULL
+        : PE_DLL == pe_type ? "__dllstart@12"
+        : PE_GUI == pe_type ? "_winstart" : "_start"
+        ;
+
+    /* grab the startup code from libtcc1 */
+    if (start_symbol)
+        add_elf_sym(symtab_section,
+            0, 0,
+            ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
+            SHN_UNDEF, start_symbol);
+
+    if (0 == s1->nostdlib) {
+        tcc_add_library(s1, "tcc1");
+#ifdef __CYGWIN__
+        tcc_add_library(s1, "cygwin1");
+#else
+        tcc_add_library(s1, "msvcrt");
+#endif
+        tcc_add_library(s1, "kernel32");
+        if (PE_DLL == pe_type || PE_GUI == pe_type) {
+            tcc_add_library(s1, "user32");
+            tcc_add_library(s1, "gdi32");
+        }
+    }
+
+    if (start_symbol) {
+        addr = (unsigned long)tcc_get_symbol_err(s1, start_symbol);
+        if (s1->output_type == TCC_OUTPUT_MEMORY && addr)
+            /* for -run GUI's, put '_runwinmain' instead of 'main' */
+            add_elf_sym(symtab_section,
+                    addr, 0,
+                    ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
+                    text_section->sh_num, "main");
+    }
+
+    if (pe) {
+        pe->type = pe_type;
+        pe->start_addr = addr;
+    }
+}
+
+PUB_FN void pe_add_runtime(TCCState *s1)
+{
+    pe_add_runtime_ex(s1, NULL);
+}
+
+PUB_FN int pe_output_file(TCCState * s1, const char *filename)
+{
+    int ret;
+    struct pe_info pe;
+    int i;
+
+    memset(&pe, 0, sizeof pe);
+    pe.filename = filename;
+    pe.s1 = s1;
+
+    pe_add_runtime_ex(s1, &pe);
+    relocate_common_syms(); /* assign bss adresses */
+    tcc_add_linker_symbols(s1);
+
+    ret = pe_check_symbols(&pe);
+    if (0 == ret) {
+        if (PE_DLL == pe.type) {
+            pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
+            pe.imagebase = 0x10000000;
+        } else {
+            pe.imagebase = 0x00400000;
+        }
+        pe_assign_addresses(&pe);
+        relocate_syms(s1, 0);
+        for (i = 1; i < s1->nb_sections; ++i) {
+            Section *s = s1->sections[i];
+            if (s->reloc) {
+                relocate_section(s1, s);
+                pe_relocate_rva(&pe, s);
+            }
+        }
+        if (s1->nb_errors)
+            ret = 1;
+        else
+            ret = pe_write(&pe);
+        tcc_free(pe.sec_info);
+    }
+
+#ifdef PE_PRINT_SECTIONS
+    pe_print_sections(s1, "tcc.log");
+#endif
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+#endif /* def TCC_TARGET_PE */
+/* ------------------------------------------------------------- */
diff --git a/tinyc/tccpp.c b/tinyc/tccpp.c
new file mode 100755
index 000000000..ff17d8bed
--- /dev/null
+++ b/tinyc/tccpp.c
@@ -0,0 +1,2935 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+static const char tcc_keywords[] = 
+#define DEF(id, str) str "\0"
+#include "tcctok.h"
+#undef DEF
+;
+
+/* WARNING: the content of this string encodes token numbers */
+static 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);
+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);
+
+
+/* allocate a new token */
+static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
+{
+    TokenSym *ts, **ptable;
+    int i;
+
+    if (tok_ident >= SYM_FIRST_ANOM) 
+        error("memory full");
+
+    /* expand token table if needed */
+    i = tok_ident - TOK_IDENT;
+    if ((i % TOK_ALLOC_INCR) == 0) {
+        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
+        if (!ptable)
+            error("memory full");
+        table_ident = ptable;
+    }
+
+    ts = tcc_malloc(sizeof(TokenSym) + len);
+    table_ident[i] = ts;
+    ts->tok = tok_ident++;
+    ts->sym_define = NULL;
+    ts->sym_label = NULL;
+    ts->sym_struct = NULL;
+    ts->sym_identifier = NULL;
+    ts->len = len;
+    ts->hash_next = NULL;
+    memcpy(ts->str, str, len);
+    ts->str[len] = '\0';
+    *pts = ts;
+    return ts;
+}
+
+#define TOK_HASH_INIT 1
+#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)
+{
+    TokenSym *ts, **pts;
+    int i;
+    unsigned int h;
+    
+    h = TOK_HASH_INIT;
+    for(i=0;i<len;i++)
+        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
+    h &= (TOK_HASH_SIZE - 1);
+
+    pts = &hash_ident[h];
+    for(;;) {
+        ts = *pts;
+        if (!ts)
+            break;
+        if (ts->len == len && !memcmp(ts->str, str, len))
+            return ts;
+        pts = &(ts->hash_next);
+    }
+    return tok_alloc_new(pts, str, len);
+}
+
+/* XXX: buffer overflow */
+/* XXX: float tokens */
+char *get_tok_str(int v, CValue *cv)
+{
+    static char buf[STRING_MAX_SIZE + 1];
+    static CString cstr_buf;
+    CString *cstr;
+    unsigned char *q;
+    char *p;
+    int i, len;
+
+    /* NOTE: to go faster, we give a fixed buffer for small strings */
+    cstr_reset(&cstr_buf);
+    cstr_buf.data = buf;
+    cstr_buf.size_allocated = sizeof(buf);
+    p = buf;
+
+    switch(v) {
+    case TOK_CINT:
+    case TOK_CUINT:
+        /* XXX: not quite exact, but only useful for testing */
+        sprintf(p, "%u", cv->ui);
+        break;
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+        /* XXX: not quite exact, but only useful for testing  */
+        sprintf(p, "%Lu", cv->ull);
+        break;
+    case TOK_LCHAR:
+        cstr_ccat(&cstr_buf, 'L');
+    case TOK_CCHAR:
+        cstr_ccat(&cstr_buf, '\'');
+        add_char(&cstr_buf, cv->i);
+        cstr_ccat(&cstr_buf, '\'');
+        cstr_ccat(&cstr_buf, '\0');
+        break;
+    case TOK_PPNUM:
+        cstr = cv->cstr;
+        len = cstr->size - 1;
+        for(i=0;i<len;i++)
+            add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
+        cstr_ccat(&cstr_buf, '\0');
+        break;
+    case TOK_LSTR:
+        cstr_ccat(&cstr_buf, 'L');
+    case TOK_STR:
+        cstr = cv->cstr;
+        cstr_ccat(&cstr_buf, '\"');
+        if (v == TOK_STR) {
+            len = cstr->size - 1;
+            for(i=0;i<len;i++)
+                add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
+        } else {
+            len = (cstr->size / sizeof(nwchar_t)) - 1;
+            for(i=0;i<len;i++)
+                add_char(&cstr_buf, ((nwchar_t *)cstr->data)[i]);
+        }
+        cstr_ccat(&cstr_buf, '\"');
+        cstr_ccat(&cstr_buf, '\0');
+        break;
+    case TOK_LT:
+        v = '<';
+        goto addv;
+    case TOK_GT:
+        v = '>';
+        goto addv;
+    case TOK_DOTS:
+        return strcpy(p, "...");
+    case TOK_A_SHL:
+        return strcpy(p, "<<=");
+    case TOK_A_SAR:
+        return strcpy(p, ">>=");
+    default:
+        if (v < TOK_IDENT) {
+            /* search in two bytes table */
+            q = tok_two_chars;
+            while (*q) {
+                if (q[2] == v) {
+                    *p++ = q[0];
+                    *p++ = q[1];
+                    *p = '\0';
+                    return buf;
+                }
+                q += 3;
+            }
+        addv:
+            *p++ = v;
+            *p = '\0';
+        } else if (v < tok_ident) {
+            return table_ident[v - TOK_IDENT]->str;
+        } else if (v >= SYM_FIRST_ANOM) {
+            /* special name for anonymous symbol */
+            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
+        } else {
+            /* should never happen */
+            return NULL;
+        }
+        break;
+    }
+    return cstr_buf.data;
+}
+
+/* fill input buffer and peek next char */
+static int tcc_peekc_slow(BufferedFile *bf)
+{
+    int len;
+    /* only tries to read if really end of buffer */
+    if (bf->buf_ptr >= bf->buf_end) {
+        if (bf->fd != -1) {
+#if defined(PARSE_DEBUG)
+            len = 8;
+#else
+            len = IO_BUF_SIZE;
+#endif
+            len = read(bf->fd, bf->buffer, len);
+            if (len < 0)
+                len = 0;
+        } else {
+            len = 0;
+        }
+        total_bytes += len;
+        bf->buf_ptr = bf->buffer;
+        bf->buf_end = bf->buffer + len;
+        *bf->buf_end = CH_EOB;
+    }
+    if (bf->buf_ptr < bf->buf_end) {
+        return bf->buf_ptr[0];
+    } else {
+        bf->buf_ptr = bf->buf_end;
+        return CH_EOF;
+    }
+}
+
+/* return the current character, handling end of block if necessary
+   (but not stray) */
+static 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)
+{
+    ch = *(++(file->buf_ptr));
+    /* end of buffer/file handling */
+    if (ch == CH_EOB)
+        ch = handle_eob();
+}
+
+/* handle '\[\r]\n' */
+static int handle_stray_noerror(void)
+{
+    while (ch == '\\') {
+        inp();
+        if (ch == '\n') {
+            file->line_num++;
+            inp();
+        } else if (ch == '\r') {
+            inp();
+            if (ch != '\n')
+                goto fail;
+            file->line_num++;
+            inp();
+        } else {
+        fail:
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static void handle_stray(void)
+{
+    if (handle_stray_noerror())
+        error("stray '\\' in program");
+}
+
+/* skip the stray and handle the \\n case. Output an error if
+   incorrect char after the stray */
+static int handle_stray1(uint8_t *p)
+{
+    int c;
+
+    if (p >= file->buf_end) {
+        file->buf_ptr = p;
+        c = handle_eob();
+        p = file->buf_ptr;
+        if (c == '\\')
+            goto parse_stray;
+    } else {
+    parse_stray:
+        file->buf_ptr = p;
+        ch = *p;
+        handle_stray();
+        p = file->buf_ptr;
+        c = *p;
+    }
+    return c;
+}
+
+/* handle just the EOB case, but not stray */
+#define PEEKC_EOB(c, p)\
+{\
+    p++;\
+    c = *p;\
+    if (c == '\\') {\
+        file->buf_ptr = p;\
+        c = handle_eob();\
+        p = file->buf_ptr;\
+    }\
+}
+
+/* handle the complicated stray case */
+#define PEEKC(c, p)\
+{\
+    p++;\
+    c = *p;\
+    if (c == '\\') {\
+        c = handle_stray1(p);\
+        p = file->buf_ptr;\
+    }\
+}
+
+/* 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)
+{
+    inp();
+    if (ch == '\\') 
+        handle_stray();
+}
+
+
+/* single line C++ comments */
+static uint8_t *parse_line_comment(uint8_t *p)
+{
+    int c;
+
+    p++;
+    for(;;) {
+        c = *p;
+    redo:
+        if (c == '\n' || c == CH_EOF) {
+            break;
+        } else if (c == '\\') {
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == '\\') {
+                PEEKC_EOB(c, p);
+                if (c == '\n') {
+                    file->line_num++;
+                    PEEKC_EOB(c, p);
+                } else if (c == '\r') {
+                    PEEKC_EOB(c, p);
+                    if (c == '\n') {
+                        file->line_num++;
+                        PEEKC_EOB(c, p);
+                    }
+                }
+            } else {
+                goto redo;
+            }
+        } else {
+            p++;
+        }
+    }
+    return p;
+}
+
+/* C comments */
+static uint8_t *parse_comment(uint8_t *p)
+{
+    int c;
+    
+    p++;
+    for(;;) {
+        /* fast skip loop */
+        for(;;) {
+            c = *p;
+            if (c == '\n' || c == '*' || c == '\\')
+                break;
+            p++;
+            c = *p;
+            if (c == '\n' || c == '*' || c == '\\')
+                break;
+            p++;
+        }
+        /* now we can handle all the cases */
+        if (c == '\n') {
+            file->line_num++;
+            p++;
+        } else if (c == '*') {
+            p++;
+            for(;;) {
+                c = *p;
+                if (c == '*') {
+                    p++;
+                } else if (c == '/') {
+                    goto end_of_comment;
+                } else if (c == '\\') {
+                    file->buf_ptr = p;
+                    c = handle_eob();
+                    p = file->buf_ptr;
+                    if (c == '\\') {
+                        /* skip '\[\r]\n', otherwise just skip the stray */
+                        while (c == '\\') {
+                            PEEKC_EOB(c, p);
+                            if (c == '\n') {
+                                file->line_num++;
+                                PEEKC_EOB(c, p);
+                            } else if (c == '\r') {
+                                PEEKC_EOB(c, p);
+                                if (c == '\n') {
+                                    file->line_num++;
+                                    PEEKC_EOB(c, p);
+                                }
+                            } else {
+                                goto after_star;
+                            }
+                        }
+                    }
+                } else {
+                    break;
+                }
+            }
+        after_star: ;
+        } else {
+            /* stray, eob or eof */
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == CH_EOF) {
+                error("unexpected end of file in comment");
+            } else if (c == '\\') {
+                p++;
+            }
+        }
+    }
+ end_of_comment:
+    p++;
+    return p;
+}
+
+#define cinp minp
+
+static inline void skip_spaces(void)
+{
+    while (is_space(ch))
+        cinp();
+}
+
+static inline int check_space(int t, int *spc) 
+{
+    if (is_space(t)) {
+        if (*spc) 
+            return 1;
+        *spc = 1;
+    } else 
+        *spc = 0;
+    return 0;
+}
+
+/* parse a string without interpreting escapes */
+static uint8_t *parse_pp_string(uint8_t *p,
+                                int sep, CString *str)
+{
+    int c;
+    p++;
+    for(;;) {
+        c = *p;
+        if (c == sep) {
+            break;
+        } else if (c == '\\') {
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == CH_EOF) {
+            unterminated_string:
+                /* XXX: indicate line number of start of string */
+                error("missing terminating %c character", sep);
+            } else if (c == '\\') {
+                /* escape : just skip \[\r]\n */
+                PEEKC_EOB(c, p);
+                if (c == '\n') {
+                    file->line_num++;
+                    p++;
+                } else if (c == '\r') {
+                    PEEKC_EOB(c, p);
+                    if (c != '\n')
+                        expect("'\n' after '\r'");
+                    file->line_num++;
+                    p++;
+                } else if (c == CH_EOF) {
+                    goto unterminated_string;
+                } else {
+                    if (str) {
+                        cstr_ccat(str, '\\');
+                        cstr_ccat(str, c);
+                    }
+                    p++;
+                }
+            }
+        } else if (c == '\n') {
+            file->line_num++;
+            goto add_char;
+        } else if (c == '\r') {
+            PEEKC_EOB(c, p);
+            if (c != '\n') {
+                if (str)
+                    cstr_ccat(str, '\r');
+            } else {
+                file->line_num++;
+                goto add_char;
+            }
+        } else {
+        add_char:
+            if (str)
+                cstr_ccat(str, c);
+            p++;
+        }
+    }
+    p++;
+    return p;
+}
+
+/* skip block of text until #else, #elif or #endif. skip also pairs of
+   #if/#endif */
+void preprocess_skip(void)
+{
+    int a, start_of_line, c, in_warn_or_error;
+    uint8_t *p;
+
+    p = file->buf_ptr;
+    a = 0;
+redo_start:
+    start_of_line = 1;
+    in_warn_or_error = 0;
+    for(;;) {
+    redo_no_start:
+        c = *p;
+        switch(c) {
+        case ' ':
+        case '\t':
+        case '\f':
+        case '\v':
+        case '\r':
+            p++;
+            goto redo_no_start;
+        case '\n':
+            file->line_num++;
+            p++;
+            goto redo_start;
+        case '\\':
+            file->buf_ptr = p;
+            c = handle_eob();
+            if (c == CH_EOF) {
+                expect("#endif");
+            } else if (c == '\\') {
+                ch = file->buf_ptr[0];
+                handle_stray_noerror();
+            }
+            p = file->buf_ptr;
+            goto redo_no_start;
+        /* skip strings */
+        case '\"':
+        case '\'':
+            if (in_warn_or_error)
+                goto _default;
+            p = parse_pp_string(p, c, NULL);
+            break;
+        /* skip comments */
+        case '/':
+            if (in_warn_or_error)
+                goto _default;
+            file->buf_ptr = p;
+            ch = *p;
+            minp();
+            p = file->buf_ptr;
+            if (ch == '*') {
+                p = parse_comment(p);
+            } else if (ch == '/') {
+                p = parse_line_comment(p);
+            }
+            break;
+        case '#':
+            p++;
+            if (start_of_line) {
+                file->buf_ptr = p;
+                next_nomacro();
+                p = file->buf_ptr;
+                if (a == 0 && 
+                    (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
+                    goto the_end;
+                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
+                    a++;
+                else if (tok == TOK_ENDIF)
+                    a--;
+                else if( tok == TOK_ERROR || tok == TOK_WARNING)
+                    in_warn_or_error = 1;
+            }
+            break;
+_default:
+        default:
+            p++;
+            break;
+        }
+        start_of_line = 0;
+    }
+ the_end: ;
+    file->buf_ptr = p;
+}
+
+/* ParseState handling */
+
+/* XXX: currently, no include file info is stored. Thus, we cannot display
+   accurate messages if the function or data definition spans multiple
+   files */
+
+/* save current parse state in 's' */
+void save_parse_state(ParseState *s)
+{
+    s->line_num = file->line_num;
+    s->macro_ptr = macro_ptr;
+    s->tok = tok;
+    s->tokc = tokc;
+}
+
+/* restore parse state from 's' */
+void restore_parse_state(ParseState *s)
+{
+    file->line_num = s->line_num;
+    macro_ptr = s->macro_ptr;
+    tok = s->tok;
+    tokc = s->tokc;
+}
+
+/* return the number of additional 'ints' necessary to store the
+   token */
+static inline int tok_ext_size(int t)
+{
+    switch(t) {
+        /* 4 bytes */
+    case TOK_CINT:
+    case TOK_CUINT:
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+    case TOK_CFLOAT:
+    case TOK_LINENUM:
+        return 1;
+    case TOK_STR:
+    case TOK_LSTR:
+    case TOK_PPNUM:
+        error("unsupported token");
+        return 1;
+    case TOK_CDOUBLE:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+        return 2;
+    case TOK_CLDOUBLE:
+        return LDOUBLE_SIZE / 4;
+    default:
+        return 0;
+    }
+}
+
+/* token string handling */
+
+static inline void tok_str_new(TokenString *s)
+{
+    s->str = NULL;
+    s->len = 0;
+    s->allocated_len = 0;
+    s->last_line_num = -1;
+}
+
+static void tok_str_free(int *str)
+{
+    tcc_free(str);
+}
+
+static int *tok_str_realloc(TokenString *s)
+{
+    int *str, len;
+
+    if (s->allocated_len == 0) {
+        len = 8;
+    } else {
+        len = s->allocated_len * 2;
+    }
+    str = tcc_realloc(s->str, len * sizeof(int));
+    if (!str)
+        error("memory full");
+    s->allocated_len = len;
+    s->str = str;
+    return str;
+}
+
+static void tok_str_add(TokenString *s, int t)
+{
+    int len, *str;
+
+    len = s->len;
+    str = s->str;
+    if (len >= s->allocated_len)
+        str = tok_str_realloc(s);
+    str[len++] = t;
+    s->len = len;
+}
+
+static void tok_str_add2(TokenString *s, int t, CValue *cv)
+{
+    int len, *str;
+
+    len = s->len;
+    str = s->str;
+
+    /* allocate space for worst case */
+    if (len + TOK_MAX_SIZE > s->allocated_len)
+        str = tok_str_realloc(s);
+    str[len++] = t;
+    switch(t) {
+    case TOK_CINT:
+    case TOK_CUINT:
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+    case TOK_CFLOAT:
+    case TOK_LINENUM:
+        str[len++] = cv->tab[0];
+        break;
+    case TOK_PPNUM:
+    case TOK_STR:
+    case TOK_LSTR:
+        {
+            int nb_words;
+            CString *cstr;
+
+            nb_words = (sizeof(CString) + cv->cstr->size + 3) >> 2;
+            while ((len + nb_words) > s->allocated_len)
+                str = tok_str_realloc(s);
+            cstr = (CString *)(str + len);
+            cstr->data = NULL;
+            cstr->size = cv->cstr->size;
+            cstr->data_allocated = NULL;
+            cstr->size_allocated = cstr->size;
+            memcpy((char *)cstr + sizeof(CString), 
+                   cv->cstr->data, cstr->size);
+            len += nb_words;
+        }
+        break;
+    case TOK_CDOUBLE:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+#if LDOUBLE_SIZE == 8
+    case TOK_CLDOUBLE:
+#endif
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        break;
+#if LDOUBLE_SIZE == 12
+    case TOK_CLDOUBLE:
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        str[len++] = cv->tab[2];
+#elif LDOUBLE_SIZE == 16
+    case TOK_CLDOUBLE:
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        str[len++] = cv->tab[2];
+        str[len++] = cv->tab[3];
+#elif LDOUBLE_SIZE != 8
+#error add long double size support
+#endif
+        break;
+    default:
+        break;
+    }
+    s->len = len;
+}
+
+/* add the current parse token in token string 's' */
+static void tok_str_add_tok(TokenString *s)
+{
+    CValue cval;
+
+    /* save line number info */
+    if (file->line_num != s->last_line_num) {
+        s->last_line_num = file->line_num;
+        cval.i = s->last_line_num;
+        tok_str_add2(s, TOK_LINENUM, &cval);
+    }
+    tok_str_add2(s, tok, &tokc);
+}
+
+#if LDOUBLE_SIZE == 16
+#define LDOUBLE_GET(p, cv)                      \
+        cv.tab[0] = p[0];                       \
+        cv.tab[1] = p[1];                       \
+        cv.tab[2] = p[2];                       \
+        cv.tab[3] = p[3];
+#elif LDOUBLE_SIZE == 12
+#define LDOUBLE_GET(p, cv)                      \
+        cv.tab[0] = p[0];                       \
+        cv.tab[1] = p[1];                       \
+        cv.tab[2] = p[2];
+#elif LDOUBLE_SIZE == 8
+#define LDOUBLE_GET(p, cv)                      \
+        cv.tab[0] = p[0];                       \
+        cv.tab[1] = p[1];
+#else
+#error add long double size support
+#endif
+
+
+/* get a token from an integer array and increment pointer
+   accordingly. we code it as a macro to avoid pointer aliasing. */
+#define TOK_GET(t, p, cv)                       \
+{                                               \
+    t = *p++;                                   \
+    switch(t) {                                 \
+    case TOK_CINT:                              \
+    case TOK_CUINT:                             \
+    case TOK_CCHAR:                             \
+    case TOK_LCHAR:                             \
+    case TOK_CFLOAT:                            \
+    case TOK_LINENUM:                           \
+        cv.tab[0] = *p++;                       \
+        break;                                  \
+    case TOK_STR:                               \
+    case TOK_LSTR:                              \
+    case TOK_PPNUM:                             \
+        cv.cstr = (CString *)p;                 \
+        cv.cstr->data = (char *)p + sizeof(CString);\
+        p += (sizeof(CString) + cv.cstr->size + 3) >> 2;\
+        break;                                  \
+    case TOK_CDOUBLE:                           \
+    case TOK_CLLONG:                            \
+    case TOK_CULLONG:                           \
+        cv.tab[0] = p[0];                       \
+        cv.tab[1] = p[1];                       \
+        p += 2;                                 \
+        break;                                  \
+    case TOK_CLDOUBLE:                          \
+        LDOUBLE_GET(p, cv);                     \
+        p += LDOUBLE_SIZE / 4;                  \
+        break;                                  \
+    default:                                    \
+        break;                                  \
+    }                                           \
+}
+
+/* defines handling */
+static inline void define_push(int v, int macro_type, int *str, Sym *first_arg)
+{
+    Sym *s;
+
+    s = sym_push2(&define_stack, v, macro_type, (long)str);
+    s->next = first_arg;
+    table_ident[v - TOK_IDENT]->sym_define = s;
+}
+
+/* undefined a define symbol. Its name is just set to zero */
+static void define_undef(Sym *s)
+{
+    int v;
+    v = s->v;
+    if (v >= TOK_IDENT && v < tok_ident)
+        table_ident[v - TOK_IDENT]->sym_define = NULL;
+    s->v = 0;
+}
+
+static inline Sym *define_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_define;
+}
+
+/* free define stack until top reaches 'b' */
+static void free_defines(Sym *b)
+{
+    Sym *top, *top1;
+    int v;
+
+    top = define_stack;
+    while (top != b) {
+        top1 = top->prev;
+        /* do not free args or predefined defines */
+        if (top->c)
+            tok_str_free((int *)top->c);
+        v = top->v;
+        if (v >= TOK_IDENT && v < tok_ident)
+            table_ident[v - TOK_IDENT]->sym_define = NULL;
+        sym_free(top);
+        top = top1;
+    }
+    define_stack = b;
+}
+
+/* label lookup */
+static Sym *label_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_label;
+}
+
+static Sym *label_push(Sym **ptop, int v, int flags)
+{
+    Sym *s, **ps;
+    s = sym_push2(ptop, v, 0, 0);
+    s->r = flags;
+    ps = &table_ident[v - TOK_IDENT]->sym_label;
+    if (ptop == &global_label_stack) {
+        /* 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 = *ps;
+    *ps = s;
+    return s;
+}
+
+/* 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)
+{
+    Sym *s, *s1;
+    for(s = *ptop; s != slast; s = s1) {
+        s1 = s->prev;
+        if (s->r == LABEL_DECLARED) {
+            warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
+        } else if (s->r == LABEL_FORWARD) {
+                error("label '%s' used but not defined",
+                      get_tok_str(s->v, NULL));
+        } else {
+            if (s->c) {
+                /* define corresponding symbol. A size of
+                   1 is put. */
+                put_extern_sym(s, cur_text_section, (long)s->next, 1);
+            }
+        }
+        /* remove label */
+        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
+        sym_free(s);
+    }
+    *ptop = slast;
+}
+
+/* eval an expression for #if/#elif */
+static int expr_preprocess(void)
+{
+    int c, t;
+    TokenString str;
+    
+    tok_str_new(&str);
+    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+        next(); /* do macro subst */
+        if (tok == TOK_DEFINED) {
+            next_nomacro();
+            t = tok;
+            if (t == '(') 
+                next_nomacro();
+            c = define_find(tok) != 0;
+            if (t == '(')
+                next_nomacro();
+            tok = TOK_CINT;
+            tokc.i = c;
+        } else if (tok >= TOK_IDENT) {
+            /* if undefined macro */
+            tok = TOK_CINT;
+            tokc.i = 0;
+        }
+        tok_str_add_tok(&str);
+    }
+    tok_str_add(&str, -1); /* simulate end of file */
+    tok_str_add(&str, 0);
+    /* now evaluate C constant expression */
+    macro_ptr = str.str;
+    next();
+    c = expr_const();
+    macro_ptr = NULL;
+    tok_str_free(str.str);
+    return c != 0;
+}
+
+#if defined(PARSE_DEBUG) || defined(PP_DEBUG)
+static void tok_print(int *str)
+{
+    int t;
+    CValue cval;
+
+    printf("<");
+    while (1) {
+        TOK_GET(t, str, cval);
+        if (!t)
+            break;
+        printf("%s", get_tok_str(t, &cval));
+    }
+    printf(">\n");
+}
+#endif
+
+/* parse after #define */
+static void parse_define(void)
+{
+    Sym *s, *first, **ps;
+    int v, t, varg, is_vaargs, spc;
+    TokenString str;
+    
+    v = tok;
+    if (v < TOK_IDENT)
+        error("invalid macro name '%s'", get_tok_str(tok, &tokc));
+    /* XXX: should check if same macro (ANSI) */
+    first = NULL;
+    t = MACRO_OBJ;
+    /* '(' must be just after macro definition for MACRO_FUNC */
+    next_nomacro_spc();
+    if (tok == '(') {
+        next_nomacro();
+        ps = &first;
+        while (tok != ')') {
+            varg = tok;
+            next_nomacro();
+            is_vaargs = 0;
+            if (varg == TOK_DOTS) {
+                varg = TOK___VA_ARGS__;
+                is_vaargs = 1;
+            } else if (tok == TOK_DOTS && gnu_ext) {
+                is_vaargs = 1;
+                next_nomacro();
+            }
+            if (varg < TOK_IDENT)
+                error("badly punctuated parameter list");
+            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
+            *ps = s;
+            ps = &s->next;
+            if (tok != ',')
+                break;
+            next_nomacro();
+        }
+        if (tok == ')')
+            next_nomacro_spc();
+        t = MACRO_FUNC;
+    }
+    tok_str_new(&str);
+    spc = 2;
+    /* EOF testing necessary for '-D' handling */
+    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+        /* remove spaces around ## and after '#' */        
+        if (TOK_TWOSHARPS == tok) {
+            if (1 == spc)
+                --str.len;
+            spc = 2;
+        } else if ('#' == tok) {
+            spc = 2;
+        } else if (check_space(tok, &spc)) {
+            goto skip;
+        }
+        tok_str_add2(&str, tok, &tokc);
+    skip:
+        next_nomacro_spc();
+    }
+    if (spc == 1)
+        --str.len; /* remove trailing space */
+    tok_str_add(&str, 0);
+#ifdef PP_DEBUG
+    printf("define %s %d: ", get_tok_str(v, NULL), t);
+    tok_print(str.str);
+#endif
+    define_push(v, t, str.str, first);
+}
+
+static inline int hash_cached_include(int type, const char *filename)
+{
+    const unsigned char *s;
+    unsigned int h;
+
+    h = TOK_HASH_INIT;
+    h = TOK_HASH_FUNC(h, type);
+    s = filename;
+    while (*s) {
+        h = TOK_HASH_FUNC(h, *s);
+        s++;
+    }
+    h &= (CACHED_INCLUDES_HASH_SIZE - 1);
+    return h;
+}
+
+/* XXX: use a token or a hash table to accelerate matching ? */
+static CachedInclude *search_cached_include(TCCState *s1,
+                                            int type, const char *filename)
+{
+    CachedInclude *e;
+    int i, h;
+    h = hash_cached_include(type, filename);
+    i = s1->cached_includes_hash[h];
+    for(;;) {
+        if (i == 0)
+            break;
+        e = s1->cached_includes[i - 1];
+        if (e->type == type && !PATHCMP(e->filename, filename))
+            return e;
+        i = e->hash_next;
+    }
+    return NULL;
+}
+
+static inline void add_cached_include(TCCState *s1, int type, 
+                                      const char *filename, int ifndef_macro)
+{
+    CachedInclude *e;
+    int h;
+
+    if (search_cached_include(s1, type, filename))
+        return;
+#ifdef INC_DEBUG
+    printf("adding cached '%s' %s\n", filename, get_tok_str(ifndef_macro, NULL));
+#endif
+    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
+    if (!e)
+        return;
+    e->type = type;
+    strcpy(e->filename, filename);
+    e->ifndef_macro = ifndef_macro;
+    dynarray_add((void ***)&s1->cached_includes, &s1->nb_cached_includes, e);
+    /* add in hash table */
+    h = hash_cached_include(type, filename);
+    e->hash_next = s1->cached_includes_hash[h];
+    s1->cached_includes_hash[h] = s1->nb_cached_includes;
+}
+
+static void pragma_parse(TCCState *s1)
+{
+    int val;
+
+    next();
+    if (tok == TOK_pack) {
+        /*
+          This may be:
+          #pragma pack(1) // set
+          #pragma pack() // reset to default
+          #pragma pack(push,1) // push & set
+          #pragma pack(pop) // restore previous
+        */
+        next();
+        skip('(');
+        if (tok == TOK_ASM_pop) {
+            next();
+            if (s1->pack_stack_ptr <= s1->pack_stack) {
+            stk_error:
+                error("out of pack stack");
+            }
+            s1->pack_stack_ptr--;
+        } else {
+            val = 0;
+            if (tok != ')') {
+                if (tok == TOK_ASM_push) {
+                    next();
+                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
+                        goto stk_error;
+                    s1->pack_stack_ptr++;
+                    skip(',');
+                }
+                if (tok != TOK_CINT) {
+                pack_error:
+                    error("invalid pack pragma");
+                }
+                val = tokc.i;
+                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
+                    goto pack_error;
+                next();
+            }
+            *s1->pack_stack_ptr = val;
+            skip(')');
+        }
+    }
+}
+
+/* is_bof is true if first non space token at beginning of file */
+static void preprocess(int is_bof)
+{
+    TCCState *s1 = tcc_state;
+    int i, c, n, saved_parse_flags;
+    char buf[1024], *q;
+    Sym *s;
+
+    saved_parse_flags = parse_flags;
+    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | 
+        PARSE_FLAG_LINEFEED;
+    next_nomacro();
+ redo:
+    switch(tok) {
+    case TOK_DEFINE:
+        next_nomacro();
+        parse_define();
+        break;
+    case TOK_UNDEF:
+        next_nomacro();
+        s = define_find(tok);
+        /* undefine symbol by putting an invalid name */
+        if (s)
+            define_undef(s);
+        break;
+    case TOK_INCLUDE:
+    case TOK_INCLUDE_NEXT:
+        ch = file->buf_ptr[0];
+        /* XXX: incorrect if comments : use next_nomacro with a special mode */
+        skip_spaces();
+        if (ch == '<') {
+            c = '>';
+            goto read_name;
+        } else if (ch == '\"') {
+            c = ch;
+        read_name:
+            inp();
+            q = buf;
+            while (ch != c && ch != '\n' && ch != CH_EOF) {
+                if ((q - buf) < sizeof(buf) - 1)
+                    *q++ = ch;
+                if (ch == '\\') {
+                    if (handle_stray_noerror() == 0)
+                        --q;
+                } else
+                    inp();
+            }
+            *q = '\0';
+            minp();
+#if 0
+            /* eat all spaces and comments after include */
+            /* XXX: slightly incorrect */
+            while (ch1 != '\n' && ch1 != CH_EOF)
+                inp();
+#endif
+        } else {
+            /* computed #include : either we have only strings or
+               we have anything enclosed in '<>' */
+            next();
+            buf[0] = '\0';
+            if (tok == TOK_STR) {
+                while (tok != TOK_LINEFEED) {
+                    if (tok != TOK_STR) {
+                    include_syntax:
+                        error("'#include' expects \"FILENAME\" or <FILENAME>");
+                    }
+                    pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
+                    next();
+                }
+                c = '\"';
+            } else {
+                int len;
+                while (tok != TOK_LINEFEED) {
+                    pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
+                    next();
+                }
+                len = strlen(buf);
+                /* check syntax and remove '<>' */
+                if (len < 2 || buf[0] != '<' || buf[len - 1] != '>')
+                    goto include_syntax;
+                memmove(buf, buf + 1, len - 2);
+                buf[len - 2] = '\0';
+                c = '>';
+            }
+        }
+
+        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
+            error("#include recursion too deep");
+
+        n = s1->nb_include_paths + s1->nb_sysinclude_paths;
+        for (i = -2; i < n; ++i) {
+            char buf1[sizeof file->filename];
+            BufferedFile *f;
+            CachedInclude *e;
+            const char *path;
+            int size;
+
+            if (i == -2) {
+                /* check absolute include path */
+                if (!IS_ABSPATH(buf))
+                    continue;
+                buf1[0] = 0;
+
+            } else if (i == -1) {
+                /* search in current dir if "header.h" */
+                if (c != '\"')
+                    continue;
+                size = tcc_basename(file->filename) - file->filename;
+                memcpy(buf1, file->filename, size);
+                buf1[size] = '\0';
+
+            } else {
+                /* search in all the include paths */
+                if (i < s1->nb_include_paths)
+                    path = s1->include_paths[i];
+                else
+                    path = s1->sysinclude_paths[i - s1->nb_include_paths];
+                pstrcpy(buf1, sizeof(buf1), path);
+                pstrcat(buf1, sizeof(buf1), "/");
+            }
+
+            pstrcat(buf1, sizeof(buf1), buf);
+
+            e = search_cached_include(s1, c, buf1);
+            if (e && define_find(e->ifndef_macro)) {
+                /* no need to parse the include because the 'ifndef macro'
+                   is defined */
+#ifdef INC_DEBUG
+                printf("%s: skipping %s\n", file->filename, buf);
+#endif
+                f = NULL;
+            }  else {
+                f = tcc_open(s1, buf1);
+                if (!f)
+                    continue;
+            }
+
+            if (tok == TOK_INCLUDE_NEXT) {
+                tok = TOK_INCLUDE;
+                if (f)
+                    tcc_close(f);
+                continue;
+            }
+
+            if (!f)
+                goto include_done;
+
+#ifdef INC_DEBUG
+            printf("%s: including %s\n", file->filename, buf1);
+#endif
+
+           /* XXX: fix current line init */
+           /* push current file in stack */
+            *s1->include_stack_ptr++ = file;
+            f->inc_type = c;
+            pstrcpy(f->inc_filename, sizeof(f->inc_filename), buf1);
+            file = f;
+            /* add include file debug info */
+            if (tcc_state->do_debug) {
+                put_stabs(file->filename, N_BINCL, 0, 0, 0);
+            }
+            tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
+            ch = file->buf_ptr[0];
+            goto the_end;
+        }
+        error("include file '%s' not found", buf);
+include_done:
+        break;
+    case TOK_IFNDEF:
+        c = 1;
+        goto do_ifdef;
+    case TOK_IF:
+        c = expr_preprocess();
+        goto do_if;
+    case TOK_IFDEF:
+        c = 0;
+    do_ifdef:
+        next_nomacro();
+        if (tok < TOK_IDENT)
+            error("invalid argument for '#if%sdef'", c ? "n" : "");
+        if (is_bof) {
+            if (c) {
+#ifdef INC_DEBUG
+                printf("#ifndef %s\n", get_tok_str(tok, NULL));
+#endif
+                file->ifndef_macro = tok;
+            }
+        }
+        c = (define_find(tok) != 0) ^ c;
+    do_if:
+        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
+            error("memory full");
+        *s1->ifdef_stack_ptr++ = c;
+        goto test_skip;
+    case TOK_ELSE:
+        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+            error("#else without matching #if");
+        if (s1->ifdef_stack_ptr[-1] & 2)
+            error("#else after #else");
+        c = (s1->ifdef_stack_ptr[-1] ^= 3);
+        goto test_skip;
+    case TOK_ELIF:
+        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+            error("#elif without matching #if");
+        c = s1->ifdef_stack_ptr[-1];
+        if (c > 1)
+            error("#elif after #else");
+        /* last #if/#elif expression was true: we skip */
+        if (c == 1)
+            goto skip;
+        c = expr_preprocess();
+        s1->ifdef_stack_ptr[-1] = c;
+    test_skip:
+        if (!(c & 1)) {
+        skip:
+            preprocess_skip();
+            is_bof = 0;
+            goto redo;
+        }
+        break;
+    case TOK_ENDIF:
+        if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
+            error("#endif without matching #if");
+        s1->ifdef_stack_ptr--;
+        /* '#ifndef macro' was at the start of file. Now we check if
+           an '#endif' is exactly at the end of file */
+        if (file->ifndef_macro &&
+            s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
+            file->ifndef_macro_saved = file->ifndef_macro;
+            /* need to set to zero to avoid false matches if another
+               #ifndef at middle of file */
+            file->ifndef_macro = 0;
+            while (tok != TOK_LINEFEED)
+                next_nomacro();
+            tok_flags |= TOK_FLAG_ENDIF;
+            goto the_end;
+        }
+        break;
+    case TOK_LINE:
+        next();
+        if (tok != TOK_CINT)
+            error("#line");
+        file->line_num = tokc.i - 1; /* the line number will be incremented after */
+        next();
+        if (tok != TOK_LINEFEED) {
+            if (tok != TOK_STR)
+                error("#line");
+            pstrcpy(file->filename, sizeof(file->filename), 
+                    (char *)tokc.cstr->data);
+        }
+        break;
+    case TOK_ERROR:
+    case TOK_WARNING:
+        c = tok;
+        ch = file->buf_ptr[0];
+        skip_spaces();
+        q = buf;
+        while (ch != '\n' && ch != CH_EOF) {
+            if ((q - buf) < sizeof(buf) - 1)
+                *q++ = ch;
+            if (ch == '\\') {
+                if (handle_stray_noerror() == 0)
+                    --q;
+            } else
+                inp();
+        }
+        *q = '\0';
+        if (c == TOK_ERROR)
+            error("#error %s", buf);
+        else
+            warning("#warning %s", buf);
+        break;
+    case TOK_PRAGMA:
+        pragma_parse(s1);
+        break;
+    default:
+        if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_CINT) {
+            /* '!' is ignored to allow C scripts. numbers are ignored
+               to emulate cpp behaviour */
+        } else {
+            if (!(saved_parse_flags & PARSE_FLAG_ASM_COMMENTS))
+                warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
+        }
+        break;
+    }
+    /* ignore other preprocess commands or #! for C scripts */
+    while (tok != TOK_LINEFEED)
+        next_nomacro();
+ the_end:
+    parse_flags = saved_parse_flags;
+}
+
+/* evaluate escape codes in a string. */
+static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
+{
+    int c, n;
+    const uint8_t *p;
+
+    p = buf;
+    for(;;) {
+        c = *p;
+        if (c == '\0')
+            break;
+        if (c == '\\') {
+            p++;
+            /* escape */
+            c = *p;
+            switch(c) {
+            case '0': case '1': case '2': case '3':
+            case '4': case '5': case '6': case '7':
+                /* at most three octal digits */
+                n = c - '0';
+                p++;
+                c = *p;
+                if (isoct(c)) {
+                    n = n * 8 + c - '0';
+                    p++;
+                    c = *p;
+                    if (isoct(c)) {
+                        n = n * 8 + c - '0';
+                        p++;
+                    }
+                }
+                c = n;
+                goto add_char_nonext;
+            case 'x':
+            case 'u':
+            case 'U':
+                p++;
+                n = 0;
+                for(;;) {
+                    c = *p;
+                    if (c >= 'a' && c <= 'f')
+                        c = c - 'a' + 10;
+                    else if (c >= 'A' && c <= 'F')
+                        c = c - 'A' + 10;
+                    else if (isnum(c))
+                        c = c - '0';
+                    else
+                        break;
+                    n = n * 16 + c;
+                    p++;
+                }
+                c = n;
+                goto add_char_nonext;
+            case 'a':
+                c = '\a';
+                break;
+            case 'b':
+                c = '\b';
+                break;
+            case 'f':
+                c = '\f';
+                break;
+            case 'n':
+                c = '\n';
+                break;
+            case 'r':
+                c = '\r';
+                break;
+            case 't':
+                c = '\t';
+                break;
+            case 'v':
+                c = '\v';
+                break;
+            case 'e':
+                if (!gnu_ext)
+                    goto invalid_escape;
+                c = 27;
+                break;
+            case '\'':
+            case '\"':
+            case '\\': 
+            case '?':
+                break;
+            default:
+            invalid_escape:
+                if (c >= '!' && c <= '~')
+                    warning("unknown escape sequence: \'\\%c\'", c);
+                else
+                    warning("unknown escape sequence: \'\\x%x\'", c);
+                break;
+            }
+        }
+        p++;
+    add_char_nonext:
+        if (!is_long)
+            cstr_ccat(outstr, c);
+        else
+            cstr_wccat(outstr, c);
+    }
+    /* add a trailing '\0' */
+    if (!is_long)
+        cstr_ccat(outstr, '\0');
+    else
+        cstr_wccat(outstr, '\0');
+}
+
+/* we use 64 bit numbers */
+#define BN_SIZE 2
+
+/* bn = (bn << shift) | or_val */
+void bn_lshift(unsigned int *bn, int shift, int or_val)
+{
+    int i;
+    unsigned int v;
+    for(i=0;i<BN_SIZE;i++) {
+        v = bn[i];
+        bn[i] = (v << shift) | or_val;
+        or_val = v >> (32 - shift);
+    }
+}
+
+void bn_zero(unsigned int *bn)
+{
+    int i;
+    for(i=0;i<BN_SIZE;i++) {
+        bn[i] = 0;
+    }
+}
+
+/* parse number in null terminated string 'p' and return it in the
+   current token */
+void parse_number(const char *p)
+{
+    int b, t, shift, frac_bits, s, exp_val, ch;
+    char *q;
+    unsigned int bn[BN_SIZE];
+    double d;
+
+    /* number */
+    q = token_buf;
+    ch = *p++;
+    t = ch;
+    ch = *p++;
+    *q++ = t;
+    b = 10;
+    if (t == '.') {
+        goto float_frac_parse;
+    } else if (t == '0') {
+        if (ch == 'x' || ch == 'X') {
+            q--;
+            ch = *p++;
+            b = 16;
+        } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
+            q--;
+            ch = *p++;
+            b = 2;
+        }
+    }
+    /* parse all digits. cannot check octal numbers at this stage
+       because of floating point constants */
+    while (1) {
+        if (ch >= 'a' && ch <= 'f')
+            t = ch - 'a' + 10;
+        else if (ch >= 'A' && ch <= 'F')
+            t = ch - 'A' + 10;
+        else if (isnum(ch))
+            t = ch - '0';
+        else
+            break;
+        if (t >= b)
+            break;
+        if (q >= token_buf + STRING_MAX_SIZE) {
+        num_too_long:
+            error("number too long");
+        }
+        *q++ = ch;
+        ch = *p++;
+    }
+    if (ch == '.' ||
+        ((ch == 'e' || ch == 'E') && b == 10) ||
+        ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
+        if (b != 10) {
+            /* NOTE: strtox should support that for hexa numbers, but
+               non ISOC99 libcs do not support it, so we prefer to do
+               it by hand */
+            /* hexadecimal or binary floats */
+            /* XXX: handle overflows */
+            *q = '\0';
+            if (b == 16)
+                shift = 4;
+            else 
+                shift = 2;
+            bn_zero(bn);
+            q = token_buf;
+            while (1) {
+                t = *q++;
+                if (t == '\0') {
+                    break;
+                } else if (t >= 'a') {
+                    t = t - 'a' + 10;
+                } else if (t >= 'A') {
+                    t = t - 'A' + 10;
+                } else {
+                    t = t - '0';
+                }
+                bn_lshift(bn, shift, t);
+            }
+            frac_bits = 0;
+            if (ch == '.') {
+                ch = *p++;
+                while (1) {
+                    t = ch;
+                    if (t >= 'a' && t <= 'f') {
+                        t = t - 'a' + 10;
+                    } else if (t >= 'A' && t <= 'F') {
+                        t = t - 'A' + 10;
+                    } else if (t >= '0' && t <= '9') {
+                        t = t - '0';
+                    } else {
+                        break;
+                    }
+                    if (t >= b)
+                        error("invalid digit");
+                    bn_lshift(bn, shift, t);
+                    frac_bits += shift;
+                    ch = *p++;
+                }
+            }
+            if (ch != 'p' && ch != 'P')
+                expect("exponent");
+            ch = *p++;
+            s = 1;
+            exp_val = 0;
+            if (ch == '+') {
+                ch = *p++;
+            } else if (ch == '-') {
+                s = -1;
+                ch = *p++;
+            }
+            if (ch < '0' || ch > '9')
+                expect("exponent digits");
+            while (ch >= '0' && ch <= '9') {
+                exp_val = exp_val * 10 + ch - '0';
+                ch = *p++;
+            }
+            exp_val = exp_val * s;
+            
+            /* now we can generate the number */
+            /* XXX: should patch directly float number */
+            d = (double)bn[1] * 4294967296.0 + (double)bn[0];
+            d = ldexp(d, exp_val - frac_bits);
+            t = toup(ch);
+            if (t == 'F') {
+                ch = *p++;
+                tok = TOK_CFLOAT;
+                /* float : should handle overflow */
+                tokc.f = (float)d;
+            } else if (t == 'L') {
+                ch = *p++;
+                tok = TOK_CLDOUBLE;
+                /* XXX: not large enough */
+                tokc.ld = (long double)d;
+            } else {
+                tok = TOK_CDOUBLE;
+                tokc.d = d;
+            }
+        } else {
+            /* decimal floats */
+            if (ch == '.') {
+                if (q >= token_buf + STRING_MAX_SIZE)
+                    goto num_too_long;
+                *q++ = ch;
+                ch = *p++;
+            float_frac_parse:
+                while (ch >= '0' && ch <= '9') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+            }
+            if (ch == 'e' || ch == 'E') {
+                if (q >= token_buf + STRING_MAX_SIZE)
+                    goto num_too_long;
+                *q++ = ch;
+                ch = *p++;
+                if (ch == '-' || ch == '+') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+                if (ch < '0' || ch > '9')
+                    expect("exponent digits");
+                while (ch >= '0' && ch <= '9') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+            }
+            *q = '\0';
+            t = toup(ch);
+            errno = 0;
+            if (t == 'F') {
+                ch = *p++;
+                tok = TOK_CFLOAT;
+                tokc.f = strtof(token_buf, NULL);
+            } else if (t == 'L') {
+                ch = *p++;
+                tok = TOK_CLDOUBLE;
+                tokc.ld = strtold(token_buf, NULL);
+            } else {
+                tok = TOK_CDOUBLE;
+                tokc.d = strtod(token_buf, NULL);
+            }
+        }
+    } else {
+        unsigned long long n, n1;
+        int lcount, ucount;
+
+        /* integer number */
+        *q = '\0';
+        q = token_buf;
+        if (b == 10 && *q == '0') {
+            b = 8;
+            q++;
+        }
+        n = 0;
+        while(1) {
+            t = *q++;
+            /* no need for checks except for base 10 / 8 errors */
+            if (t == '\0') {
+                break;
+            } else if (t >= 'a') {
+                t = t - 'a' + 10;
+            } else if (t >= 'A') {
+                t = t - 'A' + 10;
+            } else {
+                t = t - '0';
+                if (t >= b)
+                    error("invalid digit");
+            }
+            n1 = n;
+            n = n * b + t;
+            /* detect overflow */
+            /* XXX: this test is not reliable */
+            if (n < n1)
+                error("integer constant overflow");
+        }
+        
+        /* XXX: not exactly ANSI compliant */
+        if ((n & 0xffffffff00000000LL) != 0) {
+            if ((n >> 63) != 0)
+                tok = TOK_CULLONG;
+            else
+                tok = TOK_CLLONG;
+        } else if (n > 0x7fffffff) {
+            tok = TOK_CUINT;
+        } else {
+            tok = TOK_CINT;
+        }
+        lcount = 0;
+        ucount = 0;
+        for(;;) {
+            t = toup(ch);
+            if (t == 'L') {
+                if (lcount >= 2)
+                    error("three 'l's in integer constant");
+                lcount++;
+                if (lcount == 2) {
+                    if (tok == TOK_CINT)
+                        tok = TOK_CLLONG;
+                    else if (tok == TOK_CUINT)
+                        tok = TOK_CULLONG;
+                }
+                ch = *p++;
+            } else if (t == 'U') {
+                if (ucount >= 1)
+                    error("two 'u's in integer constant");
+                ucount++;
+                if (tok == TOK_CINT)
+                    tok = TOK_CUINT;
+                else if (tok == TOK_CLLONG)
+                    tok = TOK_CULLONG;
+                ch = *p++;
+            } else {
+                break;
+            }
+        }
+        if (tok == TOK_CINT || tok == TOK_CUINT)
+            tokc.ui = n;
+        else
+            tokc.ull = n;
+    }
+    if (ch)
+        error("invalid number\n");
+}
+
+
+#define PARSE2(c1, tok1, c2, tok2)              \
+    case c1:                                    \
+        PEEKC(c, p);                            \
+        if (c == c2) {                          \
+            p++;                                \
+            tok = tok2;                         \
+        } else {                                \
+            tok = tok1;                         \
+        }                                       \
+        break;
+
+/* return next token without macro substitution */
+static inline void next_nomacro1(void)
+{
+    int t, c, is_long;
+    TokenSym *ts;
+    uint8_t *p, *p1;
+    unsigned int h;
+
+    p = file->buf_ptr;
+ redo_no_start:
+    c = *p;
+    switch(c) {
+    case ' ':
+    case '\t':
+        tok = c;
+        p++;
+        goto keep_tok_flags;
+    case '\f':
+    case '\v':
+    case '\r':
+        p++;
+        goto redo_no_start;
+    case '\\':
+        /* first look if it is in fact an end of buffer */
+        if (p >= file->buf_end) {
+            file->buf_ptr = p;
+            handle_eob();
+            p = file->buf_ptr;
+            if (p >= file->buf_end)
+                goto parse_eof;
+            else
+                goto redo_no_start;
+        } else {
+            file->buf_ptr = p;
+            ch = *p;
+            handle_stray();
+            p = file->buf_ptr;
+            goto redo_no_start;
+        }
+    parse_eof:
+        {
+            TCCState *s1 = tcc_state;
+            if ((parse_flags & PARSE_FLAG_LINEFEED)
+                && !(tok_flags & TOK_FLAG_EOF)) {
+                tok_flags |= TOK_FLAG_EOF;
+                tok = TOK_LINEFEED;
+                goto keep_tok_flags;
+            } else if (s1->include_stack_ptr == s1->include_stack ||
+                       !(parse_flags & PARSE_FLAG_PREPROCESS)) {
+                /* no include left : end of file. */
+                tok = TOK_EOF;
+            } else {
+                tok_flags &= ~TOK_FLAG_EOF;
+                /* pop include file */
+                
+                /* test if previous '#endif' was after a #ifdef at
+                   start of file */
+                if (tok_flags & TOK_FLAG_ENDIF) {
+#ifdef INC_DEBUG
+                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
+#endif
+                    add_cached_include(s1, file->inc_type, file->inc_filename,
+                                       file->ifndef_macro_saved);
+                }
+
+                /* add end of include file debug info */
+                if (tcc_state->do_debug) {
+                    put_stabd(N_EINCL, 0, 0);
+                }
+                /* pop include stack */
+                tcc_close(file);
+                s1->include_stack_ptr--;
+                file = *s1->include_stack_ptr;
+                p = file->buf_ptr;
+                goto redo_no_start;
+            }
+        }
+        break;
+
+    case '\n':
+        file->line_num++;
+        tok_flags |= TOK_FLAG_BOL;
+        p++;
+        if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
+            goto redo_no_start;
+        tok = TOK_LINEFEED;
+        goto keep_tok_flags;
+
+    case '#':
+        /* XXX: simplify */
+        PEEKC(c, p);
+        if ((tok_flags & TOK_FLAG_BOL) && 
+            (parse_flags & PARSE_FLAG_PREPROCESS)) {
+            file->buf_ptr = p;
+            preprocess(tok_flags & TOK_FLAG_BOF);
+            p = file->buf_ptr;
+            goto redo_no_start;
+        } else {
+            if (c == '#') {
+                p++;
+                tok = TOK_TWOSHARPS;
+            } else {
+                if (parse_flags & PARSE_FLAG_ASM_COMMENTS) {
+                    p = parse_line_comment(p - 1);
+                    goto redo_no_start;
+                } else {
+                    tok = '#';
+                }
+            }
+        }
+        break;
+
+    case 'a': case 'b': case 'c': case 'd':
+    case 'e': case 'f': case 'g': case 'h':
+    case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p':
+    case 'q': case 'r': case 's': case 't':
+    case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z': 
+    case 'A': case 'B': case 'C': case 'D':
+    case 'E': case 'F': case 'G': case 'H':
+    case 'I': case 'J': case 'K': 
+    case 'M': case 'N': case 'O': case 'P':
+    case 'Q': case 'R': case 'S': case 'T':
+    case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z': 
+    case '_':
+    parse_ident_fast:
+        p1 = p;
+        h = TOK_HASH_INIT;
+        h = TOK_HASH_FUNC(h, c);
+        p++;
+        for(;;) {
+            c = *p;
+            if (!isidnum_table[c-CH_EOF])
+                break;
+            h = TOK_HASH_FUNC(h, c);
+            p++;
+        }
+        if (c != '\\') {
+            TokenSym **pts;
+            int len;
+
+            /* fast case : no stray found, so we have the full token
+               and we have already hashed it */
+            len = p - p1;
+            h &= (TOK_HASH_SIZE - 1);
+            pts = &hash_ident[h];
+            for(;;) {
+                ts = *pts;
+                if (!ts)
+                    break;
+                if (ts->len == len && !memcmp(ts->str, p1, len))
+                    goto token_found;
+                pts = &(ts->hash_next);
+            }
+            ts = tok_alloc_new(pts, p1, len);
+        token_found: ;
+        } else {
+            /* slower case */
+            cstr_reset(&tokcstr);
+
+            while (p1 < p) {
+                cstr_ccat(&tokcstr, *p1);
+                p1++;
+            }
+            p--;
+            PEEKC(c, p);
+        parse_ident_slow:
+            while (isidnum_table[c-CH_EOF]) {
+                cstr_ccat(&tokcstr, c);
+                PEEKC(c, p);
+            }
+            ts = tok_alloc(tokcstr.data, tokcstr.size);
+        }
+        tok = ts->tok;
+        break;
+    case 'L':
+        t = p[1];
+        if (t != '\\' && t != '\'' && t != '\"') {
+            /* fast case */
+            goto parse_ident_fast;
+        } else {
+            PEEKC(c, p);
+            if (c == '\'' || c == '\"') {
+                is_long = 1;
+                goto str_const;
+            } else {
+                cstr_reset(&tokcstr);
+                cstr_ccat(&tokcstr, 'L');
+                goto parse_ident_slow;
+            }
+        }
+        break;
+    case '0': case '1': case '2': case '3':
+    case '4': case '5': case '6': case '7':
+    case '8': case '9':
+
+        cstr_reset(&tokcstr);
+        /* after the first digit, accept digits, alpha, '.' or sign if
+           prefixed by 'eEpP' */
+    parse_num:
+        for(;;) {
+            t = c;
+            cstr_ccat(&tokcstr, c);
+            PEEKC(c, p);
+            if (!(isnum(c) || isid(c) || c == '.' ||
+                  ((c == '+' || c == '-') && 
+                   (t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
+                break;
+        }
+        /* We add a trailing '\0' to ease parsing */
+        cstr_ccat(&tokcstr, '\0');
+        tokc.cstr = &tokcstr;
+        tok = TOK_PPNUM;
+        break;
+    case '.':
+        /* special dot handling because it can also start a number */
+        PEEKC(c, p);
+        if (isnum(c)) {
+            cstr_reset(&tokcstr);
+            cstr_ccat(&tokcstr, '.');
+            goto parse_num;
+        } else if (c == '.') {
+            PEEKC(c, p);
+            if (c != '.')
+                expect("'.'");
+            PEEKC(c, p);
+            tok = TOK_DOTS;
+        } else {
+            tok = '.';
+        }
+        break;
+    case '\'':
+    case '\"':
+        is_long = 0;
+    str_const:
+        {
+            CString str;
+            int sep;
+
+            sep = c;
+
+            /* parse the string */
+            cstr_new(&str);
+            p = parse_pp_string(p, sep, &str);
+            cstr_ccat(&str, '\0');
+            
+            /* eval the escape (should be done as TOK_PPNUM) */
+            cstr_reset(&tokcstr);
+            parse_escape_string(&tokcstr, str.data, is_long);
+            cstr_free(&str);
+
+            if (sep == '\'') {
+                int char_size;
+                /* XXX: make it portable */
+                if (!is_long)
+                    char_size = 1;
+                else
+                    char_size = sizeof(nwchar_t);
+                if (tokcstr.size <= char_size)
+                    error("empty character constant");
+                if (tokcstr.size > 2 * char_size)
+                    warning("multi-character character constant");
+                if (!is_long) {
+                    tokc.i = *(int8_t *)tokcstr.data;
+                    tok = TOK_CCHAR;
+                } else {
+                    tokc.i = *(nwchar_t *)tokcstr.data;
+                    tok = TOK_LCHAR;
+                }
+            } else {
+                tokc.cstr = &tokcstr;
+                if (!is_long)
+                    tok = TOK_STR;
+                else
+                    tok = TOK_LSTR;
+            }
+        }
+        break;
+
+    case '<':
+        PEEKC(c, p);
+        if (c == '=') {
+            p++;
+            tok = TOK_LE;
+        } else if (c == '<') {
+            PEEKC(c, p);
+            if (c == '=') {
+                p++;
+                tok = TOK_A_SHL;
+            } else {
+                tok = TOK_SHL;
+            }
+        } else {
+            tok = TOK_LT;
+        }
+        break;
+        
+    case '>':
+        PEEKC(c, p);
+        if (c == '=') {
+            p++;
+            tok = TOK_GE;
+        } else if (c == '>') {
+            PEEKC(c, p);
+            if (c == '=') {
+                p++;
+                tok = TOK_A_SAR;
+            } else {
+                tok = TOK_SAR;
+            }
+        } else {
+            tok = TOK_GT;
+        }
+        break;
+        
+    case '&':
+        PEEKC(c, p);
+        if (c == '&') {
+            p++;
+            tok = TOK_LAND;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_AND;
+        } else {
+            tok = '&';
+        }
+        break;
+        
+    case '|':
+        PEEKC(c, p);
+        if (c == '|') {
+            p++;
+            tok = TOK_LOR;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_OR;
+        } else {
+            tok = '|';
+        }
+        break;
+
+    case '+':
+        PEEKC(c, p);
+        if (c == '+') {
+            p++;
+            tok = TOK_INC;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_ADD;
+        } else {
+            tok = '+';
+        }
+        break;
+        
+    case '-':
+        PEEKC(c, p);
+        if (c == '-') {
+            p++;
+            tok = TOK_DEC;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_SUB;
+        } else if (c == '>') {
+            p++;
+            tok = TOK_ARROW;
+        } else {
+            tok = '-';
+        }
+        break;
+
+    PARSE2('!', '!', '=', TOK_NE)
+    PARSE2('=', '=', '=', TOK_EQ)
+    PARSE2('*', '*', '=', TOK_A_MUL)
+    PARSE2('%', '%', '=', TOK_A_MOD)
+    PARSE2('^', '^', '=', TOK_A_XOR)
+        
+        /* comments or operator */
+    case '/':
+        PEEKC(c, p);
+        if (c == '*') {
+            p = parse_comment(p);
+            goto redo_no_start;
+        } else if (c == '/') {
+            p = parse_line_comment(p);
+            goto redo_no_start;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_DIV;
+        } else {
+            tok = '/';
+        }
+        break;
+        
+        /* simple tokens */
+    case '(':
+    case ')':
+    case '[':
+    case ']':
+    case '{':
+    case '}':
+    case ',':
+    case ';':
+    case ':':
+    case '?':
+    case '~':
+    case '$': /* only used in assembler */
+    case '@': /* dito */
+        tok = c;
+        p++;
+        break;
+    default:
+        error("unrecognized character \\x%02x", c);
+        break;
+    }
+    tok_flags = 0;
+keep_tok_flags:
+    file->buf_ptr = p;
+#if defined(PARSE_DEBUG)
+    printf("token = %s\n", get_tok_str(tok, &tokc));
+#endif
+}
+
+/* return next token without macro substitution. Can read input from
+   macro_ptr buffer */
+static void next_nomacro_spc(void)
+{
+    if (macro_ptr) {
+    redo:
+        tok = *macro_ptr;
+        if (tok) {
+            TOK_GET(tok, macro_ptr, tokc);
+            if (tok == TOK_LINENUM) {
+                file->line_num = tokc.i;
+                goto redo;
+            }
+        }
+    } else {
+        next_nomacro1();
+    }
+}
+
+static void next_nomacro(void)
+{
+    do {
+        next_nomacro_spc();
+    } while (is_space(tok));
+}
+ 
+/* substitute args in macro_str and return allocated string */
+static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
+{
+    int *st, last_tok, t, spc;
+    Sym *s;
+    CValue cval;
+    TokenString str;
+    CString cstr;
+
+    tok_str_new(&str);
+    last_tok = 0;
+    while(1) {
+        TOK_GET(t, macro_str, cval);
+        if (!t)
+            break;
+        if (t == '#') {
+            /* stringize */
+            TOK_GET(t, macro_str, cval);
+            if (!t)
+                break;
+            s = sym_find2(args, t);
+            if (s) {
+                cstr_new(&cstr);
+                st = (int *)s->c;
+                spc = 0;
+                while (*st) {
+                    TOK_GET(t, st, cval);
+                    if (!check_space(t, &spc))
+                        cstr_cat(&cstr, get_tok_str(t, &cval));
+                }
+                cstr.size -= spc;
+                cstr_ccat(&cstr, '\0');
+#ifdef PP_DEBUG
+                printf("stringize: %s\n", (char *)cstr.data);
+#endif
+                /* add string */
+                cval.cstr = &cstr;
+                tok_str_add2(&str, TOK_STR, &cval);
+                cstr_free(&cstr);
+            } else {
+                tok_str_add2(&str, t, &cval);
+            }
+        } else if (t >= TOK_IDENT) {
+            s = sym_find2(args, t);
+            if (s) {
+                st = (int *)s->c;
+                /* if '##' is present before or after, no arg substitution */
+                if (*macro_str == TOK_TWOSHARPS || last_tok == TOK_TWOSHARPS) {
+                    /* special case for var arg macros : ## eats the
+                       ',' if empty VA_ARGS variable. */
+                    /* XXX: test of the ',' is not 100%
+                       reliable. should fix it to avoid security
+                       problems */
+                    if (gnu_ext && s->type.t &&
+                        last_tok == TOK_TWOSHARPS && 
+                        str.len >= 2 && str.str[str.len - 2] == ',') {
+                        if (*st == 0) {
+                            /* suppress ',' '##' */
+                            str.len -= 2;
+                        } else {
+                            /* suppress '##' and add variable */
+                            str.len--;
+                            goto add_var;
+                        }
+                    } else {
+                        int t1;
+                    add_var:
+                        for(;;) {
+                            TOK_GET(t1, st, cval);
+                            if (!t1)
+                                break;
+                            tok_str_add2(&str, t1, &cval);
+                        }
+                    }
+                } else {
+                    /* NOTE: the stream cannot be read when macro
+                       substituing an argument */
+                    macro_subst(&str, nested_list, st, NULL);
+                }
+            } else {
+                tok_str_add(&str, t);
+            }
+        } else {
+            tok_str_add2(&str, t, &cval);
+        }
+        last_tok = t;
+    }
+    tok_str_add(&str, 0);
+    return str.str;
+}
+
+static char const ab_month_name[12][4] =
+{
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+/* do macro substitution of current token with macro 's' and add
+   result to (tok_str,tok_len). 'nested_list' is the list of all
+   macros we got inside to avoid recursing. Return non zero if no
+   substitution needs to be done */
+static int macro_subst_tok(TokenString *tok_str,
+                           Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
+{
+    Sym *args, *sa, *sa1;
+    int mstr_allocated, parlevel, *mstr, t, t1, *p, spc;
+    TokenString str;
+    char *cstrval;
+    CValue cval;
+    CString cstr;
+    char buf[32];
+    
+    /* if symbol is a macro, prepare substitution */
+    /* special macros */
+    if (tok == TOK___LINE__) {
+        snprintf(buf, sizeof(buf), "%d", file->line_num);
+        cstrval = buf;
+        t1 = TOK_PPNUM;
+        goto add_cstr1;
+    } else if (tok == TOK___FILE__) {
+        cstrval = file->filename;
+        goto add_cstr;
+    } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
+        time_t ti;
+        struct tm *tm;
+
+        time(&ti);
+        tm = localtime(&ti);
+        if (tok == TOK___DATE__) {
+            snprintf(buf, sizeof(buf), "%s %2d %d", 
+                     ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
+        } else {
+            snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 
+                     tm->tm_hour, tm->tm_min, tm->tm_sec);
+        }
+        cstrval = buf;
+    add_cstr:
+        t1 = TOK_STR;
+    add_cstr1:
+        cstr_new(&cstr);
+        cstr_cat(&cstr, cstrval);
+        cstr_ccat(&cstr, '\0');
+        cval.cstr = &cstr;
+        tok_str_add2(tok_str, t1, &cval);
+        cstr_free(&cstr);
+    } else {
+        mstr = (int *)s->c;
+        mstr_allocated = 0;
+        if (s->type.t == MACRO_FUNC) {
+            /* NOTE: we do not use next_nomacro to avoid eating the
+               next token. XXX: find better solution */
+        redo:
+            if (macro_ptr) {
+                p = macro_ptr;
+                while (is_space(t = *p) || TOK_LINEFEED == t) 
+                    ++p;
+                if (t == 0 && can_read_stream) {
+                    /* end of macro stream: we must look at the token
+                       after in the file */
+                    struct macro_level *ml = *can_read_stream;
+                    macro_ptr = NULL;
+                    if (ml)
+                    {
+                        macro_ptr = ml->p;
+                        ml->p = NULL;
+                        *can_read_stream = ml -> prev;
+                    }
+                    goto redo;
+                }
+            } else {
+                /* XXX: incorrect with comments */
+                ch = file->buf_ptr[0];
+                while (is_space(ch) || ch == '\n')
+                    cinp();
+                t = ch;
+            }
+            if (t != '(') /* no macro subst */
+                return -1;
+                    
+            /* argument macro */
+            next_nomacro();
+            next_nomacro();
+            args = NULL;
+            sa = s->next;
+            /* NOTE: empty args are allowed, except if no args */
+            for(;;) {
+                /* handle '()' case */
+                if (!args && !sa && tok == ')')
+                    break;
+                if (!sa)
+                    error("macro '%s' used with too many args",
+                          get_tok_str(s->v, 0));
+                tok_str_new(&str);
+                parlevel = spc = 0;
+                /* NOTE: non zero sa->t indicates VA_ARGS */
+                while ((parlevel > 0 || 
+                        (tok != ')' && 
+                         (tok != ',' || sa->type.t))) && 
+                       tok != -1) {
+                    if (tok == '(')
+                        parlevel++;
+                    else if (tok == ')')
+                        parlevel--;
+                    if (tok == TOK_LINEFEED)
+                        tok = ' ';
+                    if (!check_space(tok, &spc))
+                        tok_str_add2(&str, tok, &tokc);
+                    next_nomacro_spc();
+                }
+                str.len -= spc;
+                tok_str_add(&str, 0);
+                sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
+                sa = sa->next;
+                if (tok == ')') {
+                    /* special case for gcc var args: add an empty
+                       var arg argument if it is omitted */
+                    if (sa && sa->type.t && gnu_ext)
+                        continue;
+                    else
+                        break;
+                }
+                if (tok != ',')
+                    expect(",");
+                next_nomacro();
+            }
+            if (sa) {
+                error("macro '%s' used with too few args",
+                      get_tok_str(s->v, 0));
+            }
+
+            /* now subst each arg */
+            mstr = macro_arg_subst(nested_list, mstr, args);
+            /* free memory */
+            sa = args;
+            while (sa) {
+                sa1 = sa->prev;
+                tok_str_free((int *)sa->c);
+                sym_free(sa);
+                sa = sa1;
+            }
+            mstr_allocated = 1;
+        }
+        sym_push2(nested_list, s->v, 0, 0);
+        macro_subst(tok_str, nested_list, mstr, can_read_stream);
+        /* pop nested defined symbol */
+        sa1 = *nested_list;
+        *nested_list = sa1->prev;
+        sym_free(sa1);
+        if (mstr_allocated)
+            tok_str_free(mstr);
+    }
+    return 0;
+}
+
+/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
+   return the resulting string (which must be freed). */
+static inline int *macro_twosharps(const int *macro_str)
+{
+    TokenSym *ts;
+    const int *ptr, *saved_macro_ptr;
+    int t;
+    const char *p1, *p2;
+    CValue cval;
+    TokenString macro_str1;
+    CString cstr;
+
+    /* we search the first '##' */
+    for(ptr = macro_str;;) {
+        TOK_GET(t, ptr, cval);
+        if (t == TOK_TWOSHARPS)
+            break;
+        /* nothing more to do if end of string */
+        if (t == 0)
+            return NULL;
+    }
+
+    /* we saw '##', so we need more processing to handle it */
+    cstr_new(&cstr);
+    tok_str_new(&macro_str1);
+    saved_macro_ptr = macro_ptr;
+    /* XXX: get rid of the use of macro_ptr here */
+    macro_ptr = (int *)macro_str;
+    for(;;) {
+        next_nomacro_spc();
+        if (tok == 0)
+            break;
+        if (tok == TOK_TWOSHARPS)
+            continue;
+        while (*macro_ptr == TOK_TWOSHARPS) {
+            t = *++macro_ptr;
+            if (t && t != TOK_TWOSHARPS) {
+                TOK_GET(t, macro_ptr, cval);
+                /* We concatenate the two tokens if we have an
+                   identifier or a preprocessing number */
+                cstr_reset(&cstr);
+                p1 = get_tok_str(tok, &tokc);
+                cstr_cat(&cstr, p1);
+                p2 = get_tok_str(t, &cval);
+                cstr_cat(&cstr, p2);
+                cstr_ccat(&cstr, '\0');
+
+                if ((tok >= TOK_IDENT || tok == TOK_PPNUM) && 
+                    (t >= TOK_IDENT || t == TOK_PPNUM)) {
+                    if (tok == TOK_PPNUM) {
+                        /* if number, then create a number token */
+                        /* NOTE: no need to allocate because
+                           tok_str_add2() does it */
+                        cstr_reset(&tokcstr);
+                        tokcstr = cstr;
+                        cstr_new(&cstr);
+                        tokc.cstr = &tokcstr;
+                    } else {
+                        /* if identifier, we must do a test to
+                           validate we have a correct identifier */
+                        if (t == TOK_PPNUM) {
+                            const char *p;
+                            int c;
+
+                            p = p2;
+                            for(;;) {
+                                c = *p;
+                                if (c == '\0')
+                                    break;
+                                p++;
+                                if (!isnum(c) && !isid(c))
+                                    goto error_pasting;
+                            }
+                        }
+                        ts = tok_alloc(cstr.data, strlen(cstr.data));
+                        tok = ts->tok; /* modify current token */
+                    }
+                } else {
+                    const char *str = cstr.data;
+                    const unsigned char *q;
+
+                    /* we look for a valid token */
+                    /* XXX: do more extensive checks */
+                    if (!strcmp(str, ">>=")) {
+                        tok = TOK_A_SAR;
+                    } else if (!strcmp(str, "<<=")) {
+                        tok = TOK_A_SHL;
+                    } else if (strlen(str) == 2) {
+                        /* search in two bytes table */
+                        q = tok_two_chars;
+                        for(;;) {
+                            if (!*q)
+                                goto error_pasting;
+                            if (q[0] == str[0] && q[1] == str[1])
+                                break;
+                            q += 3;
+                        }
+                        tok = q[2];
+                    } else {
+                    error_pasting:
+                        /* NOTE: because get_tok_str use a static buffer,
+                           we must save it */
+                        cstr_reset(&cstr);
+                        p1 = get_tok_str(tok, &tokc);
+                        cstr_cat(&cstr, p1);
+                        cstr_ccat(&cstr, '\0');
+                        p2 = get_tok_str(t, &cval);
+                        warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
+                        /* cannot merge tokens: just add them separately */
+                        tok_str_add2(&macro_str1, tok, &tokc);
+                        /* XXX: free associated memory ? */
+                        tok = t;
+                        tokc = cval;
+                    }
+                }
+            }
+        }
+        tok_str_add2(&macro_str1, tok, &tokc);
+    }
+    macro_ptr = (int *)saved_macro_ptr;
+    cstr_free(&cstr);
+    tok_str_add(&macro_str1, 0);
+    return macro_str1.str;
+}
+
+
+/* do macro substitution of macro_str and add result to
+   (tok_str,tok_len). 'nested_list' is the list of all macros we got
+   inside to avoid recursing. */
+static void macro_subst(TokenString *tok_str, Sym **nested_list, 
+                        const int *macro_str, struct macro_level ** can_read_stream)
+{
+    Sym *s;
+    int *macro_str1;
+    const int *ptr;
+    int t, ret, spc;
+    CValue cval;
+    struct macro_level ml;
+    
+    /* first scan for '##' operator handling */
+    ptr = macro_str;
+    macro_str1 = macro_twosharps(ptr);
+    if (macro_str1) 
+        ptr = macro_str1;
+    spc = 0;
+    while (1) {
+        /* NOTE: ptr == NULL can only happen if tokens are read from
+           file stream due to a macro function call */
+        if (ptr == NULL)
+            break;
+        TOK_GET(t, ptr, cval);
+        if (t == 0)
+            break;
+        s = define_find(t);
+        if (s != NULL) {
+            /* if nested substitution, do nothing */
+            if (sym_find2(*nested_list, t))
+                goto no_subst;
+            ml.p = macro_ptr;
+            if (can_read_stream)
+                ml.prev = *can_read_stream, *can_read_stream = &ml;
+            macro_ptr = (int *)ptr;
+            tok = t;
+            ret = macro_subst_tok(tok_str, nested_list, s, can_read_stream);
+            ptr = (int *)macro_ptr;
+            macro_ptr = ml.p;
+            if (can_read_stream && *can_read_stream == &ml)
+                *can_read_stream = ml.prev;
+            if (ret != 0)
+                goto no_subst;
+        } else {
+        no_subst:
+            if (!check_space(t, &spc)) 
+                tok_str_add2(tok_str, t, &cval);
+        }
+    }
+    if (macro_str1)
+        tok_str_free(macro_str1);
+}
+
+/* return next token with macro substitution */
+static void next(void)
+{
+    Sym *nested_list, *s;
+    TokenString str;
+    struct macro_level *ml;
+
+ redo:
+    if (parse_flags & PARSE_FLAG_SPACES)
+        next_nomacro_spc();
+    else
+        next_nomacro();
+    if (!macro_ptr) {
+        /* if not reading from macro substituted string, then try
+           to substitute macros */
+        if (tok >= TOK_IDENT &&
+            (parse_flags & PARSE_FLAG_PREPROCESS)) {
+            s = define_find(tok);
+            if (s) {
+                /* we have a macro: we try to substitute */
+                tok_str_new(&str);
+                nested_list = NULL;
+                ml = NULL;
+                if (macro_subst_tok(&str, &nested_list, s, &ml) == 0) {
+                    /* substitution done, NOTE: maybe empty */
+                    tok_str_add(&str, 0);
+                    macro_ptr = str.str;
+                    macro_ptr_allocated = str.str;
+                    goto redo;
+                }
+            }
+        }
+    } else {
+        if (tok == 0) {
+            /* end of macro or end of unget buffer */
+            if (unget_buffer_enabled) {
+                macro_ptr = unget_saved_macro_ptr;
+                unget_buffer_enabled = 0;
+            } else {
+                /* end of macro string: free it */
+                tok_str_free(macro_ptr_allocated);
+                macro_ptr = NULL;
+            }
+            goto redo;
+        }
+    }
+    
+    /* convert preprocessor tokens into C tokens */
+    if (tok == TOK_PPNUM &&
+        (parse_flags & PARSE_FLAG_TOK_NUM)) {
+        parse_number((char *)tokc.cstr->data);
+    }
+}
+
+/* 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)
+{
+    int i, n;
+    int *q;
+    unget_saved_macro_ptr = macro_ptr;
+    unget_buffer_enabled = 1;
+    q = unget_saved_buffer;
+    macro_ptr = q;
+    *q++ = tok;
+    n = tok_ext_size(tok) - 1;
+    for(i=0;i<n;i++)
+        *q++ = tokc.tab[i];
+    *q = 0; /* end of token string */
+    tok = last_tok;
+}
+
+
+/* better than nothing, but needs extension to handle '-E' option
+   correctly too */
+static void preprocess_init(TCCState *s1)
+{
+    s1->include_stack_ptr = s1->include_stack;
+    /* XXX: move that before to avoid having to initialize
+       file->ifdef_stack_ptr ? */
+    s1->ifdef_stack_ptr = s1->ifdef_stack;
+    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+
+    /* XXX: not ANSI compliant: bound checking says error */
+    vtop = vstack - 1;
+    s1->pack_stack[0] = 0;
+    s1->pack_stack_ptr = s1->pack_stack;
+}
+
+void preprocess_new()
+{
+    int i, c;
+    const char *p, *r;
+    TokenSym *ts;
+
+    /* init isid table */
+    for(i=CH_EOF;i<256;i++)
+        isidnum_table[i-CH_EOF] = isid(i) || isnum(i);
+
+    /* add all tokens */
+    table_ident = NULL;
+    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
+    
+    tok_ident = TOK_IDENT;
+    p = tcc_keywords;
+    while (*p) {
+        r = p;
+        for(;;) {
+            c = *r++;
+            if (c == '\0')
+                break;
+        }
+        ts = tok_alloc(p, r - p - 1);
+        p = r;
+    }
+}
+
+/* Preprocess the current file */
+static int tcc_preprocess(TCCState *s1)
+{
+    Sym *define_start;
+    BufferedFile *file_ref;
+    int token_seen, line_ref;
+
+    preprocess_init(s1);
+    define_start = define_stack;
+    ch = file->buf_ptr[0];
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+    parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
+        PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
+    token_seen = 0;
+    line_ref = 0;
+    file_ref = NULL;
+
+    for (;;) {
+        next();
+        if (tok == TOK_EOF) {
+            break;
+        } else if (tok == TOK_LINEFEED) {
+            if (!token_seen)
+                continue;
+            ++line_ref;
+            token_seen = 0;
+        } else if (!token_seen) {
+            int d = file->line_num - line_ref;
+            if (file != file_ref || d < 0 || d >= 8)
+                fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);
+            else
+                while (d)
+                    fputs("\n", s1->outfile), --d;
+            line_ref = (file_ref = file)->line_num;
+            token_seen = 1;
+        }
+        fputs(get_tok_str(tok, &tokc), s1->outfile);
+    }
+    free_defines(define_start); 
+    return 0;
+}
+
diff --git a/tinyc/tcctok.h b/tinyc/tcctok.h
new file mode 100755
index 000000000..6dc477821
--- /dev/null
+++ b/tinyc/tcctok.h
@@ -0,0 +1,469 @@
+/* keywords */
+     DEF(TOK_INT, "int")
+     DEF(TOK_VOID, "void")
+     DEF(TOK_CHAR, "char")
+     DEF(TOK_IF, "if")
+     DEF(TOK_ELSE, "else")
+     DEF(TOK_WHILE, "while")
+     DEF(TOK_BREAK, "break")
+     DEF(TOK_RETURN, "return")
+     DEF(TOK_FOR, "for")
+     DEF(TOK_EXTERN, "extern")
+     DEF(TOK_STATIC, "static")
+     DEF(TOK_UNSIGNED, "unsigned")
+     DEF(TOK_GOTO, "goto")
+     DEF(TOK_DO, "do")
+     DEF(TOK_CONTINUE, "continue")
+     DEF(TOK_SWITCH, "switch")
+     DEF(TOK_CASE, "case")
+
+     DEF(TOK_CONST1, "const")
+     DEF(TOK_CONST2, "__const") /* gcc keyword */
+     DEF(TOK_CONST3, "__const__") /* gcc keyword */
+     DEF(TOK_VOLATILE1, "volatile")
+     DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
+     DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
+     DEF(TOK_LONG, "long")
+     DEF(TOK_REGISTER, "register")
+     DEF(TOK_SIGNED1, "signed")
+     DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
+     DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
+     DEF(TOK_AUTO, "auto")
+     DEF(TOK_INLINE1, "inline")
+     DEF(TOK_INLINE2, "__inline") /* gcc keyword */
+     DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
+     DEF(TOK_RESTRICT1, "restrict")
+     DEF(TOK_RESTRICT2, "__restrict")
+     DEF(TOK_RESTRICT3, "__restrict__")
+     DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
+     
+     DEF(TOK_FLOAT, "float")
+     DEF(TOK_DOUBLE, "double")
+     DEF(TOK_BOOL, "_Bool")
+     DEF(TOK_SHORT, "short")
+     DEF(TOK_STRUCT, "struct")
+     DEF(TOK_UNION, "union")
+     DEF(TOK_TYPEDEF, "typedef")
+     DEF(TOK_DEFAULT, "default")
+     DEF(TOK_ENUM, "enum")
+     DEF(TOK_SIZEOF, "sizeof")
+     DEF(TOK_ATTRIBUTE1, "__attribute")
+     DEF(TOK_ATTRIBUTE2, "__attribute__")
+     DEF(TOK_ALIGNOF1, "__alignof")
+     DEF(TOK_ALIGNOF2, "__alignof__")
+     DEF(TOK_TYPEOF1, "typeof")
+     DEF(TOK_TYPEOF2, "__typeof")
+     DEF(TOK_TYPEOF3, "__typeof__")
+     DEF(TOK_LABEL, "__label__")
+     DEF(TOK_ASM1, "asm")
+     DEF(TOK_ASM2, "__asm")
+     DEF(TOK_ASM3, "__asm__")
+
+/*********************************************************************/
+/* the following are not keywords. They are included to ease parsing */
+/* preprocessor only */
+     DEF(TOK_DEFINE, "define")
+     DEF(TOK_INCLUDE, "include")
+     DEF(TOK_INCLUDE_NEXT, "include_next")
+     DEF(TOK_IFDEF, "ifdef")
+     DEF(TOK_IFNDEF, "ifndef")
+     DEF(TOK_ELIF, "elif")
+     DEF(TOK_ENDIF, "endif")
+     DEF(TOK_DEFINED, "defined")
+     DEF(TOK_UNDEF, "undef")
+     DEF(TOK_ERROR, "error")
+     DEF(TOK_WARNING, "warning")
+     DEF(TOK_LINE, "line")
+     DEF(TOK_PRAGMA, "pragma")
+     DEF(TOK___LINE__, "__LINE__")
+     DEF(TOK___FILE__, "__FILE__")
+     DEF(TOK___DATE__, "__DATE__")
+     DEF(TOK___TIME__, "__TIME__")
+     DEF(TOK___FUNCTION__, "__FUNCTION__")
+     DEF(TOK___VA_ARGS__, "__VA_ARGS__")
+     
+/* special identifiers */
+     DEF(TOK___FUNC__, "__func__")
+     
+/* attribute identifiers */
+/* XXX: handle all tokens generically since speed is not critical */
+     DEF(TOK_SECTION1, "section")
+     DEF(TOK_SECTION2, "__section__")
+     DEF(TOK_ALIGNED1, "aligned")
+     DEF(TOK_ALIGNED2, "__aligned__")
+     DEF(TOK_PACKED1, "packed")
+     DEF(TOK_PACKED2, "__packed__")
+     DEF(TOK_UNUSED1, "unused")
+     DEF(TOK_UNUSED2, "__unused__")
+     DEF(TOK_CDECL1, "cdecl")
+     DEF(TOK_CDECL2, "__cdecl")
+     DEF(TOK_CDECL3, "__cdecl__")
+     DEF(TOK_STDCALL1, "stdcall")
+     DEF(TOK_STDCALL2, "__stdcall")
+     DEF(TOK_STDCALL3, "__stdcall__")
+     DEF(TOK_FASTCALL1, "fastcall")
+     DEF(TOK_FASTCALL2, "__fastcall")
+     DEF(TOK_FASTCALL3, "__fastcall__")
+     DEF(TOK_DLLEXPORT, "dllexport")
+     DEF(TOK_NORETURN1, "noreturn")
+     DEF(TOK_NORETURN2, "__noreturn__")
+     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
+     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
+     DEF(TOK_builtin_frame_address, "__builtin_frame_address")
+#ifdef TCC_TARGET_X86_64
+     DEF(TOK_builtin_malloc, "__builtin_malloc")
+     DEF(TOK_builtin_free, "__builtin_free")
+     DEF(TOK_malloc, "malloc")
+     DEF(TOK_free, "free")
+#endif
+     DEF(TOK_REGPARM1, "regparm")
+     DEF(TOK_REGPARM2, "__regparm__")
+
+/* pragma */
+     DEF(TOK_pack, "pack")
+#if !defined(TCC_TARGET_I386)
+     /* already defined for assembler */
+     DEF(TOK_ASM_push, "push")
+     DEF(TOK_ASM_pop, "pop")
+#endif
+
+/* builtin functions or variables */
+#ifdef TCC_ARM_EABI
+     DEF(TOK_memcpy, "__aeabi_memcpy")
+     DEF(TOK_memcpy4, "__aeabi_memcpy4")
+     DEF(TOK_memcpy8, "__aeabi_memcpy8")
+     DEF(TOK_memset, "__aeabi_memset")
+     DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
+     DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
+#else
+     DEF(TOK_memcpy, "memcpy")
+     DEF(TOK_memset, "memset")
+     DEF(TOK___divdi3, "__divdi3")
+     DEF(TOK___moddi3, "__moddi3")
+     DEF(TOK___udivdi3, "__udivdi3")
+     DEF(TOK___umoddi3, "__umoddi3")
+#endif
+#if defined(TCC_TARGET_ARM)
+#ifdef TCC_ARM_EABI
+     DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
+     DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
+     DEF(TOK___divsi3, "__aeabi_idiv")
+     DEF(TOK___udivsi3, "__aeabi_uidiv")
+     DEF(TOK___floatdisf, "__aeabi_l2f")
+     DEF(TOK___floatdidf, "__aeabi_l2d")
+     DEF(TOK___fixsfdi, "__aeabi_f2lz")
+     DEF(TOK___fixdfdi, "__aeabi_d2lz")
+#else
+     DEF(TOK___modsi3, "__modsi3")
+     DEF(TOK___umodsi3, "__umodsi3")
+     DEF(TOK___divsi3, "__divsi3")
+     DEF(TOK___udivsi3, "__udivsi3")
+     DEF(TOK___floatdisf, "__floatdisf")
+     DEF(TOK___floatdidf, "__floatdidf")
+#ifndef TCC_ARM_VFP
+     DEF(TOK___floatdixf, "__floatdixf")
+     DEF(TOK___fixunssfsi, "__fixunssfsi")
+     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
+     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
+     DEF(TOK___fixxfdi, "__fixxfdi")
+#endif
+     DEF(TOK___fixsfdi, "__fixsfdi")
+     DEF(TOK___fixdfdi, "__fixdfdi")
+#endif
+#elif defined(TCC_TARGET_C67)
+     DEF(TOK__divi, "_divi")
+     DEF(TOK__divu, "_divu")
+     DEF(TOK__divf, "_divf")
+     DEF(TOK__divd, "_divd")
+     DEF(TOK__remi, "_remi")
+     DEF(TOK__remu, "_remu")
+#endif
+#ifdef TCC_TARGET_I386
+     DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control")
+     DEF(TOK___tcc_fpu_control, "__tcc_fpu_control")
+#endif
+#ifdef TCC_ARM_EABI
+     DEF(TOK___ashrdi3, "__aeabi_lasr")
+     DEF(TOK___lshrdi3, "__aeabi_llsr")
+     DEF(TOK___ashldi3, "__aeabi_llsl")
+     DEF(TOK___floatundisf, "__aeabi_ul2f")
+     DEF(TOK___floatundidf, "__aeabi_ul2d")
+     DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
+     DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
+#else
+     DEF(TOK___ashrdi3, "__ashrdi3")
+     DEF(TOK___lshrdi3, "__lshrdi3")
+     DEF(TOK___ashldi3, "__ashldi3")
+     DEF(TOK___floatundisf, "__floatundisf")
+     DEF(TOK___floatundidf, "__floatundidf")
+#ifndef TCC_ARM_VFP
+     DEF(TOK___floatundixf, "__floatundixf")
+     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
+#endif
+     DEF(TOK___fixunssfdi, "__fixunssfdi")
+     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
+#endif
+#ifdef TCC_TARGET_PE
+     DEF(TOK___chkstk, "__chkstk")
+#endif
+
+/* bound checking symbols */
+#ifdef CONFIG_TCC_BCHECK
+     DEF(TOK___bound_ptr_add, "__bound_ptr_add")
+     DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
+     DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
+     DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
+     DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
+     DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
+     DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
+     DEF(TOK___bound_local_new, "__bound_local_new")
+     DEF(TOK___bound_local_delete, "__bound_local_delete")
+#if 0
+     DEF(TOK_malloc, "malloc")
+     DEF(TOK_free, "free")
+     DEF(TOK_realloc, "realloc")
+     DEF(TOK_memalign, "memalign")
+     DEF(TOK_calloc, "calloc")
+#endif
+     DEF(TOK_memmove, "memmove")
+     DEF(TOK_strlen, "strlen")
+     DEF(TOK_strcpy, "strcpy")
+     DEF(TOK_alloca, "alloca")
+#endif
+
+/* Tiny Assembler */
+
+ DEF_ASM(byte)
+ DEF_ASM(align)
+ DEF_ASM(skip)
+ DEF_ASM(space)
+ DEF_ASM(string)
+ DEF_ASM(asciz)
+ DEF_ASM(ascii)
+ DEF_ASM(globl)
+ DEF_ASM(global)
+ DEF_ASM(text)
+ DEF_ASM(data)
+ DEF_ASM(bss)
+ DEF_ASM(previous)
+ DEF_ASM(fill)
+ DEF_ASM(org)
+ DEF_ASM(quad)
+
+#ifdef TCC_TARGET_I386
+
+/* WARNING: relative order of tokens is important. */
+ DEF_ASM(al)
+ DEF_ASM(cl)
+ DEF_ASM(dl)
+ DEF_ASM(bl)
+ DEF_ASM(ah)
+ DEF_ASM(ch)
+ DEF_ASM(dh)
+ DEF_ASM(bh)
+ DEF_ASM(ax)
+ DEF_ASM(cx)
+ DEF_ASM(dx)
+ DEF_ASM(bx)
+ DEF_ASM(sp)
+ DEF_ASM(bp)
+ DEF_ASM(si)
+ DEF_ASM(di)
+ DEF_ASM(eax)
+ DEF_ASM(ecx)
+ DEF_ASM(edx)
+ DEF_ASM(ebx)
+ DEF_ASM(esp)
+ DEF_ASM(ebp)
+ DEF_ASM(esi)
+ DEF_ASM(edi)
+ DEF_ASM(mm0)
+ DEF_ASM(mm1)
+ DEF_ASM(mm2)
+ DEF_ASM(mm3)
+ DEF_ASM(mm4)
+ DEF_ASM(mm5)
+ DEF_ASM(mm6)
+ DEF_ASM(mm7)
+ DEF_ASM(xmm0)
+ DEF_ASM(xmm1)
+ DEF_ASM(xmm2)
+ DEF_ASM(xmm3)
+ DEF_ASM(xmm4)
+ DEF_ASM(xmm5)
+ DEF_ASM(xmm6)
+ DEF_ASM(xmm7)
+ DEF_ASM(cr0)
+ DEF_ASM(cr1)
+ DEF_ASM(cr2)
+ DEF_ASM(cr3)
+ DEF_ASM(cr4)
+ DEF_ASM(cr5)
+ DEF_ASM(cr6)
+ DEF_ASM(cr7)
+ DEF_ASM(tr0)
+ DEF_ASM(tr1)
+ DEF_ASM(tr2)
+ DEF_ASM(tr3)
+ DEF_ASM(tr4)
+ DEF_ASM(tr5)
+ DEF_ASM(tr6)
+ DEF_ASM(tr7)
+ DEF_ASM(db0)
+ DEF_ASM(db1)
+ DEF_ASM(db2)
+ DEF_ASM(db3)
+ DEF_ASM(db4)
+ DEF_ASM(db5)
+ DEF_ASM(db6)
+ DEF_ASM(db7)
+ DEF_ASM(dr0)
+ DEF_ASM(dr1)
+ DEF_ASM(dr2)
+ DEF_ASM(dr3)
+ DEF_ASM(dr4)
+ DEF_ASM(dr5)
+ DEF_ASM(dr6)
+ DEF_ASM(dr7)
+ DEF_ASM(es)
+ DEF_ASM(cs)
+ DEF_ASM(ss)
+ DEF_ASM(ds)
+ DEF_ASM(fs)
+ DEF_ASM(gs)
+ DEF_ASM(st)
+
+ DEF_BWL(mov)
+
+ /* generic two operands */
+ DEF_BWL(add)
+ DEF_BWL(or)
+ DEF_BWL(adc)
+ DEF_BWL(sbb)
+ DEF_BWL(and)
+ DEF_BWL(sub)
+ DEF_BWL(xor)
+ DEF_BWL(cmp)
+
+ /* unary ops */
+ DEF_BWL(inc)
+ DEF_BWL(dec)
+ DEF_BWL(not)
+ DEF_BWL(neg)
+ DEF_BWL(mul)
+ DEF_BWL(imul)
+ DEF_BWL(div)
+ DEF_BWL(idiv)
+
+ DEF_BWL(xchg)
+ DEF_BWL(test)
+
+ /* shifts */
+ DEF_BWL(rol)
+ DEF_BWL(ror)
+ DEF_BWL(rcl)
+ DEF_BWL(rcr)
+ DEF_BWL(shl)
+ DEF_BWL(shr)
+ DEF_BWL(sar)
+
+ DEF_ASM(shldw)
+ DEF_ASM(shldl)
+ DEF_ASM(shld)
+ DEF_ASM(shrdw)
+ DEF_ASM(shrdl)
+ DEF_ASM(shrd)
+
+ DEF_ASM(pushw)
+ DEF_ASM(pushl)
+ DEF_ASM(push)
+ DEF_ASM(popw)
+ DEF_ASM(popl)
+ DEF_ASM(pop)
+ DEF_BWL(in)
+ DEF_BWL(out)
+
+ DEF_WL(movzb)
+
+ DEF_ASM(movzwl)
+ DEF_ASM(movsbw)
+ DEF_ASM(movsbl)
+ DEF_ASM(movswl)
+
+ DEF_WL(lea) 
+
+ DEF_ASM(les) 
+ DEF_ASM(lds) 
+ DEF_ASM(lss) 
+ DEF_ASM(lfs) 
+ DEF_ASM(lgs) 
+
+ DEF_ASM(call)
+ DEF_ASM(jmp)
+ DEF_ASM(lcall)
+ DEF_ASM(ljmp)
+ 
+ DEF_ASMTEST(j)
+
+ DEF_ASMTEST(set)
+ DEF_ASMTEST(cmov)
+
+ DEF_WL(bsf)
+ DEF_WL(bsr)
+ DEF_WL(bt)
+ DEF_WL(bts)
+ DEF_WL(btr)
+ DEF_WL(btc)
+
+ DEF_WL(lsl)
+
+ /* generic FP ops */
+ DEF_FP(add)
+ DEF_FP(mul)
+
+ DEF_ASM(fcom)
+ DEF_ASM(fcom_1) /* non existant op, just to have a regular table */
+ DEF_FP1(com)
+
+ DEF_FP(comp)
+ DEF_FP(sub)
+ DEF_FP(subr)
+ DEF_FP(div)
+ DEF_FP(divr)
+
+ DEF_BWL(xadd)
+ DEF_BWL(cmpxchg)
+
+ /* string ops */
+ DEF_BWL(cmps)
+ DEF_BWL(scmp)
+ DEF_BWL(ins)
+ DEF_BWL(outs)
+ DEF_BWL(lods)
+ DEF_BWL(slod)
+ DEF_BWL(movs)
+ DEF_BWL(smov)
+ DEF_BWL(scas)
+ DEF_BWL(ssca)
+ DEF_BWL(stos)
+ DEF_BWL(ssto)
+
+ /* generic asm ops */
+
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#include "i386-asm.h"
+
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
+#include "i386-asm.h"
+
+#endif
diff --git a/tinyc/tests/asmtest.S b/tinyc/tests/asmtest.S
new file mode 100755
index 000000000..358a8239f
--- /dev/null
+++ b/tinyc/tests/asmtest.S
@@ -0,0 +1,558 @@
+
+/* some directive tests */
+
+   .byte 0xff
+   .byte 1, 2, 3
+   .short 1, 2, 3
+   .word 1, 2, 3
+   .long 1, 2, 3
+   .int 1, 2, 3
+   .align 8
+   .byte 1
+   .align 16, 0x90
+   .skip 3
+   .skip 15, 0x90
+   .string "hello\0world"
+
+/* some label tests */
+
+        movl %eax, %ebx
+L1:
+        movl %eax, %ebx
+        mov 0x10000, %eax
+L2:
+        movl $L2 - L1, %ecx
+var1:
+        nop ; nop ; nop ; nop
+
+        mov var1, %eax
+
+/* instruction tests */
+movl %eax, %ebx
+mov 0x10000, %eax
+mov 0x10000, %ax
+mov 0x10000, %al
+mov %al, 0x10000
+                
+mov $1, %edx
+mov $1, %dx
+mov $1, %dl
+movb $2, 0x100(%ebx,%edx,2)
+movw $2, 0x100(%ebx,%edx,2)
+movl $2, 0x100(%ebx,%edx,2)
+movl %eax, 0x100(%ebx,%edx,2)
+movl 0x100(%ebx,%edx,2), %edx
+movw %ax, 0x100(%ebx,%edx,2)
+
+mov %eax, 0x12(,%edx,2)
+        
+mov %cr3, %edx
+mov %ecx, %cr3
+movl %cr3, %eax
+movl %tr3, %eax
+movl %db3, %ebx
+movl %dr6, %eax
+movl %fs, %ecx
+movl %ebx, %fs
+
+     movsbl 0x1000, %eax
+     movsbw 0x1000, %ax
+     movswl 0x1000, %eax
+
+     movzbl 0x1000, %eax
+     movzbw 0x1000, %ax
+     movzwl 0x1000, %eax
+            
+     movzb 0x1000, %eax
+     movzb 0x1000, %ax
+                
+        
+  pushl %eax
+  pushw %ax
+  push %eax
+  push %cs
+  push %gs
+  push $1
+  push $100
+                                                
+  popl %eax
+  popw %ax
+  pop %eax
+  pop %ds
+  pop %fs
+          
+  xchg %eax, %ecx
+  xchg %edx, %eax
+  xchg %bx, 0x10000
+  xchg 0x10000, %ebx
+  xchg 0x10000, %dl
+
+  in $100, %al               
+  in $100, %ax               
+  in $100, %eax
+  in %dx, %al
+  in %dx, %ax               
+  in %dx, %eax
+  inb %dx
+  inw %dx               
+  inl %dx
+
+  out %al, $100                       
+  out %ax, $100                       
+  out %eax, $100                       
+
+  /* NOTE: gas is bugged here, so size must be added */
+  outb %al, %dx                       
+  outw %ax, %dx                       
+  outl %eax, %dx                       
+
+  leal 0x1000(%ebx), %ecx
+  lea 0x1000(%ebx), %ecx
+
+  les 0x2000, %eax
+  lds 0x2000, %ebx
+  lfs 0x2000, %ecx
+  lgs 0x2000, %edx
+  lss 0x2000, %edx
+
+addl $0x123, %eax
+add $0x123, %ebx
+addl $0x123, 0x100
+addl $0x123, 0x100(%ebx)
+addl $0x123, 0x100(%ebx,%edx,2)
+addl $0x123, 0x100(%esp)
+addl $0x123, (%ebp)
+addl $0x123, (%esp)
+cmpl $0x123, (%esp)
+
+add %eax, (%ebx)
+add (%ebx), %eax
+                
+or %dx, (%ebx)
+or (%ebx), %si
+        
+add %cl, (%ebx)
+add (%ebx), %dl
+
+    inc %edx
+    incl 0x10000
+    incb 0x10000
+    dec %dx
+  
+  test $1, %al
+  test $1, %cl
+
+  testl $1, 0x1000
+  testb $1, 0x1000
+  testw $1, 0x1000
+  test %eax, %ebx
+  test %eax, 0x1000
+  test 0x1000, %edx
+
+    not %edx
+    notw 0x10000
+    notl 0x10000
+    notb 0x10000
+
+    neg %edx
+    negw 0x10000
+    negl 0x10000
+    negb 0x10000
+
+    imul %ecx
+    mul %edx
+    mulb %cl
+
+    imul %eax, %ecx
+    imul 0x1000, %cx
+    imul $10, %eax, %ecx
+    imul $10, %ax, %cx
+    imul $10, %eax
+    imul $0x1100000, %eax
+    imul $1, %eax
+    
+    idivw 0x1000
+    div %ecx
+    div %bl
+    div %ecx, %eax
+
+
+shl %edx
+shl $10, %edx
+shl %cl, %edx
+
+shld $1, %eax, %edx
+shld %cl, %eax, %edx
+shld %eax, %edx
+
+shrd $1, %eax, %edx
+shrd %cl, %eax, %edx
+shrd %eax, %edx
+
+L4:
+call 0x1000
+call L4
+call *%eax
+call *0x1000
+call func1
+
+lcall $0x100, $0x1000
+
+jmp 0x1000
+jmp *%eax
+jmp *0x1000
+
+ljmp $0x100, $0x1000
+
+ret
+
+ret $10
+
+lret
+
+lret $10
+
+enter $1234, $10
+
+L3:
+ jo 0x1000
+ jnp 0x1001
+ jne 0x1002
+ jg 0x1003
+
+ jo L3
+ jnp L3
+ jne L3
+ jg L3
+
+ loopne L3
+ loopnz L3
+ loope L3
+ loopz L3
+ loop L3
+ jecxz L3
+
+        
+ seto %al
+ setnp 0x1000
+ setl 0xaaaa
+ setg %dl
+
+ fadd
+ fadd %st(1), %st
+ fadd %st(3)
+
+ faddp %st(5)
+ faddp
+ faddp %st(1), %st
+
+ fadds 0x1000
+ fiadds 0x1002
+ faddl 0x1004
+ fiaddl 0x1006
+
+ fmul
+ fmul %st(1), %st
+ fmul %st(3)
+
+ fmulp %st(5)
+ fmulp
+ fmulp %st(1), %st
+
+ fmuls 0x1000
+ fimuls 0x1002
+ fmull 0x1004
+ fimull 0x1006
+
+ fsub
+ fsub %st(1), %st
+ fsub %st(3)
+
+ fsubp %st(5)
+ fsubp
+ fsubp %st(1), %st
+
+ fsubs 0x1000
+ fisubs 0x1002
+ fsubl 0x1004
+ fisubl 0x1006
+
+ fsubr
+ fsubr %st(1), %st
+ fsubr %st(3)
+
+ fsubrp %st(5)
+ fsubrp
+ fsubrp %st(1), %st
+
+ fsubrs 0x1000
+ fisubrs 0x1002
+ fsubrl 0x1004
+ fisubrl 0x1006
+
+ fdiv
+ fdiv %st(1), %st
+ fdiv %st(3)
+
+ fdivp %st(5)
+ fdivp
+ fdivp %st(1), %st
+
+ fdivs 0x1000
+ fidivs 0x1002
+ fdivl 0x1004
+ fidivl 0x1006
+
+ fcom %st(3)
+
+ fcoms 0x1000
+ ficoms 0x1002
+ fcoml 0x1004
+ ficoml 0x1006
+
+ fcomp %st(5)
+ fcomp
+ fcompp
+
+ fcomps 0x1000
+ ficomps 0x1002
+ fcompl 0x1004
+ ficompl 0x1006
+
+ fld %st(5)
+ fldl 0x1000
+ flds 0x1002
+ fildl 0x1004
+ fst %st(4)
+ fstp %st(6)
+ fstpt 0x1006
+ fbstp 0x1008
+
+ fxch
+ fxch %st(4)
+
+ fucom %st(6)
+ fucomp %st(3)
+ fucompp
+
+ finit
+ fninit
+ fldcw 0x1000
+ fnstcw 0x1002
+ fstcw 0x1002
+ fnstsw 0x1004
+ fnstsw %eax
+ fstsw 0x1004
+ fstsw %eax
+ fnclex
+ fclex
+ fnstenv 0x1000
+ fstenv 0x1000
+ fldenv 0x1000
+ fnsave 0x1002
+ fsave 0x1000
+ frstor 0x1000
+ ffree %st(7)
+ ffreep %st(6)
+ 
+    ftst
+    fxam
+    fld1
+    fldl2t
+    fldl2e
+    fldpi
+    fldlg2
+    fldln2
+    fldz
+
+    f2xm1
+    fyl2x
+    fptan
+    fpatan
+    fxtract
+    fprem1
+    fdecstp
+    fincstp
+    fprem
+    fyl2xp1
+    fsqrt
+    fsincos
+    frndint
+    fscale
+    fsin
+    fcos
+    fchs
+    fabs
+    fnop
+    fwait
+
+bswap %edx
+xadd %ecx, %edx
+xaddb %dl, 0x1000
+xaddw %ax, 0x1000
+xaddl %eax, 0x1000
+cmpxchg %ecx, %edx
+cmpxchgb %dl, 0x1000
+cmpxchgw %ax, 0x1000
+cmpxchgl %eax, 0x1000
+invlpg 0x1000
+cmpxchg8b 0x1002
+
+fcmovb %st(5), %st
+fcmove %st(5), %st
+fcmovbe %st(5), %st
+fcmovu %st(5), %st
+fcmovnb %st(5), %st
+fcmovne %st(5), %st
+fcmovnbe %st(5), %st
+fcmovnu %st(5), %st
+fcomi %st(5), %st
+fucomi %st(5), %st
+fcomip %st(5), %st
+fucomip %st(5), %st
+
+
+
+ cmovo 0x1000, %eax
+ cmovs 0x1000, %eax
+ cmovns %edx, %edi
+
+int $3
+int $0x10
+
+    pusha
+    popa
+    clc
+    cld
+    cli
+    clts
+    cmc
+    lahf
+    sahf
+    pushfl
+    popfl
+    pushf
+    popf
+    stc
+    std
+    sti
+    aaa
+    aas
+    daa
+    das
+    aad
+    aam
+    cbw
+    cwd
+    cwde
+    cdq
+    cbtw
+    cwtd
+    cwtl
+    cltd
+    leave
+    int3
+    into
+    iret
+    rsm
+    hlt
+    wait
+    nop
+
+    /* XXX: handle prefixes */
+#if 0
+    aword
+    addr16
+#endif
+    lock
+    rep
+    repe
+    repz
+    repne
+    repnz
+    
+    invd
+    wbinvd
+    cpuid
+    wrmsr
+    rdtsc
+    rdmsr
+    rdpmc
+    ud2
+
+    emms
+    movd %edx, %mm3
+    movd 0x1000, %mm2
+    movd %mm4, %ecx
+    movd %mm5, 0x1000
+                    
+    movq 0x1000, %mm2
+    movq %mm4, 0x1000
+    
+    pand 0x1000, %mm3
+    pand %mm4, %mm5
+    
+    psllw $1, %mm6
+    psllw 0x1000, %mm7
+    psllw %mm2, %mm7
+
+    xlat
+    cmpsb
+    scmpw
+    insl
+    outsw
+    lodsb
+    slodl
+    movsb
+    movsl
+    smovb
+    scasb
+    sscaw
+    stosw
+    sstol
+
+    bsf 0x1000, %ebx
+    bsr 0x1000, %ebx
+    bt %edx, 0x1000
+    btl $2, 0x1000
+    btc %edx, 0x1000
+    btcl $2, 0x1000
+    btr %edx, 0x1000
+    btrl $2, 0x1000
+    bts %edx, 0x1000
+    btsl $2, 0x1000
+
+        
+        
+    boundl %edx, 0x10000
+    boundw %bx, 0x1000
+    
+    arpl %bx, 0x1000
+    lar 0x1000, %eax
+    lgdt 0x1000
+    lidt 0x1000
+    lldt 0x1000
+    lmsw 0x1000
+    lsl 0x1000, %ecx
+    ltr 0x1000
+    
+    sgdt 0x1000
+    sidt 0x1000
+    sldt 0x1000
+    smsw 0x1000
+    str 0x1000
+    
+    verr 0x1000
+    verw 0x1000
+  
+    push %ds
+    pushw %ds
+    pushl %ds
+    pop %ds
+    popw %ds
+    popl %ds
+    fxsave 1(%ebx)
+    fxrstor 1(%ecx)
+    pushl $1
+    pushw $1
+    push $1
diff --git a/tinyc/tests/boundtest.c b/tinyc/tests/boundtest.c
new file mode 100755
index 000000000..9bc982803
--- /dev/null
+++ b/tinyc/tests/boundtest.c
@@ -0,0 +1,214 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define NB_ITS 1000000
+//#define NB_ITS 1
+#define TAB_SIZE 100
+
+int tab[TAB_SIZE];
+int ret_sum;
+char tab3[256];
+
+int test1(void)
+{
+    int i, sum = 0;
+    for(i=0;i<TAB_SIZE;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* error */
+int test2(void)
+{
+    int i, sum = 0;
+    for(i=0;i<TAB_SIZE + 1;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* actually, profiling test */
+int test3(void)
+{
+    int sum;
+    int i, it;
+
+    sum = 0;
+    for(it=0;it<NB_ITS;it++) {
+        for(i=0;i<TAB_SIZE;i++) {
+            sum += tab[i];
+        }
+    }
+    return sum;
+}
+
+/* ok */
+int test4(void)
+{
+    int i, sum = 0;
+    int *tab4;
+
+    tab4 = malloc(20 * sizeof(int));
+    for(i=0;i<20;i++) {
+        sum += tab4[i];
+    }
+    free(tab4);
+
+    return sum;
+}
+
+/* error */
+int test5(void)
+{
+    int i, sum = 0;
+    int *tab4;
+
+    tab4 = malloc(20 * sizeof(int));
+    for(i=0;i<21;i++) {
+        sum += tab4[i];
+    }
+    free(tab4);
+
+    return sum;
+}
+
+/* error */
+/* XXX: currently: bug */
+int test6(void)
+{
+    int i, sum = 0;
+    int *tab4;
+    
+    tab4 = malloc(20 * sizeof(int));
+    free(tab4);
+    for(i=0;i<21;i++) {
+        sum += tab4[i];
+    }
+
+    return sum;
+}
+
+/* error */
+int test7(void)
+{
+    int i, sum = 0;
+    int *p;
+
+    for(i=0;i<TAB_SIZE + 1;i++) {
+        p = &tab[i];
+        if (i == TAB_SIZE)
+            printf("i=%d %x\n", i, p);
+        sum += *p;
+    }
+    return sum;
+}
+
+/* ok */
+int test8(void)
+{
+    int i, sum = 0;
+    int tab[10];
+
+    for(i=0;i<10;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* error */
+int test9(void)
+{
+    int i, sum = 0;
+    char tab[10];
+
+    for(i=0;i<11;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* ok */
+int test10(void)
+{
+    char tab[10];
+    char tab1[10];
+
+    memset(tab, 0, 10);
+    memcpy(tab, tab1, 10);
+    memmove(tab, tab1, 10);
+    return 0;
+}
+
+/* error */
+int test11(void)
+{
+    char tab[10];
+
+    memset(tab, 0, 11);
+    return 0;
+}
+
+/* error */
+int test12(void)
+{
+    void *ptr;
+    ptr = malloc(10);
+    free(ptr);
+    free(ptr);
+    return 0;
+}
+
+/* error */
+int test13(void)
+{
+    char pad1 = 0;
+    char tab[10];
+    char pad2 = 0;
+    memset(tab, 'a', sizeof(tab));
+    return strlen(tab);
+}
+
+int (*table_test[])(void) = {
+    test1,
+    test1,
+    test2,
+    test3,
+    test4,
+    test5,
+    test6,
+    test7,
+    test8,
+    test9,
+    test10,
+    test11,
+    test12,
+    test13,
+};
+
+int main(int argc, char **argv)
+{
+    int index;
+    int (*ftest)(void);
+
+    if (argc < 2) {
+        printf("usage: boundtest n\n"
+               "test TCC bound checking system\n"
+               );
+        exit(1);
+    }
+
+    index = 0;
+    if (argc >= 2)
+        index = atoi(argv[1]);
+    /* well, we also use bounds on this ! */
+    ftest = table_test[index];
+    ftest();
+
+    return 0;
+}
+
+/*
+ * without bound   0.77 s
+ * with bounds    4.73
+ */  
diff --git a/tinyc/tests/gcctestsuite.sh b/tinyc/tests/gcctestsuite.sh
new file mode 100755
index 000000000..bd9204b2b
--- /dev/null
+++ b/tinyc/tests/gcctestsuite.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture
+TCC="./tcc -B. -I. -DNO_TRAMPOLINES" 
+rm -f tcc.sum tcc.log
+nb_failed="0"
+
+for src in $TESTSUITE_PATH/compile/*.c ; do
+  echo $TCC -o /tmp/test.o -c $src 
+  $TCC -o /tmp/test.o -c $src >> tcc.log 2>&1
+  if [ "$?" == "0" ] ; then
+     result="PASS"
+  else
+     result="FAIL"
+     nb_failed=$[ $nb_failed + 1 ]
+  fi
+  echo "$result: $src"  >> tcc.sum
+done
+
+for src in $TESTSUITE_PATH/execute/*.c ; do
+  echo $TCC $src 
+  $TCC $src >> tcc.log 2>&1
+  if [ "$?" == "0" ] ; then
+     result="PASS"
+  else
+     result="FAIL"
+     nb_failed=$[ $nb_failed + 1 ]
+  fi
+  echo "$result: $src"  >> tcc.sum
+done
+
+echo "$nb_failed test(s) failed." >> tcc.sum
+echo "$nb_failed test(s) failed."
diff --git a/tinyc/tests/libtcc_test.c b/tinyc/tests/libtcc_test.c
new file mode 100755
index 000000000..a602fb0f4
--- /dev/null
+++ b/tinyc/tests/libtcc_test.c
@@ -0,0 +1,84 @@
+/*
+ * Simple Test program for libtcc
+ *
+ * libtcc can be useful to use tcc as a "backend" for a code generator.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libtcc.h"
+
+/* this function is called by the generated code */
+int add(int a, int b)
+{
+    return a + b;
+}
+
+char my_program[] =
+"int fib(int n)\n"
+"{\n"
+"    if (n <= 2)\n"
+"        return 1;\n"
+"    else\n"
+"        return fib(n-1) + fib(n-2);\n"
+"}\n"
+"\n"
+"int foo(int n)\n"
+"{\n"
+"    printf(\"Hello World!\\n\");\n"
+"    printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
+"    printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
+"    return 0;\n"
+"}\n";
+
+int main(int argc, char **argv)
+{
+    TCCState *s;
+    int (*func)(int);
+    void *mem;
+    int size;
+
+    s = tcc_new();
+    if (!s) {
+        fprintf(stderr, "Could not create tcc state\n");
+        exit(1);
+    }
+
+    /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+    if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
+        tcc_set_lib_path(s, argv[1]+9);
+
+    /* MUST BE CALLED before any compilation */
+    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+
+    if (tcc_compile_string(s, my_program) == -1)
+        return 1;
+
+    /* as a test, we add a symbol that the compiled program can use.
+       You may also open a dll with tcc_add_dll() and use symbols from that */
+    tcc_add_symbol(s, "add", add);
+
+    /* get needed size of the code */
+    size = tcc_relocate(s, NULL);
+    if (size == -1)
+        return 1;
+
+    /* allocate memory and copy the code into it */
+    mem = malloc(size);
+    tcc_relocate(s, mem);
+
+    /* get entry symbol */
+    func = tcc_get_symbol(s, "foo");
+    if (!func)
+        return 1;
+
+    /* delete the state */
+    tcc_delete(s);
+
+    /* run the code */
+    func(32);
+
+    free(mem);
+    return 0;
+}
diff --git a/tinyc/tests/tcctest.c b/tinyc/tests/tcctest.c
new file mode 100755
index 000000000..a2d481a6a
--- /dev/null
+++ b/tinyc/tests/tcctest.c
@@ -0,0 +1,2202 @@
+/*
+ * TCC auto test program
+ */
+#include "../config.h"
+
+#if GCC_MAJOR >= 3
+
+/* Unfortunately, gcc version < 3 does not handle that! */
+#define ALL_ISOC99
+
+/* only gcc 3 handles _Bool correctly */
+#define BOOL_ISOC99
+
+/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
+#define CORRECT_CR_HANDLING
+
+#endif
+
+/* deprecated and no longer supported in gcc 3.3 */
+//#define ACCEPT_CR_IN_STRINGS
+
+/* __VA_ARGS__ and __func__ support */
+#define C99_MACROS
+
+/* test various include syntaxes */
+
+#define TCCLIB_INC <tcclib.h>
+#define TCCLIB_INC1 <tcclib
+#define TCCLIB_INC2 h>
+#define TCCLIB_INC3 "tcclib"
+
+#include TCCLIB_INC
+
+#include TCCLIB_INC1.TCCLIB_INC2
+
+#include TCCLIB_INC1.h>
+
+/* gcc 3.2 does not accept that (bug ?) */
+//#include TCCLIB_INC3 ".h"
+
+#include <tcclib.h>
+
+#include "tcclib.h"
+
+void string_test();
+void expr_test();
+void macro_test();
+void scope_test();
+void forward_test();
+void funcptr_test();
+void loop_test();
+void switch_test();
+void goto_test();
+void enum_test();
+void typedef_test();
+void struct_test();
+void array_test();
+void expr_ptr_test();
+void bool_test();
+void expr2_test();
+void constant_expr_test();
+void expr_cmp_test();
+void char_short_test();
+void init_test(void);
+void compound_literal_test(void);
+int kr_test();
+void struct_assign_test(void);
+void cast_test(void);
+void bitfield_test(void);
+void c99_bool_test(void);
+void float_test(void);
+void longlong_test(void);
+void manyarg_test(void);
+void stdarg_test(void);
+void whitespace_test(void);
+void relocation_test(void);
+void old_style_function(void);
+void alloca_test(void);
+void sizeof_test(void);
+void typeof_test(void);
+void local_label_test(void);
+void statement_expr_test(void);
+void asm_test(void);
+void builtin_test(void);
+
+int fib(int n);
+void num(int n);
+void forward_ref(void);
+int isid(int c);
+
+#define A 2
+#define N 1234 + A
+#define pf printf
+#define M1(a, b)  (a) + (b)
+
+#define str\
+(s) # s
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#ifdef C99_MACROS
+#define dprintf(level,...) printf(__VA_ARGS__)
+#endif
+
+/* gcc vararg macros */
+#define dprintf1(level, fmt, args...) printf(fmt, ## args)
+
+#define MACRO_NOARGS()
+
+#define AAA 3
+#undef AAA
+#define AAA 4
+
+#if 1
+#define B3 1
+#elif 1
+#define B3 2
+#elif 0
+#define B3 3
+#else
+#define B3 4
+#endif
+
+#define __INT64_C(c)	c ## LL
+#define INT64_MIN	(-__INT64_C(9223372036854775807)-1)
+
+int qq(int x)
+{
+    return x + 40;
+}
+#define qq(x) x
+
+#define spin_lock(lock) do { } while (0)
+#define wq_spin_lock spin_lock
+#define TEST2() wq_spin_lock(a)
+
+void macro_test(void)
+{
+    printf("macro:\n");

+    pf("N=%d\n", N);
+    printf("aaa=%d\n", AAA);
+
+    printf("min=%d\n", min(1, min(2, -1)));
+
+    printf("s1=%s\n", glue(HIGH, LOW));
+    printf("s2=%s\n", xglue(HIGH, LOW));
+    printf("s3=%s\n", str("c"));
+    printf("s4=%s\n", str(a1));
+    printf("B3=%d\n", B3);
+
+#ifdef A
+    printf("A defined\n");
+#endif
+#ifdef B
+    printf("B defined\n");
+#endif
+#ifdef A
+    printf("A defined\n");
+#else
+    printf("A not defined\n");
+#endif
+#ifdef B
+    printf("B defined\n");
+#else
+    printf("B not defined\n");
+#endif
+
+#ifdef A
+    printf("A defined\n");
+#ifdef B
+    printf("B1 defined\n");
+#else
+    printf("B1 not defined\n");
+#endif
+#else
+    printf("A not defined\n");
+#ifdef B
+    printf("B2 defined\n");
+#else
+    printf("B2 not defined\n");
+#endif
+#endif
+
+#if 1+1
+    printf("test true1\n");
+#endif
+#if 0
+    printf("test true2\n");
+#endif
+#if 1-1
+    printf("test true3\n");
+#endif
+#if defined(A)
+    printf("test trueA\n");
+#endif
+#if defined(B)
+    printf("test trueB\n");
+#endif
+
+#if 0
+    printf("test 0\n");
+#elif 0
+    printf("test 1\n");
+#elif 2
+    printf("test 2\n");
+#else
+    printf("test 3\n");
+#endif
+
+    MACRO_NOARGS();
+
+#ifdef __LINE__
+    printf("__LINE__ defined\n");
+#endif
+
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#line 200
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#line 203 "test" 
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#line 227 "tcctest.c"
+
+    /* not strictly preprocessor, but we test it there */
+#ifdef C99_MACROS
+    printf("__func__ = %s\n", __func__);
+    dprintf(1, "vaarg=%d\n", 1);
+#endif
+    dprintf1(1, "vaarg1\n");
+    dprintf1(1, "vaarg1=%d\n", 2);
+    dprintf1(1, "vaarg1=%d %d\n", 1, 2);
+
+    /* gcc extension */
+    printf("func='%s'\n", __FUNCTION__);
+
+    /* complicated macros in glibc */
+    printf("INT64_MIN=%Ld\n", INT64_MIN);
+    {
+        int a;
+        a = 1;
+        glue(a+, +);
+        printf("a=%d\n", a);
+        glue(a <, <= 2);
+        printf("a=%d\n", a);
+    }
+    
+    /* macro function with argument outside the macro string */
+#define MF_s MF_hello
+#define MF_hello(msg) printf("%s\n",msg)
+
+#define MF_t printf("tralala\n"); MF_hello
+
+    MF_s("hi");
+    MF_t("hi");
+    
+    /* test macro substituion inside args (should not eat stream) */
+    printf("qq=%d\n", qq(qq)(2));
+
+    /* test zero argument case. NOTE: gcc 2.95.x does not accept a
+       null argument without a space. gcc 3.2 fixes that. */
+
+#define qq1(x) 1
+    printf("qq1=%d\n", qq1( ));
+
+    /* comment with stray handling *\
+/
+       /* this is a valid *\/ comment */
+       /* this is a valid comment *\*/
+    //  this is a valid\
+comment
+
+    /* test function macro substitution when the function name is
+       substituted */
+    TEST2();
+}
+
+int op(a,b)
+{
+    return a / b;
+}
+
+int ret(a)
+{
+    if (a == 2)
+        return 1;
+    if (a == 3)
+        return 2;
+    return 0;
+}
+
+void ps(const char *s)
+{
+    int c;
+    while (1) {
+        c = *s;
+        if (c == 0)
+            break;
+        printf("%c", c);
+        s++;
+    }
+}
+
+const char foo1_string[] = "\
+bar\n\
+test\14\
+1";
+
+void string_test()
+{
+    unsigned int b;
+    printf("string:\n");
+    printf("\141\1423\143\n");/* dezdez test */
+    printf("\x41\x42\x43\x3a\n");
+    printf("c=%c\n", 'r');
+    printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
+    printf("foo1_string='%s'\n", foo1_string);
+#if 0
+    printf("wstring=%S\n", L"abc");
+    printf("wstring=%S\n", L"abc" L"def" "ghi");
+    printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
+    printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
+#endif
+    ps("test\n");
+    b = 32;
+    while ((b = b + 1) < 96) {
+        printf("%c", b);
+    }
+    printf("\n");
+    printf("fib=%d\n", fib(33));
+    b = 262144;
+    while (b != 0x80000000) {
+        num(b);
+        b = b * 2;
+    }
+}
+
+void loop_test()
+{
+    int i;
+    i = 0;
+    while (i < 10)
+        printf("%d", i++);
+    printf("\n");
+    for(i = 0; i < 10;i++)
+        printf("%d", i);
+    printf("\n");
+    i = 0;
+    do {
+        printf("%d", i++);
+    } while (i < 10);
+    printf("\n");
+
+    /* break/continue tests */
+    i = 0;
+    while (1) {
+        if (i == 6)
+            break;
+        i++;
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    }
+    printf("\n");
+
+    /* break/continue tests */
+    i = 0;
+    do {
+        if (i == 6)
+            break;
+        i++;
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    } while(1);
+    printf("\n");
+
+    for(i = 0;i < 10;i++) {
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    }
+    printf("\n");
+}
+
+
+void goto_test()
+{
+    int i;
+    static void *label_table[3] = { &&label1, &&label2, &&label3 };
+
+    printf("goto:\n");
+    i = 0;
+ s_loop:
+    if (i >= 10) 
+        goto s_end;
+    printf("%d", i);
+    i++;
+    goto s_loop;
+ s_end:
+    printf("\n");
+
+    /* we also test computed gotos (GCC extension) */
+    for(i=0;i<3;i++) {
+        goto *label_table[i];
+    label1:
+        printf("label1\n");
+        goto next;
+    label2:
+        printf("label2\n");
+        goto next;
+    label3:
+        printf("label3\n");
+    next: ;
+    }
+}
+
+enum {
+    E0,
+    E1 = 2,
+    E2 = 4,
+    E3,
+    E4,
+};
+
+enum test {
+    E5 = 1000,
+};
+
+void enum_test()
+{
+    enum test b1;
+    printf("enum:\n%d %d %d %d %d %d\n",
+           E0, E1, E2, E3, E4, E5);
+    b1 = 1;
+    printf("b1=%d\n", b1);
+}
+
+typedef int *my_ptr;
+
+typedef int mytype1;
+typedef int mytype2;
+
+void typedef_test()
+{
+    my_ptr a;
+    mytype1 mytype2;
+    int b;
+
+    a = &b;
+    *a = 1234;
+    printf("typedef:\n");
+    printf("a=%d\n", *a);
+    mytype2 = 2;
+    printf("mytype2=%d\n", mytype2);
+}
+
+void forward_test()
+{
+    printf("forward:\n");
+    forward_ref();
+    forward_ref();
+}
+
+
+void forward_ref(void)
+{
+    printf("forward ok\n");
+}
+
+typedef struct struct1 {
+    int f1;
+    int f2, f3;
+    union union1 {
+        int v1;
+        int v2;
+    } u;
+    char str[3];
+} struct1;
+
+struct struct2 {
+    int a;
+    char b;
+};
+
+union union2 {
+    int w1;
+    int w2;
+};
+
+struct struct1 st1, st2;
+
+int main(int argc, char **argv)
+{
+    string_test();
+    expr_test();
+    macro_test();
+    scope_test();
+    forward_test();
+    funcptr_test();
+    loop_test();
+    switch_test();
+    goto_test();
+    enum_test();
+    typedef_test();
+    struct_test();
+    array_test();
+    expr_ptr_test();
+    bool_test();
+    expr2_test();
+    constant_expr_test();
+    expr_cmp_test();
+    char_short_test();
+    init_test();
+    compound_literal_test();
+    kr_test();
+    struct_assign_test();
+    cast_test();
+    bitfield_test();
+    c99_bool_test();
+    float_test();
+    longlong_test();
+    manyarg_test();
+    stdarg_test();
+    whitespace_test();
+    relocation_test();
+    old_style_function();
+    alloca_test();
+    sizeof_test();
+    typeof_test();
+    statement_expr_test();
+    local_label_test();
+    asm_test();
+    builtin_test();
+    return 0; 
+}
+
+int tab[3];
+int tab2[3][2];
+
+int g;
+
+void f1(g)
+{
+    printf("g1=%d\n", g);
+}
+
+void scope_test()
+{
+    printf("scope:\n");
+    g = 2;
+    f1(1);
+    printf("g2=%d\n", g);
+    {
+        int g;
+        g = 3;
+        printf("g3=%d\n", g);
+        {
+            int g;
+            g = 4;
+            printf("g4=%d\n", g);
+        }
+    }
+    printf("g5=%d\n", g);
+}
+
+void array_test(int a[4])
+{
+    int i, j;
+
+    printf("array:\n");
+    printf("sizeof(a) = %d\n", sizeof(a));
+    printf("sizeof(\"a\") = %d\n", sizeof("a"));
+#ifdef C99_MACROS
+    printf("sizeof(__func__) = %d\n", sizeof(__func__));
+#endif
+    printf("sizeof tab %d\n", sizeof(tab));
+    printf("sizeof tab2 %d\n", sizeof tab2);
+    tab[0] = 1;
+    tab[1] = 2;
+    tab[2] = 3;
+    printf("%d %d %d\n", tab[0], tab[1], tab[2]);
+    for(i=0;i<3;i++)
+        for(j=0;j<2;j++)
+            tab2[i][j] = 10 * i + j;
+    for(i=0;i<3*2;i++) {
+        printf(" %3d", ((int *)tab2)[i]);
+    }
+    printf("\n");
+}
+
+void expr_test()
+{
+    int a, b;
+    a = 0;
+    printf("%d\n", a += 1);
+    printf("%d\n", a -= 2);
+    printf("%d\n", a *= 31232132);
+    printf("%d\n", a /= 4);
+    printf("%d\n", a %= 20);
+    printf("%d\n", a &= 6);
+    printf("%d\n", a ^= 7);
+    printf("%d\n", a |= 8);
+    printf("%d\n", a >>= 3);
+    printf("%d\n", a <<= 4);
+
+    a = 22321;
+    b = -22321;
+    printf("%d\n", a + 1);
+    printf("%d\n", a - 2);
+    printf("%d\n", a * 312);
+    printf("%d\n", a / 4);
+    printf("%d\n", b / 4);
+    printf("%d\n", (unsigned)b / 4);
+    printf("%d\n", a % 20);
+    printf("%d\n", b % 20);
+    printf("%d\n", (unsigned)b % 20);
+    printf("%d\n", a & 6);
+    printf("%d\n", a ^ 7);
+    printf("%d\n", a | 8);
+    printf("%d\n", a >> 3);
+    printf("%d\n", b >> 3);
+    printf("%d\n", (unsigned)b >> 3);
+    printf("%d\n", a << 4);
+    printf("%d\n", ~a);
+    printf("%d\n", -a);
+    printf("%d\n", +a);
+
+    printf("%d\n", 12 + 1);
+    printf("%d\n", 12 - 2);
+    printf("%d\n", 12 * 312);
+    printf("%d\n", 12 / 4);
+    printf("%d\n", 12 % 20);
+    printf("%d\n", 12 & 6);
+    printf("%d\n", 12 ^ 7);
+    printf("%d\n", 12 | 8);
+    printf("%d\n", 12 >> 2);
+    printf("%d\n", 12 << 4);
+    printf("%d\n", ~12);
+    printf("%d\n", -12);
+    printf("%d\n", +12);
+    printf("%d %d %d %d\n", 
+           isid('a'), 
+           isid('g'), 
+           isid('T'), 
+           isid('('));
+}
+
+int isid(int c)
+{
+    return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
+}
+
+/**********************/
+
+int vstack[10], *vstack_ptr;
+
+void vpush(int vt, int vc)
+{
+    *vstack_ptr++ = vt;
+    *vstack_ptr++ = vc;
+}
+
+void vpop(int *ft, int *fc)
+{
+    *fc = *--vstack_ptr;
+    *ft = *--vstack_ptr;
+}
+
+void expr2_test()
+{
+    int a, b;
+
+    printf("expr2:\n");
+    vstack_ptr = vstack;
+    vpush(1432432, 2);
+    vstack_ptr[-2] &= ~0xffffff80;
+    vpop(&a, &b);
+    printf("res= %d %d\n", a, b);
+}
+
+void constant_expr_test()
+{
+    int a;
+    printf("constant_expr:\n");
+    a = 3;
+    printf("%d\n", a * 16);
+    printf("%d\n", a * 1);
+    printf("%d\n", a + 0);
+}
+
+int tab4[10];
+
+void expr_ptr_test()
+{
+    int *p, *q;
+    int i = -1;
+
+    printf("expr_ptr:\n");
+    p = tab4;
+    q = tab4 + 10;
+    printf("diff=%d\n", q - p);
+    p++;
+    printf("inc=%d\n", p - tab4);
+    p--;
+    printf("dec=%d\n", p - tab4);
+    ++p;
+    printf("inc=%d\n", p - tab4);
+    --p;
+    printf("dec=%d\n", p - tab4);
+    printf("add=%d\n", p + 3 - tab4);
+    printf("add=%d\n", 3 + p - tab4);
+
+    /* check if 64bit support is ok */
+    q = p = 0;
+    q += i;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    i = 0xf0000000;
+    p += i;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    p = (int *)((char *)p + 0xf0000000);
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    p += 0xf0000000;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    {
+        struct size12 {
+            int i, j, k;
+        };
+        struct size12 s[2], *sp = s;
+        int i, j;
+        sp->i = 42;
+        sp++;
+        j = -1;
+        printf("%d\n", sp[j].i);
+    }
+}
+
+void expr_cmp_test()
+{
+    int a, b;
+    printf("constant_expr:\n");
+    a = -1;
+    b = 1;
+    printf("%d\n", a == a);
+    printf("%d\n", a != a);
+
+    printf("%d\n", a < b);
+    printf("%d\n", a <= b);
+    printf("%d\n", a <= a);
+    printf("%d\n", b >= a);
+    printf("%d\n", a >= a);
+    printf("%d\n", b > a);
+
+    printf("%d\n", (unsigned)a < b);
+    printf("%d\n", (unsigned)a <= b);
+    printf("%d\n", (unsigned)a <= a);
+    printf("%d\n", (unsigned)b >= a);
+    printf("%d\n", (unsigned)a >= a);
+    printf("%d\n", (unsigned)b > a);
+}
+
+struct empty {
+};
+
+struct aligntest1 {
+    char a[10];
+};
+
+struct aligntest2 {
+    int a;
+    char b[10];
+};
+
+struct aligntest3 {
+    double a, b;
+};
+
+struct aligntest4 {
+    double a[0];
+};
+
+void struct_test()
+{
+    struct1 *s;
+    union union2 u;
+
+    printf("struct:\n");
+    printf("sizes: %d %d %d %d\n",
+           sizeof(struct struct1),
+           sizeof(struct struct2),
+           sizeof(union union1),
+           sizeof(union union2));
+    st1.f1 = 1;
+    st1.f2 = 2;
+    st1.f3 = 3;
+    printf("st1: %d %d %d\n",
+           st1.f1, st1.f2, st1.f3);
+    st1.u.v1 = 1;
+    st1.u.v2 = 2;
+    printf("union1: %d\n", st1.u.v1);
+    u.w1 = 1;
+    u.w2 = 2;
+    printf("union2: %d\n", u.w1);
+    s = &st2;
+    s->f1 = 3;
+    s->f2 = 2;
+    s->f3 = 1;
+    printf("st2: %d %d %d\n",
+           s->f1, s->f2, s->f3);
+    printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1);
+
+    /* align / size tests */
+    printf("aligntest1 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest1), __alignof__(struct aligntest1));
+    printf("aligntest2 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest2), __alignof__(struct aligntest2));
+    printf("aligntest3 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest3), __alignof__(struct aligntest3));
+    printf("aligntest4 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest4), __alignof__(struct aligntest4));
+           
+    /* empty structures (GCC extension) */
+    printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
+    printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
+}
+
+/* XXX: depend on endianness */
+void char_short_test()
+{
+    int var1, var2;
+
+    printf("char_short:\n");
+
+    var1 = 0x01020304;
+    var2 = 0xfffefdfc;
+    printf("s8=%d %d\n", 
+           *(char *)&var1, *(char *)&var2);
+    printf("u8=%d %d\n", 
+           *(unsigned char *)&var1, *(unsigned char *)&var2);
+    printf("s16=%d %d\n", 
+           *(short *)&var1, *(short *)&var2);
+    printf("u16=%d %d\n", 
+           *(unsigned short *)&var1, *(unsigned short *)&var2);
+    printf("s32=%d %d\n", 
+           *(int *)&var1, *(int *)&var2);
+    printf("u32=%d %d\n", 
+           *(unsigned int *)&var1, *(unsigned int *)&var2);
+    *(char *)&var1 = 0x08;
+    printf("var1=%x\n", var1);
+    *(short *)&var1 = 0x0809;
+    printf("var1=%x\n", var1);
+    *(int *)&var1 = 0x08090a0b;
+    printf("var1=%x\n", var1);
+}
+
+/******************/
+
+typedef struct Sym {
+    int v;
+    int t;
+    int c;
+    struct Sym *next;
+    struct Sym *prev;
+} Sym;
+
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+
+static int toupper1(int a)
+{
+    return TOUPPER(a);
+}
+
+void bool_test()
+{
+    int *s, a, b, t, f, i;
+
+    a = 0;
+    s = (void*)0;
+    printf("!s=%d\n", !s);
+
+    if (!s || !s[0])
+        a = 1;
+    printf("a=%d\n", a);
+
+    printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
+    printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
+    printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
+#if 1 && 1
+    printf("a1\n");
+#endif
+#if 1 || 0
+    printf("a2\n");
+#endif
+#if 1 ? 0 : 1
+    printf("a3\n");
+#endif
+#if 0 ? 0 : 1
+    printf("a4\n");
+#endif
+
+    a = 4;
+    printf("b=%d\n", a + (0 ? 1 : a / 2));
+
+    /* test register spilling */
+    a = 10;
+    b = 10;
+    a = (a + b) * ((a < b) ?
+                   ((b - a) * (a - b)): a + b);
+    printf("a=%d\n", a);
+
+    /* test complex || or && expressions */
+    t = 1;
+    f = 0;
+    a = 32;
+    printf("exp=%d\n", f == (32 <= a && a <= 3));
+    printf("r=%d\n", (t || f) + (t && f));
+
+    /* test ? : cast */
+    {
+        int aspect_on;
+        int aspect_native = 65536;
+        double bfu_aspect = 1.0;
+        int aspect;
+        for(aspect_on = 0; aspect_on < 2; aspect_on++) {
+            aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
+            printf("aspect=%d\n", aspect);
+        }
+    }
+
+    /* test ? : GCC extension */
+    {
+        static int v1 = 34 ? : -1; /* constant case */
+        static int v2 = 0 ? : -1; /* constant case */
+        int a = 30;
+        
+        printf("%d %d\n", v1, v2);
+        printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
+    }
+
+    /* again complex expression */
+    for(i=0;i<256;i++) {
+        if (toupper1 (i) != TOUPPER (i))
+            printf("error %d\n", i);
+    }
+}
+
+/* GCC accepts that */
+static int tab_reinit[];
+static int tab_reinit[10];
+
+//int cinit1; /* a global variable can be defined several times without error ! */
+int cinit1; 
+int cinit1; 
+int cinit1 = 0;
+int *cinit2 = (int []){3, 2, 1};
+
+void compound_literal_test(void)
+{
+    int *p, i;
+    char *q, *q3;
+
+    printf("compound_test:\n");
+
+    p = (int []){1, 2, 3};
+    for(i=0;i<3;i++)
+        printf(" %d", p[i]);
+    printf("\n");
+
+    for(i=0;i<3;i++)
+        printf("%d", cinit2[i]);
+    printf("\n");
+
+    q = "tralala1";
+    printf("q1=%s\n", q);
+
+    q = (char *){ "tralala2" };
+    printf("q2=%s\n", q);
+
+    q3 = (char *){ q };
+    printf("q3=%s\n", q3);
+
+    q = (char []){ "tralala3" };
+    printf("q4=%s\n", q);
+
+#ifdef ALL_ISOC99
+    p = (int []){1, 2, cinit1 + 3};
+    for(i=0;i<3;i++)
+        printf(" %d", p[i]);
+    printf("\n");
+
+    for(i=0;i<3;i++) {
+        p = (int []){1, 2, 4 + i};
+        printf("%d %d %d\n", 
+               p[0],
+               p[1],
+               p[2]);
+    }
+#endif
+}
+
+/* K & R protos */
+
+kr_func1(a, b)
+{
+    return a + b;
+}
+
+int kr_func2(a, b)
+{
+    return a + b;
+}
+
+kr_test()
+{
+    printf("kr_test:\n");
+    printf("func1=%d\n", kr_func1(3, 4));
+    printf("func2=%d\n", kr_func2(3, 4));
+    return 0;
+}
+
+void num(int n)
+{
+    char *tab, *p;
+    tab = (char*)malloc(20); 
+    p = tab;
+    while (1) {
+        *p = 48 + (n % 10);
+        p++;
+        n = n / 10;
+        if (n == 0)
+            break;
+    }
+    while (p != tab) {
+        p--;
+        printf("%c", *p);
+    }
+    printf("\n");
+}
+
+/* structure assignment tests */
+struct structa1 {
+    int f1;
+    char f2;
+};
+
+struct structa1 ssta1;
+
+void struct_assign_test1(struct structa1 s1, int t)
+{
+    printf("%d %d %d\n", s1.f1, s1.f2, t);
+}
+
+struct structa1 struct_assign_test2(struct structa1 s1, int t)
+{
+    s1.f1 += t;
+    s1.f2 -= t;
+    return s1;
+}
+
+void struct_assign_test(void)
+{
+    struct structa1 lsta1, lsta2;
+    
+#if 0
+    printf("struct_assign_test:\n");
+
+    lsta1.f1 = 1;
+    lsta1.f2 = 2;
+    printf("%d %d\n", lsta1.f1, lsta1.f2);
+    lsta2 = lsta1;
+    printf("%d %d\n", lsta2.f1, lsta2.f2);
+#else
+    lsta2.f1 = 1;
+    lsta2.f2 = 2;
+#endif
+    struct_assign_test1(lsta2, 3);
+    
+    printf("before call: %d %d\n", lsta2.f1, lsta2.f2);
+    lsta2 = struct_assign_test2(lsta2, 4);
+    printf("after call: %d %d\n", lsta2.f1, lsta2.f2);
+}
+
+/* casts to short/char */
+
+void cast1(char a, short b, unsigned char c, unsigned short d)
+{
+    printf("%d %d %d %d\n", a, b, c, d);
+}
+
+char bcast;
+short scast;
+
+void cast_test()
+{
+    int a;
+    char c;
+    char tab[10];
+    unsigned b,d;
+    short s;
+    char *p = NULL;
+    p -= 0x700000000042;
+
+    printf("cast_test:\n");
+    a = 0xfffff;
+    cast1(a, a, a, a);
+    a = 0xffffe;
+    printf("%d %d %d %d\n",
+           (char)(a + 1),
+           (short)(a + 1),
+           (unsigned char)(a + 1),
+           (unsigned short)(a + 1));
+    printf("%d %d %d %d\n",
+           (char)0xfffff,
+           (short)0xfffff,
+           (unsigned char)0xfffff,
+           (unsigned short)0xfffff);
+
+    a = (bcast = 128) + 1;
+    printf("%d\n", a);
+    a = (scast = 65536) + 1;
+    printf("%d\n", a);
+    
+    printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
+    
+    /* test cast from unsigned to signed short to int */
+    b = 0xf000;
+    d = (short)b;
+    printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
+    b = 0xf0f0;
+    d = (char)b;
+    printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
+    
+    /* test implicit int casting for array accesses */
+    c = 0;
+    tab[1] = 2;
+    tab[c] = 1;
+    printf("%d %d\n", tab[0], tab[1]);
+
+    /* test implicit casting on some operators */
+    printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
+    printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
+    printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
+
+    /* from pointer to integer types */
+    printf("%d %d %ld %ld %lld %lld\n",
+           (int)p, (unsigned int)p,
+           (long)p, (unsigned long)p,
+           (long long)p, (unsigned long long)p);
+
+    /* from integers to pointers */
+    printf("%p %p %p %p\n",
+           (void *)a, (void *)b, (void *)c, (void *)d);
+}
+
+/* initializers tests */
+struct structinit1 {
+    int f1;
+    char f2;
+    short f3;
+    int farray[3];
+};
+
+int sinit1 = 2;
+int sinit2 = { 3 };
+int sinit3[3] = { 1, 2, {{3}}, };
+int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
+int sinit6[] = { 1, 2, 3 };
+int sinit7[] = { [2] = 3, [0] = 1, 2 };
+char sinit8[] = "hello" "trala";
+
+struct structinit1 sinit9 = { 1, 2, 3 };
+struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
+struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, 
+#ifdef ALL_ISOC99
+                               .farray[0] = 10,
+                               .farray[1] = 11,
+                               .farray[2] = 12,
+#endif
+};
+
+char *sinit12 = "hello world";
+char *sinit13[] = {
+    "test1",
+    "test2",
+    "test3",
+};
+char sinit14[10] = { "abc" };
+int sinit15[3] = { sizeof(sinit15), 1, 2 };
+
+struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
+
+struct bar {
+        char *s;
+        int len;
+} sinit17[] = {
+        "a1", 4,
+        "a2", 1
+};
+
+int sinit18[10] = {
+    [2 ... 5] = 20,
+    2,
+    [8] = 10,
+};
+
+void init_test(void)
+{
+    int linit1 = 2;
+    int linit2 = { 3 };
+    int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+    int linit6[] = { 1, 2, 3 };
+    int i, j;
+    char linit8[] = "hello" "trala";
+    int linit12[10] = { 1, 2 };
+    int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
+    char linit14[10] = "abc";
+    int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
+    struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
+    int linit17 = sizeof(linit17);
+    
+    printf("init_test:\n");
+
+    printf("sinit1=%d\n", sinit1);
+    printf("sinit2=%d\n", sinit2);
+    printf("sinit3=%d %d %d %d\n", 
+           sizeof(sinit3),
+           sinit3[0],
+           sinit3[1],
+           sinit3[2]
+           );
+    printf("sinit6=%d\n", sizeof(sinit6));
+    printf("sinit7=%d %d %d %d\n", 
+           sizeof(sinit7),
+           sinit7[0],
+           sinit7[1],
+           sinit7[2]
+           );
+    printf("sinit8=%s\n", sinit8);
+    printf("sinit9=%d %d %d\n", 
+           sinit9.f1,
+           sinit9.f2,
+           sinit9.f3
+           );
+    printf("sinit10=%d %d %d\n", 
+           sinit10.f1,
+           sinit10.f2,
+           sinit10.f3
+           );
+    printf("sinit11=%d %d %d %d %d %d\n", 
+           sinit11.f1,
+           sinit11.f2,
+           sinit11.f3,
+           sinit11.farray[0],
+           sinit11.farray[1],
+           sinit11.farray[2]
+           );
+
+    for(i=0;i<3;i++)
+        for(j=0;j<2;j++)
+            printf("[%d][%d] = %d %d %d\n", 
+                   i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
+    printf("linit1=%d\n", linit1);
+    printf("linit2=%d\n", linit2);
+    printf("linit6=%d\n", sizeof(linit6));
+    printf("linit8=%d %s\n", sizeof(linit8), linit8);
+
+    printf("sinit12=%s\n", sinit12);
+    printf("sinit13=%d %s %s %s\n",
+           sizeof(sinit13), 
+           sinit13[0],
+           sinit13[1],
+           sinit13[2]);
+    printf("sinit14=%s\n", sinit14);
+
+    for(i=0;i<10;i++) printf(" %d", linit12[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit13[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit14[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit15[i]);
+    printf("\n");
+    printf("%d %d %d %d\n", 
+           linit16.a1,
+           linit16.a2,
+           linit16.a3,
+           linit16.a4);
+    /* test that initialisation is done after variable declare */
+    printf("linit17=%d\n", linit17);
+    printf("sinit15=%d\n", sinit15[0]);
+    printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
+    printf("sinit17=%s %d %s %d\n",
+           sinit17[0].s, sinit17[0].len,
+           sinit17[1].s, sinit17[1].len);
+    for(i=0;i<10;i++)
+        printf("%x ", sinit18[i]);
+    printf("\n");
+}
+
+
+void switch_test()
+{
+    int i;
+
+    for(i=0;i<15;i++) {
+        switch(i) {
+        case 0:
+        case 1:
+            printf("a");
+            break;
+        default:
+            printf("%d", i);
+            break;
+        case 8 ... 12:
+            printf("c");
+            break;
+        case 3:
+            printf("b");
+            break;
+        }
+    }
+    printf("\n");
+}
+
+/* ISOC99 _Bool type */
+void c99_bool_test(void)
+{
+#ifdef BOOL_ISOC99
+    int a;
+    _Bool b;
+
+    printf("bool_test:\n");
+    printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
+    a = 3;
+    printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
+    b = 3;
+    printf("b = %d\n", b);
+    b++;
+    printf("b = %d\n", b);
+#endif
+}
+
+void bitfield_test(void)
+{
+    int a;
+    struct sbf1 {
+        int f1 : 3;
+        int : 2;
+        int f2 : 1;
+        int : 0;
+        int f3 : 5;
+        int f4 : 7;
+        unsigned int f5 : 7;
+    } st1;
+    printf("bitfield_test:");
+    printf("sizeof(st1) = %d\n", sizeof(st1));
+
+    st1.f1 = 3;
+    st1.f2 = 1;
+    st1.f3 = 15;
+    a = 120;
+    st1.f4 = a;
+    st1.f5 = a;
+    st1.f5++;
+    printf("%d %d %d %d %d\n",
+           st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
+
+    st1.f1 = 7;
+    if (st1.f1 == -1) 
+        printf("st1.f1 == -1\n");
+    else 
+        printf("st1.f1 != -1\n");
+    if (st1.f2 == -1) 
+        printf("st1.f2 == -1\n");
+    else 
+        printf("st1.f2 != -1\n");
+
+    /* bit sizes below must be bigger than 32 since GCC doesn't allow
+       long-long bitfields whose size is not bigger than int */
+    struct sbf2 {
+        long long f1 : 45;
+        long long : 2;
+        long long f2 : 35;
+        unsigned long long f3 : 38;
+    } st2;
+    st2.f1 = 0x123456789ULL;
+    a = 120;
+    st2.f2 = (long long)a << 25;
+    st2.f3 = a;
+    st2.f2++;
+    printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
+}
+
+#ifdef __x86_64__
+#define FLOAT_FMT "%f\n"
+#else
+/* x86's float isn't compatible with GCC */
+#define FLOAT_FMT "%.5f\n"
+#endif
+
+/* declare strto* functions as they are C99 */
+double strtod(const char *nptr, char **endptr);
+float strtof(const char *nptr, char **endptr);
+long double strtold(const char *nptr, char **endptr);
+
+#define FTEST(prefix, type, fmt)\
+void prefix ## cmp(type a, type b)\
+{\
+    printf("%d %d %d %d %d %d\n",\
+           a == b,\
+           a != b,\
+           a < b,\
+           a > b,\
+           a >= b,\
+           a <= b);\
+    printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
+           a,\
+           b,\
+           a + b,\
+           a - b,\
+           a * b,\
+           a / b,\
+           -a);\
+    printf(fmt "\n", ++a);\
+    printf(fmt "\n", a++);\
+    printf(fmt "\n", a);\
+    b = 0;\
+    printf("%d %d\n", !a, !b);\
+}\
+void prefix ## fcast(type a)\
+{\
+    float fa;\
+    double da;\
+    long double la;\
+    int ia;\
+    unsigned int ua;\
+    type b;\
+    fa = a;\
+    da = a;\
+    la = a;\
+    printf("ftof: %f %f %Lf\n", fa, da, la);\
+    ia = (int)a;\
+    ua = (unsigned int)a;\
+    printf("ftoi: %d %u\n", ia, ua);\
+    ia = -1234;\
+    ua = 0x81234500;\
+    b = ia;\
+    printf("itof: " fmt "\n", b);\
+    b = ua;\
+    printf("utof: " fmt "\n", b);\
+}\
+\
+float prefix ## retf(type a) { return a; }\
+double prefix ## retd(type a) { return a; }\
+long double prefix ## retld(type a) { return a; }\
+\
+void prefix ## call(void)\
+{\
+    printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
+    printf("double: %f\n", prefix ## retd(42.123456789));\
+    printf("long double: %Lf\n", prefix ## retld(42.123456789));\
+    printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
+}\
+\
+void prefix ## test(void)\
+{\
+    printf("testing '%s'\n", #type);\
+    prefix ## cmp(1, 2.5);\
+    prefix ## cmp(2, 1.5);\
+    prefix ## cmp(1, 1);\
+    prefix ## fcast(234.6);\
+    prefix ## fcast(-2334.6);\
+    prefix ## call();\
+}
+
+FTEST(f, float, "%f")
+FTEST(d, double, "%f")
+FTEST(ld, long double, "%Lf")
+
+double ftab1[3] = { 1.2, 3.4, -5.6 };
+
+
+void float_test(void)
+{
+    float fa, fb;
+    double da, db;
+    int a;
+    unsigned int b;
+
+    printf("float_test:\n");
+    printf("sizeof(float) = %d\n", sizeof(float));
+    printf("sizeof(double) = %d\n", sizeof(double));
+    printf("sizeof(long double) = %d\n", sizeof(long double));
+    ftest();
+    dtest();
+    ldtest();
+    printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
+    printf("%f %f %f\n", 2.12, .5, 2.3e10);
+    //    printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
+    da = 123;
+    printf("da=%f\n", da);
+    fa = 123;
+    printf("fa=%f\n", fa);
+    a = 4000000000;
+    da = a;
+    printf("da = %f\n", da);
+    b = 4000000000;
+    db = b;
+    printf("db = %f\n", db);
+}
+
+int fib(int n)
+{
+    if (n <= 2)
+        return 1;
+    else
+        return fib(n-1) + fib(n-2);
+}
+
+void funcptr_test()
+{
+    void (*func)(int);
+    int a;
+    struct {
+        int dummy;
+        void (*func)(int);
+    } st1;
+
+    printf("funcptr:\n");
+    func = &num;
+    (*func)(12345);
+    func = num;
+    a = 1;
+    a = 1;
+    func(12345);
+    /* more complicated pointer computation */
+    st1.func = num;
+    st1.func(12346);
+    printf("sizeof1 = %d\n", sizeof(funcptr_test));
+    printf("sizeof2 = %d\n", sizeof funcptr_test);
+    printf("sizeof3 = %d\n", sizeof(&funcptr_test));
+    printf("sizeof4 = %d\n", sizeof &funcptr_test);
+}
+
+void lloptest(long long a, long long b)
+{
+    unsigned long long ua, ub;
+
+    ua = a;
+    ub = b;
+    /* arith */
+    printf("arith: %Ld %Ld %Ld\n",
+           a + b,
+           a - b,
+           a * b);
+    
+    if (b != 0) {
+        printf("arith1: %Ld %Ld\n",
+           a / b,
+           a % b);
+    }
+
+    /* binary */
+    printf("bin: %Ld %Ld %Ld\n",
+           a & b,
+           a | b,
+           a ^ b);
+
+    /* tests */
+    printf("test: %d %d %d %d %d %d\n",
+           a == b,
+           a != b,
+           a < b,
+           a > b,
+           a >= b,
+           a <= b);
+    
+    printf("utest: %d %d %d %d %d %d\n",
+           ua == ub,
+           ua != ub,
+           ua < ub,
+           ua > ub,
+           ua >= ub,
+           ua <= ub);
+
+    /* arith2 */
+    a++;
+    b++;
+    printf("arith2: %Ld %Ld\n", a, b);
+    printf("arith2: %Ld %Ld\n", a++, b++);
+    printf("arith2: %Ld %Ld\n", --a, --b);
+    printf("arith2: %Ld %Ld\n", a, b);
+    b = ub = 0;
+    printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
+}
+
+void llshift(long long a, int b)
+{
+    printf("shift: %Ld %Ld %Ld\n",
+           (unsigned long long)a >> b,
+           a >> b,
+           a << b);
+    printf("shiftc: %Ld %Ld %Ld\n",
+           (unsigned long long)a >> 3,
+           a >> 3,
+           a << 3);
+    printf("shiftc: %Ld %Ld %Ld\n",
+           (unsigned long long)a >> 35,
+           a >> 35,
+           a << 35);
+}
+
+void llfloat(void)
+{
+    float fa;
+    double da;
+    long double lda;
+    long long la, lb, lc;
+    unsigned long long ula, ulb, ulc;
+    la = 0x12345678;
+    ula = 0x72345678;
+    la = (la << 20) | 0x12345;
+    ula = ula << 33;
+    printf("la=%Ld ula=%Lu\n", la, ula);
+
+    fa = la;
+    da = la;
+    lda = la;
+    printf("lltof: %f %f %Lf\n", fa, da, lda);
+
+    la = fa;
+    lb = da;
+    lc = lda;
+    printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc);
+
+    fa = ula;
+    da = ula;
+    lda = ula;
+    printf("ulltof: %f %f %Lf\n", fa, da, lda);
+
+    ula = fa;
+    ulb = da;
+    ulc = lda;
+    printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc);
+}
+
+long long llfunc1(int a)
+{
+    return a * 2;
+}
+
+struct S {
+    int id; 
+    char item;
+};
+
+long long int value(struct S *v)
+{
+    return ((long long int)v->item);
+}
+
+void longlong_test(void)
+{
+    long long a, b, c;
+    int ia;
+    unsigned int ua;
+    printf("longlong_test:\n");
+    printf("sizeof(long long) = %d\n", sizeof(long long));
+    ia = -1;
+    ua = -2;
+    a = ia;
+    b = ua;
+    printf("%Ld %Ld\n", a, b);
+    printf("%Ld %Ld %Ld %Lx\n", 
+           (long long)1, 
+           (long long)-2,
+           1LL,
+           0x1234567812345679);
+    a = llfunc1(-3);
+    printf("%Ld\n", a);
+
+    lloptest(1000, 23);
+    lloptest(0xff, 0x1234);
+    b = 0x72345678 << 10;
+    lloptest(-3, b);
+    llshift(0x123, 5);
+    llshift(-23, 5);
+    b = 0x72345678LL << 10;
+    llshift(b, 47);
+
+    llfloat();
+#if 1
+    b = 0x12345678;
+    a = -1;
+    c = a + b;
+    printf("%Lx\n", c);
+#endif
+
+    /* long long reg spill test */
+    {
+          struct S a;
+
+          a.item = 3;
+          printf("%lld\n", value(&a));
+    }
+    lloptest(0x80000000, 0);
+
+    /* another long long spill test */
+    {
+        long long *p, v;
+        v = 1;
+        p = &v;
+        p[0]++;
+        printf("%lld\n", *p);
+    }
+
+    a = 68719476720LL;
+    b = 4294967295LL;
+    printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
+
+    printf("%Ld\n", 0x123456789LLU);
+}
+
+void manyarg_test(void)
+{
+    long double ld = 1234567891234LL;
+    printf("manyarg_test:\n");
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           "%Ld %Ld %f %f\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0);
+    printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           "%Ld %Ld %f %f\n",
+           ld, 1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0);
+    /* XXX: known bug of x86-64 */
+#ifndef __x86_64__
+    printf("%d %d %d %d %d %d %d %d %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8, ld);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           "%Ld %Ld %f %f %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0, ld);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           "%Lf %Ld %Ld %f %f %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           ld, 1234567891234LL, 987654321986LL,
+           42.0, 43.0, ld);
+#endif
+}
+
+void vprintf1(const char *fmt, ...)
+{
+    va_list ap;
+    const char *p;
+    int c, i;
+    double d;
+    long long ll;
+    long double ld;
+
+    va_start(ap, fmt);
+    
+    p = fmt;
+    for(;;) {
+        c = *p;
+        if (c == '\0')
+            break;
+        p++;
+        if (c == '%') {
+            c = *p;
+            switch(c) {
+            case '\0':
+                goto the_end;
+            case 'd':
+                i = va_arg(ap, int);
+                printf("%d", i);
+                break;
+            case 'f':
+                d = va_arg(ap, double);
+                printf("%f", d);
+                break;
+            case 'l':
+                ll = va_arg(ap, long long);
+                printf("%Ld", ll);
+                break;
+            case 'F':
+                ld = va_arg(ap, long double);
+                printf("%Lf", ld);
+                break;
+            }
+            p++;
+        } else {
+            putchar(c);
+        }
+    }
+ the_end:
+    va_end(ap);
+}
+
+
+void stdarg_test(void)
+{
+    long double ld = 1234567891234LL;
+    vprintf1("%d %d %d\n", 1, 2, 3);
+    vprintf1("%f %d %f\n", 1.0, 2, 3.0);
+    vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
+    vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L);
+#ifdef __x86_64__
+    /* a bug of x86's TCC */
+    vprintf1("%d %f %l %F %d %f %l %F\n",
+             1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L);
+#endif
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0);
+    vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f\n",
+             ld, 1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0);
+    vprintf1("%d %d %d %d %d %d %d %d %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8, ld);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0, ld);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%F %l %l %f %f %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             ld, 1234567891234LL, 987654321986LL,
+             42.0, 43.0, ld);
+}
+
+void whitespace_test(void)
+{
+    char *str;
+
+
#if 1
+    pri\
+ntf("whitspace:\n");

+#endif
+    pf("N=%d\n", 2);
+
+#ifdef CORRECT_CR_HANDLING
+    pri\

+ntf("aaa=%d\n", 3);
+#endif
+
+    pri\
+\
+ntf("min=%d\n", 4);
+
+#ifdef ACCEPT_CR_IN_STRINGS
+    printf("len1=%d\n", strlen("
+"));
+#ifdef CORRECT_CR_HANDLING
+    str = "

+";
+    printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
+#endif
+    printf("len1=%d\n", strlen("
a
+"));
+#endif /* ACCEPT_CR_IN_STRINGS */
+}
+
+int reltab[3] = { 1, 2, 3 };
+
+int *rel1 = &reltab[1];
+int *rel2 = &reltab[2];
+
+void relocation_test(void)
+{
+    printf("*rel1=%d\n", *rel1);
+    printf("*rel2=%d\n", *rel2);
+}
+
+void old_style_f(a,b,c)
+     int a, b;
+     double c;
+{
+    printf("a=%d b=%d b=%f\n", a, b, c);
+}
+
+void decl_func1(int cmpfn())
+{
+    printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void decl_func2(cmpfn)
+int cmpfn();
+{
+    printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void old_style_function(void)
+{
+    old_style_f((void *)1, 2, 3.0);
+    decl_func1(NULL);
+    decl_func2(NULL);
+}
+
+void alloca_test()
+{
+#if defined __i386__ || defined __x86_64__
+    char *p = alloca(16);
+    strcpy(p,"123456789012345");
+    printf("alloca: p is %s\n", p);
+    char *demo = "This is only a test.\n";
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+#endif
+}
+
+void sizeof_test(void)
+{
+    int a;
+    int **ptr;
+
+    printf("sizeof(int) = %d\n", sizeof(int));
+    printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
+    printf("sizeof(long) = %d\n", sizeof(long));
+    printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
+    printf("sizeof(short) = %d\n", sizeof(short));
+    printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
+    printf("sizeof(char) = %d\n", sizeof(char));
+    printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
+    printf("sizeof(func) = %d\n", sizeof sizeof_test());
+    a = 1;
+    printf("sizeof(a++) = %d\n", sizeof a++);
+    printf("a=%d\n", a);
+    ptr = NULL;
+    printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
+
+    /* some alignof tests */
+    printf("__alignof__(int) = %d\n", __alignof__(int));
+    printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
+    printf("__alignof__(short) = %d\n", __alignof__(short));
+    printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
+    printf("__alignof__(char) = %d\n", __alignof__(char));
+    printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
+    printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
+}
+
+void typeof_test(void)
+{
+    double a;
+    typeof(a) b;
+    typeof(float) c;
+
+    a = 1.5;
+    b = 2.5;
+    c = 3.5;
+    printf("a=%f b=%f c=%f\n", a, b, c);
+}
+
+void statement_expr_test(void)
+{
+    int a, i;
+
+    a = 0;
+    for(i=0;i<10;i++) {
+        a += 1 + 
+            ( { int b, j; 
+                b = 0; 
+                for(j=0;j<5;j++) 
+                    b += j; b; 
+            } );
+    }
+    printf("a=%d\n", a);
+    
+}
+
+void local_label_test(void)
+{
+    int a;
+    goto l1;
+ l2:
+    a = 1 + ({
+        __label__ l1, l2, l3, l4;
+        goto l1;
+    l4:
+        printf("aa1\n");
+        goto l3;
+    l2:
+        printf("aa3\n");
+        goto l4;
+    l1:
+        printf("aa2\n");
+        goto l2;
+    l3:;
+        1;
+    });
+    printf("a=%d\n", a);
+    return;
+ l4:
+    printf("bb1\n");
+    goto l2;
+ l1:
+    printf("bb2\n");
+    goto l4;
+}
+
+/* inline assembler test */
+#ifdef __i386__
+
+/* from linux kernel */
+static char * strncat1(char * dest,const char * src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+	"repne\n\t"
+	"scasb\n\t"
+	"decl %1\n\t"
+	"movl %8,%3\n"
+	"1:\tdecl %3\n\t"
+	"js 2f\n\t"
+	"lodsb\n\t"
+	"stosb\n\t"
+	"testb %%al,%%al\n\t"
+	"jne 1b\n"
+	"2:\txorl %2,%2\n\t"
+	"stosb"
+	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+	: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+	: "memory");
+return dest;
+}
+
+static inline void * memcpy1(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+	"rep ; movsl\n\t"
+	"testb $2,%b4\n\t"
+	"je 1f\n\t"
+	"movsw\n"
+	"1:\ttestb $1,%b4\n\t"
+	"je 2f\n\t"
+	"movsb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
+	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+	: "memory");
+return (to);
+}
+
+static __inline__ void sigaddset1(unsigned int *set, int _sig)
+{
+	__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
+}
+
+static __inline__ void sigdelset1(unsigned int *set, int _sig)
+{
+	asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
+}
+
+static __inline__ __const__ unsigned int swab32(unsigned int x)
+{
+	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
+		"rorl $16,%0\n\t"	/* swap words		*/
+		"xchgb %b0,%h0"		/* swap higher bytes	*/
+		:"=q" (x)
+		: "0" (x));
+	return x;
+}
+
+static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
+{
+    unsigned long long res;
+    __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
+    return res;
+}
+
+static __inline__ unsigned long long inc64(unsigned long long a)
+{
+    unsigned long long res;
+    __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
+    return res;
+}
+
+unsigned int set;
+
+void asm_test(void)
+{
+    char buf[128];
+    unsigned int val;
+
+    printf("inline asm:\n");
+    /* test the no operand case */
+    asm volatile ("xorl %eax, %eax");
+
+    memcpy1(buf, "hello", 6);
+    strncat1(buf, " worldXXXXX", 3);
+    printf("%s\n", buf);
+
+    /* 'A' constraint test */
+    printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
+    printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
+
+    set = 0xff;
+    sigdelset1(&set, 2);
+    sigaddset1(&set, 16);
+    /* NOTE: we test here if C labels are correctly restored after the
+       asm statement */
+    goto label1;
+ label2:
+    __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
+#ifdef __GNUC__ // works strange with GCC 4.3
+    set=0x1080fd;
+#endif
+    printf("set=0x%x\n", set);
+    val = 0x01020304;
+    printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
+    return;
+ label1:
+    goto label2;
+}
+
+#else
+
+void asm_test(void)
+{
+}
+
+#endif
+
+#define COMPAT_TYPE(type1, type2) \
+{\
+    printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
+           __builtin_types_compatible_p (type1, type2));\
+}
+
+int constant_p_var;
+
+void builtin_test(void)
+{
+#if GCC_MAJOR >= 3
+    COMPAT_TYPE(int, int);
+    COMPAT_TYPE(int, unsigned int);
+    COMPAT_TYPE(int, char);
+    COMPAT_TYPE(int, const int);
+    COMPAT_TYPE(int, volatile int);
+    COMPAT_TYPE(int *, int *);
+    COMPAT_TYPE(int *, void *);
+    COMPAT_TYPE(int *, const int *);
+    COMPAT_TYPE(char *, unsigned char *);
+/* space is needed because tcc preprocessor introduces a space between each token */
+    COMPAT_TYPE(char * *, void *); 
+#endif
+    printf("res = %d\n", __builtin_constant_p(1));
+    printf("res = %d\n", __builtin_constant_p(1 + 2));
+    printf("res = %d\n", __builtin_constant_p(&constant_p_var));
+    printf("res = %d\n", __builtin_constant_p(constant_p_var));
+}
+
+
+void const_func(const int a)
+{
+}
+
+void const_warn_test(void)
+{
+    const_func(1);
+}
diff --git a/tinyc/texi2pod.pl b/tinyc/texi2pod.pl
new file mode 100755
index 000000000..d86e176f1
--- /dev/null
+++ b/tinyc/texi2pod.pl
@@ -0,0 +1,427 @@
+#! /usr/bin/perl -w
+
+#   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This file is part of GNU CC.
+
+# GNU CC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GNU CC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU CC; see the file COPYING.  If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston MA 02111-1307, USA.
+
+# This does trivial (and I mean _trivial_) conversion of Texinfo
+# markup to Perl POD format.  It's intended to be used to extract
+# something suitable for a manpage from a Texinfo document.
+
+$output = 0;
+$skipping = 0;
+%sects = ();
+$section = "";
+@icstack = ();
+@endwstack = ();
+@skstack = ();
+@instack = ();
+$shift = "";
+%defs = ();
+$fnno = 1;
+$inf = "";
+$ibase = "";
+
+while ($_ = shift) {
+    if (/^-D(.*)$/) {
+	if ($1 ne "") {
+	    $flag = $1;
+	} else {
+	    $flag = shift;
+	}
+	$value = "";
+	($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
+	die "no flag specified for -D\n"
+	    unless $flag ne "";
+	die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
+	    unless $flag =~ /^[a-zA-Z0-9_-]+$/;
+	$defs{$flag} = $value;
+    } elsif (/^-/) {
+	usage();
+    } else {
+	$in = $_, next unless defined $in;
+	$out = $_, next unless defined $out;
+	usage();
+    }
+}
+
+if (defined $in) {
+    $inf = gensym();
+    open($inf, "<$in") or die "opening \"$in\": $!\n";
+    $ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
+} else {
+    $inf = \*STDIN;
+}
+
+if (defined $out) {
+    open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
+}
+
+while(defined $inf) {
+while(<$inf>) {
+    # Certain commands are discarded without further processing.
+    /^\@(?:
+	 [a-z]+index		# @*index: useful only in complete manual
+	 |need			# @need: useful only in printed manual
+	 |(?:end\s+)?group	# @group .. @end group: ditto
+	 |page			# @page: ditto
+	 |node			# @node: useful only in .info file
+	 |(?:end\s+)?ifnottex   # @ifnottex .. @end ifnottex: use contents
+	)\b/x and next;
+
+    chomp;
+
+    # Look for filename and title markers.
+    /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
+    /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
+
+    # Identify a man title but keep only the one we are interested in.
+    /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
+	if (exists $defs{$1}) {
+	    $fn = $1;
+	    $tl = postprocess($2);
+	}
+	next;
+    };
+
+    # Look for blocks surrounded by @c man begin SECTION ... @c man end.
+    # This really oughta be @ifman ... @end ifman and the like, but such
+    # would require rev'ing all other Texinfo translators.
+    /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
+	$output = 1 if exists $defs{$2};
+        $sect = $1;
+	next;
+    };
+    /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
+    /^\@c\s+man\s+end/ and do {
+	$sects{$sect} = "" unless exists $sects{$sect};
+	$sects{$sect} .= postprocess($section);
+	$section = "";
+	$output = 0;
+	next;
+    };
+
+    # handle variables
+    /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
+	$defs{$1} = $2;
+	next;
+    };
+    /^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
+	delete $defs{$1};
+	next;
+    };
+
+    next unless $output;
+
+    # Discard comments.  (Can't do it above, because then we'd never see
+    # @c man lines.)
+    /^\@c\b/ and next;
+
+    # End-block handler goes up here because it needs to operate even
+    # if we are skipping.
+    /^\@end\s+([a-z]+)/ and do {
+	# Ignore @end foo, where foo is not an operation which may
+	# cause us to skip, if we are presently skipping.
+	my $ended = $1;
+	next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
+
+	die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
+	die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
+
+	$endw = pop @endwstack;
+
+	if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
+	    $skipping = pop @skstack;
+	    next;
+	} elsif ($ended =~ /^(?:example|smallexample|display)$/) {
+	    $shift = "";
+	    $_ = "";	# need a paragraph break
+	} elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+	    $_ = "\n=back\n";
+	    $ic = pop @icstack;
+	} else {
+	    die "unknown command \@end $ended at line $.\n";
+	}
+    };
+
+    # We must handle commands which can cause skipping even while we
+    # are skipping, otherwise we will not process nested conditionals
+    # correctly.
+    /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = "ifset";
+	$skipping = 1 unless exists $defs{$1};
+	next;
+    };
+
+    /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = "ifclear";
+	$skipping = 1 if exists $defs{$1};
+	next;
+    };
+
+    /^\@(ignore|menu|iftex)\b/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = $1;
+	$skipping = 1;
+	next;
+    };
+
+    next if $skipping;
+
+    # Character entities.  First the ones that can be replaced by raw text
+    # or discarded outright:
+    s/\@copyright\{\}/(c)/g;
+    s/\@dots\{\}/.../g;
+    s/\@enddots\{\}/..../g;
+    s/\@([.!? ])/$1/g;
+    s/\@[:-]//g;
+    s/\@bullet(?:\{\})?/*/g;
+    s/\@TeX\{\}/TeX/g;
+    s/\@pounds\{\}/\#/g;
+    s/\@minus(?:\{\})?/-/g;
+    s/\\,/,/g;
+
+    # Now the ones that have to be replaced by special escapes
+    # (which will be turned back into text by unmunge())
+    s/&/&amp;/g;
+    s/\@\{/&lbrace;/g;
+    s/\@\}/&rbrace;/g;
+    s/\@\@/&at;/g;
+
+    # Inside a verbatim block, handle @var specially.
+    if ($shift ne "") {
+	s/\@var\{([^\}]*)\}/<$1>/g;
+    }
+
+    # POD doesn't interpret E<> inside a verbatim block.
+    if ($shift eq "") {
+	s/</&lt;/g;
+	s/>/&gt;/g;
+    } else {
+	s/</&LT;/g;
+	s/>/&GT;/g;
+    }
+
+    # Single line command handlers.
+
+    /^\@include\s+(.+)$/ and do {
+	push @instack, $inf;
+	$inf = gensym();
+
+	# Try cwd and $ibase.
+	open($inf, "<" . $1) 
+	    or open($inf, "<" . $ibase . "/" . $1)
+		or die "cannot open $1 or $ibase/$1: $!\n";
+	next;
+    };
+
+    /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
+	and $_ = "\n=head2 $1\n";
+    /^\@subsection\s+(.+)$/
+	and $_ = "\n=head3 $1\n";
+
+    # Block command handlers:
+    /^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	$ic = $1;
+	$_ = "\n=over 4\n";
+	$endw = "itemize";
+    };
+
+    /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	if (defined $1) {
+	    $ic = $1 . ".";
+	} else {
+	    $ic = "1.";
+	}
+	$_ = "\n=over 4\n";
+	$endw = "enumerate";
+    };
+
+    /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	$endw = $1;
+	$ic = $2;
+	$ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
+	$ic =~ s/\@(?:code|kbd)/C/;
+	$ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
+	$ic =~ s/\@(?:file)/F/;
+	$_ = "\n=over 4\n";
+    };
+
+    /^\@((?:small)?example|display)/ and do {
+	push @endwstack, $endw;
+	$endw = $1;
+	$shift = "\t";
+	$_ = "";	# need a paragraph break
+    };
+
+    /^\@itemx?\s*(.+)?$/ and do {
+	if (defined $1) {
+	    # Entity escapes prevent munging by the <> processing below.
+	    $_ = "\n=item $ic\&LT;$1\&GT;\n";
+	} else {
+	    $_ = "\n=item $ic\n";
+	    $ic =~ y/A-Ya-y/B-Zb-z/;
+	    $ic =~ s/(\d+)/$1 + 1/eg;
+	}
+    };
+
+    $section .= $shift.$_."\n";
+}
+# End of current file.
+close($inf);
+$inf = pop @instack;
+}
+
+die "No filename or title\n" unless defined $fn && defined $tl;
+
+$sects{NAME} = "$fn \- $tl\n";
+$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
+
+for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES
+	      BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
+    if(exists $sects{$sect}) {
+	$head = $sect;
+	$head =~ s/SEEALSO/SEE ALSO/;
+	print "=head1 $head\n\n";
+	print scalar unmunge ($sects{$sect});
+	print "\n";
+    }
+}
+
+sub usage
+{
+    die "usage: $0 [-D toggle...] [infile [outfile]]\n";
+}
+
+sub postprocess
+{
+    local $_ = $_[0];
+
+    # @value{foo} is replaced by whatever 'foo' is defined as.
+    while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
+	if (! exists $defs{$2}) {
+	    print STDERR "Option $2 not defined\n";
+	    s/\Q$1\E//;
+	} else {
+	    $value = $defs{$2};
+	    s/\Q$1\E/$value/;
+	}
+    }
+
+    # Formatting commands.
+    # Temporary escape for @r.
+    s/\@r\{([^\}]*)\}/R<$1>/g;
+    s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
+    s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
+    s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
+    s/\@sc\{([^\}]*)\}/\U$1/g;
+    s/\@file\{([^\}]*)\}/F<$1>/g;
+    s/\@w\{([^\}]*)\}/S<$1>/g;
+    s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
+
+    # Cross references are thrown away, as are @noindent and @refill.
+    # (@noindent is impossible in .pod, and @refill is unnecessary.)
+    # @* is also impossible in .pod; we discard it and any newline that
+    # follows it.  Similarly, our macro @gol must be discarded.
+
+    s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
+    s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
+    s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+    s/\@noindent\s*//g;
+    s/\@refill//g;
+    s/\@gol//g;
+    s/\@\*\s*\n?//g;
+
+    # @uref can take one, two, or three arguments, with different
+    # semantics each time.  @url and @email are just like @uref with
+    # one argument, for our purposes.
+    s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
+    s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
+    s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
+
+    # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
+    # match Texinfo semantics of @emph inside @samp.  Also handle @r
+    # inside bold.
+    s/&LT;/</g;
+    s/&GT;/>/g;
+    1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
+    1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
+    1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
+    s/[BI]<>//g;
+    s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
+    s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
+
+    # Extract footnotes.  This has to be done after all other
+    # processing because otherwise the regexp will choke on formatting
+    # inside @footnote.
+    while (/\@footnote/g) {
+	s/\@footnote\{([^\}]+)\}/[$fnno]/;
+	add_footnote($1, $fnno);
+	$fnno++;
+    }
+
+    return $_;
+}
+
+sub unmunge
+{
+    # Replace escaped symbols with their equivalents.
+    local $_ = $_[0];
+
+    s/&lt;/E<lt>/g;
+    s/&gt;/E<gt>/g;
+    s/&lbrace;/\{/g;
+    s/&rbrace;/\}/g;
+    s/&at;/\@/g;
+    s/&amp;/&/g;
+    return $_;
+}
+
+sub add_footnote
+{
+    unless (exists $sects{FOOTNOTES}) {
+	$sects{FOOTNOTES} = "\n=over 4\n\n";
+    }
+
+    $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
+    $sects{FOOTNOTES} .= $_[0];
+    $sects{FOOTNOTES} .= "\n\n";
+}
+
+# stolen from Symbol.pm
+{
+    my $genseq = 0;
+    sub gensym
+    {
+	my $name = "GEN" . $genseq++;
+	my $ref = \*{$name};
+	delete $::{$name};
+	return $ref;
+    }
+}
diff --git a/tinyc/win32/build-tcc.bat b/tinyc/win32/build-tcc.bat
new file mode 100755
index 000000000..9d3866c16
--- /dev/null
+++ b/tinyc/win32/build-tcc.bat
@@ -0,0 +1,28 @@
+@rem ----------------------------------------------------

+@rem batch file to build tcc using gcc and ar from mingw

+@rem ----------------------------------------------------

+:

+@echo>..\config.h #define TCC_VERSION "0.9.25"

+@echo>>..\config.h #define TCC_TARGET_PE 1

+@echo>>..\config.h #define CONFIG_TCCDIR "."

+@echo>>..\config.h #define CONFIG_SYSROOT ""

+:

+gcc -Os -fno-strict-aliasing ../tcc.c -o tcc.exe -s

+gcc -Os -fno-strict-aliasing ../libtcc.c -c -o libtcc.o

+gcc -Os tools/tiny_impdef.c -o tiny_impdef.exe -s

+gcc -Os tools/tiny_libmaker.c -o tiny_libmaker.exe -s

+mkdir libtcc

+ar rcs libtcc/libtcc.a libtcc.o

+del libtcc.o

+copy ..\libtcc.h libtcc

+:

+.\tcc -c lib/crt1.c

+.\tcc -c lib/wincrt1.c

+.\tcc -c lib/dllcrt1.c

+.\tcc -c lib/dllmain.c

+.\tcc -c lib/chkstk.S

+.\tcc -c ../lib/libtcc1.c

+.\tcc -c ../lib/alloca86.S

+.\tcc -c ../lib/alloca86-bt.S

+ar rcs lib/libtcc1.a crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o libtcc1.o alloca86.o alloca86-bt.o

+rem del *.o

diff --git a/tinyc/win32/examples/dll.c b/tinyc/win32/examples/dll.c
new file mode 100755
index 000000000..4202e99ca
--- /dev/null
+++ b/tinyc/win32/examples/dll.c
@@ -0,0 +1,15 @@
+//+---------------------------------------------------------------------------
+//
+//  dll.c - Windows DLL example - dynamically linked part
+//
+
+#include <windows.h>
+
+#define DLL_EXPORT __declspec(dllexport)
+
+
+DLL_EXPORT void HelloWorld (void)
+{
+	MessageBox (0, "Hello World!", "From DLL", MB_ICONINFORMATION);
+}
+
diff --git a/tinyc/win32/examples/fib.c b/tinyc/win32/examples/fib.c
new file mode 100755
index 000000000..6a4bdf5c4
--- /dev/null
+++ b/tinyc/win32/examples/fib.c
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <math.h>
+
+int fib(int n)
+{
+	if (n <= 2)
+		return 1;
+	else
+		return fib(n-1) + fib(n-2);
+}
+
+int main(int argc, char **argv) 
+{
+	int n;
+	if (argc < 2) {
+		printf("usage: fib n\n"
+			   "Compute nth Fibonacci number\n");
+		return 1;
+	}
+		
+	n = atoi(argv[1]);
+	printf("fib(%d) = %d\n", n, fib(n));
+	return 0;
+}
diff --git a/tinyc/win32/examples/hello_dll.c b/tinyc/win32/examples/hello_dll.c
new file mode 100755
index 000000000..7adba77ec
--- /dev/null
+++ b/tinyc/win32/examples/hello_dll.c
@@ -0,0 +1,19 @@
+//+---------------------------------------------------------------------------
+//
+//  HELLO_DLL.C - Windows DLL example - main application part
+//
+
+#include <windows.h>
+
+void HelloWorld (void);
+
+int WINAPI WinMain(
+	HINSTANCE hInstance,
+	HINSTANCE hPrevInstance,
+	LPSTR     lpCmdLine,
+	int       nCmdShow)
+{
+	HelloWorld();
+	return 0;
+}
+
diff --git a/tinyc/win32/examples/hello_win.c b/tinyc/win32/examples/hello_win.c
new file mode 100755
index 000000000..294b7279a
--- /dev/null
+++ b/tinyc/win32/examples/hello_win.c
@@ -0,0 +1,159 @@
+//+---------------------------------------------------------------------------
+//
+//  HELLO_WIN.C - Windows GUI 'Hello World!' Example
+//
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+#define APPNAME "HELLO_WIN"
+
+char szAppName[] = APPNAME; // The name of this application
+char szTitle[]   = APPNAME; // The title bar text
+char *pWindowText;
+
+HINSTANCE g_hInst;          // current instance
+
+void CenterWindow(HWND hWnd);
+
+//+---------------------------------------------------------------------------
+//
+//  Function:   WndProc
+//
+//  Synopsis:   very unusual type of function - gets called by system to
+//              process windows messages.
+//
+//  Arguments:  same as always.
+//----------------------------------------------------------------------------
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+	switch (message)
+	{
+		// ----------------------- first and last
+		case WM_CREATE:
+			CenterWindow(hwnd);
+			break;
+
+		case WM_DESTROY:
+			PostQuitMessage(0);
+			break;
+
+
+		// ----------------------- get out of it...
+		case WM_RBUTTONUP:
+			DestroyWindow(hwnd);
+			break;
+
+		case WM_KEYDOWN:
+			if (VK_ESCAPE == wParam)
+				DestroyWindow(hwnd);
+			break;
+
+
+		// ----------------------- display our minimal info
+		case WM_PAINT:
+		{
+			PAINTSTRUCT ps;
+			HDC         hdc;
+			RECT        rc;
+			hdc = BeginPaint(hwnd, &ps);
+
+			GetClientRect(hwnd, &rc);
+			SetTextColor(hdc, RGB(240,240,96));
+			SetBkMode(hdc, TRANSPARENT);
+			DrawText(hdc, pWindowText, -1, &rc, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
+
+			EndPaint(hwnd, &ps);
+			break;
+		}
+
+		// ----------------------- let windows do all other stuff
+		default:
+			return DefWindowProc(hwnd, message, wParam, lParam);
+	}
+	return 0;
+}
+
+//+---------------------------------------------------------------------------
+//
+//  Function:   WinMain
+//
+//  Synopsis:   standard entrypoint for GUI Win32 apps
+//
+//----------------------------------------------------------------------------
+int APIENTRY WinMain(
+				HINSTANCE hInstance,
+				HINSTANCE hPrevInstance,
+				LPSTR     lpCmdLine,
+				int       nCmdShow)
+{
+	MSG msg;
+
+	WNDCLASS wc;
+
+	HWND hwnd;
+
+	// Fill in window class structure with parameters that describe
+	// the main window.
+
+	ZeroMemory(&wc, sizeof wc);
+	wc.hInstance     = hInstance;
+	wc.lpszClassName = szAppName;
+	wc.lpfnWndProc   = (WNDPROC)WndProc;
+	wc.style         = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW;
+	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+	wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
+	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
+
+	if (FALSE == RegisterClass(&wc)) return 0;
+
+	// create the browser
+	hwnd = CreateWindow(
+		szAppName,
+		szTitle,
+		WS_OVERLAPPEDWINDOW|WS_VISIBLE,
+		CW_USEDEFAULT,
+		CW_USEDEFAULT,
+		360,//CW_USEDEFAULT,
+		240,//CW_USEDEFAULT,
+		0,
+		0,
+		g_hInst,
+		0);
+
+	if (NULL == hwnd) return 0;
+
+	pWindowText = lpCmdLine[0] ? lpCmdLine : "Hello Windows!";
+
+	// Main message loop:
+	while (GetMessage(&msg, NULL, 0, 0) > 0)
+	{
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	}
+
+	return msg.wParam;
+}
+
+//+---------------------------------------------------------------------------
+
+//+---------------------------------------------------------------------------
+
+void CenterWindow(HWND hwnd_self)
+{
+	RECT rw_self, rc_parent, rw_parent; HWND hwnd_parent;
+	hwnd_parent = GetParent(hwnd_self);
+	if (NULL==hwnd_parent) hwnd_parent = GetDesktopWindow();
+	GetWindowRect(hwnd_parent, &rw_parent);
+	GetClientRect(hwnd_parent, &rc_parent);
+	GetWindowRect(hwnd_self, &rw_self);
+	SetWindowPos(hwnd_self, NULL,
+		rw_parent.left + (rc_parent.right + rw_self.left - rw_self.right) / 2,
+		rw_parent.top  + (rc_parent.bottom + rw_self.top - rw_self.bottom) / 2,
+		0, 0,
+		SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE
+		);
+}
+
+//+---------------------------------------------------------------------------
diff --git a/tinyc/win32/include/_mingw.h b/tinyc/win32/include/_mingw.h
new file mode 100755
index 000000000..257c52376
--- /dev/null
+++ b/tinyc/win32/include/_mingw.h
@@ -0,0 +1,54 @@
+/*
+ * _mingw.h
+ *
+ *  This file is for TCC-PE and not part of the Mingw32 package.
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __MINGW_H
+#define __MINGW_H
+
+#include <stddef.h>
+
+#define __int64 long long
+#define __int32 long
+#define __int16 short
+#define __int8 char
+#define __cdecl __attribute__((__cdecl__))
+#define __stdcall __attribute__((__stdcall__))
+#define __declspec(x) __attribute__((x))
+
+#define __MINGW32_VERSION 2.0
+#define __MINGW32_MAJOR_VERSION 2
+#define __MINGW32_MINOR_VERSION 0
+
+#define __MSVCRT__ 1
+#define __MINGW_IMPORT extern
+#define _CRTIMP
+#define __CRT_INLINE extern __inline__
+
+#define WIN32 1
+
+#ifndef _WINT_T
+#define _WINT_T
+typedef unsigned int wint_t;
+#endif
+
+/* for winapi */
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#define DECLSPEC_NORETURN
+#define WIN32_LEAN_AND_MEAN
+#define DECLARE_STDCALL_P(type) __stdcall type
+
+#endif /* __MINGW_H */
diff --git a/tinyc/win32/include/assert.h b/tinyc/win32/include/assert.h
new file mode 100755
index 000000000..959c80351
--- /dev/null
+++ b/tinyc/win32/include/assert.h
@@ -0,0 +1,71 @@
+/* 
+ * assert.h
+ *
+ * Define the assert macro for debug output.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _ASSERT_H_
+#define	_ASSERT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifndef RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef NDEBUG
+
+/*
+ * If not debugging, assert does nothing.
+ */
+#define assert(x)	((void)0)
+
+#else /* debugging enabled */
+
+/*
+ * CRTDLL nicely supplies a function which does the actual output and
+ * call to abort.
+ */
+void	_assert (const char*, const char*, int)
+#ifdef	__GNUC__
+	__attribute__ ((noreturn))
+#endif
+	;
+
+/*
+ * Definition of the assert macro.
+ */
+#define assert(e)       ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
+#endif	/* NDEBUG */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _ASSERT_H_ */
+
diff --git a/tinyc/win32/include/conio.h b/tinyc/win32/include/conio.h
new file mode 100755
index 000000000..c1f4151df
--- /dev/null
+++ b/tinyc/win32/include/conio.h
@@ -0,0 +1,159 @@
+/* A conio implementation for Mingw/Dev-C++.
+ *
+ * Written by:
+ * Hongli Lai <hongli@telekabel.nl>
+ * tkorrovi <tkorrovi@altavista.net> on 2002/02/26. 
+ * Andrew Westcott <ajwestco@users.sourceforge.net>
+ *
+ * Offered for use in the public domain without any warranty.
+ */
+
+#ifndef _CONIO_H_
+#define _CONIO_H_
+
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLINK 0
+
+typedef enum
+{
+    BLACK,
+    BLUE,
+    GREEN,
+    CYAN,
+    RED,
+    MAGENTA,
+    BROWN,
+    LIGHTGRAY,
+    DARKGRAY,
+    LIGHTBLUE,
+    LIGHTGREEN,
+    LIGHTCYAN,
+    LIGHTRED,
+    LIGHTMAGENTA,
+    YELLOW,
+    WHITE
+} COLORS;
+
+
+#define cgets	_cgets
+#define cprintf	_cprintf
+#define cputs	_cputs
+#define cscanf	_cscanf
+#define ScreenClear clrscr
+
+/* blinkvideo */
+
+void clreol (void);
+void clrscr (void);
+
+int _conio_gettext (int left, int top, int right, int bottom,
+                    char *str);
+/* _conio_kbhit */
+
+void delline (void);
+
+/* gettextinfo */
+void gotoxy(int x, int y);
+/*
+highvideo
+insline
+intensevideo
+lowvideo
+movetext
+normvideo
+*/
+
+void puttext (int left, int top, int right, int bottom, char *str);
+
+// Screen Variables
+
+/* ScreenCols
+ScreenGetChar
+ScreenGetCursor
+ScreenMode
+ScreenPutChar
+ScreenPutString
+ScreenRetrieve
+ScreenRows
+ScreenSetCursor
+ScreenUpdate
+ScreenUpdateLine
+ScreenVisualBell
+_set_screen_lines */
+
+void _setcursortype (int type);
+
+void textattr (int _attr);
+
+void textbackground (int color);
+
+void textcolor (int color);
+
+/* textmode */
+
+int wherex (void);
+
+int wherey (void);
+
+/* window */
+
+
+
+/*  The code below was part of Mingw's conio.h  */
+/*
+ * conio.h
+ *
+ * Low level console I/O functions. Pretty please try to use the ANSI
+ * standard ones if you are writing new code.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+char*	_cgets (char*);
+int	_cprintf (const char*, ...);
+int	_cputs (const char*);
+int	_cscanf (char*, ...);
+
+int	_getch (void);
+int	_getche (void);
+int	_kbhit (void);
+int	_putch (int);
+int	_ungetch (int);
+
+
+int	getch (void);
+int	getche (void);
+int	kbhit (void);
+int	putch (int);
+int	ungetch (int);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONIO_H_ */
diff --git a/tinyc/win32/include/ctype.h b/tinyc/win32/include/ctype.h
new file mode 100755
index 000000000..0c416a6e1
--- /dev/null
+++ b/tinyc/win32/include/ctype.h
@@ -0,0 +1,232 @@
+/* 
+ * ctype.h
+ *
+ * Functions for testing character types and converting characters.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define	__need_wchar_t
+#define	__need_wint_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+
+/*
+ * The following flags are used to tell iswctype and _isctype what character
+ * types you are looking for.
+ */
+#define	_UPPER		0x0001
+#define	_LOWER		0x0002
+#define	_DIGIT		0x0004
+#define	_SPACE		0x0008 /* HT  LF  VT  FF  CR  SP */
+#define	_PUNCT		0x0010
+#define	_CONTROL	0x0020
+#define	_BLANK		0x0040 /* this is SP only, not SP and HT as in C99  */
+#define	_HEX		0x0080
+#define	_LEADBYTE	0x8000
+
+#define	_ALPHA		0x0103
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int	isalnum(int);
+int	isalpha(int);
+int	iscntrl(int);
+int	isdigit(int);
+int	isgraph(int);
+int	islower(int);
+int	isprint(int);
+int	ispunct(int);
+int	isspace(int);
+int	isupper(int);
+int	isxdigit(int);
+
+#ifndef __STRICT_ANSI__
+int	_isctype (int, int);
+#endif
+
+/* These are the ANSI versions, with correct checking of argument */
+int	tolower(int);
+int	toupper(int);
+
+/*
+ * NOTE: The above are not old name type wrappers, but functions exported
+ * explicitly by MSVCRT/CRTDLL. However, underscored versions are also
+ * exported.
+ */
+#ifndef	__STRICT_ANSI__
+/*
+ *  These are the cheap non-std versions: The return values are undefined
+ *  if the argument is not ASCII char or is not of appropriate case
+ */ 
+int	_tolower(int);
+int	_toupper(int);
+#endif
+
+/* Also defined in stdlib.h */
+#ifndef MB_CUR_MAX
+# ifdef __MSVCRT__
+#  define MB_CUR_MAX __mb_cur_max
+   __MINGW_IMPORT int __mb_cur_max;
+# else /* not __MSVCRT */
+#  define MB_CUR_MAX __mb_cur_max_dll
+   __MINGW_IMPORT int __mb_cur_max_dll;
+# endif /* not __MSVCRT */
+#endif  /* MB_CUR_MAX */
+
+__MINGW_IMPORT unsigned short _ctype[];
+#ifdef __MSVCRT__
+__MINGW_IMPORT unsigned short* _pctype;
+#else /* CRTDLL */
+__MINGW_IMPORT unsigned short* _pctype_dll;
+#define  _pctype _pctype_dll
+#endif
+
+/*
+ * Use inlines here rather than macros, because macros will upset 
+ * C++ usage (eg, ::isalnum), and so usually get undefined
+ *
+ * According to standard for SB chars, these function are defined only
+ * for input values representable by unsigned char or EOF.
+ * Thus, there is no range test.
+ * This reproduces behaviour of MSVCRT.dll lib implemention for SB chars.
+ *
+ * If no MB char support is needed, these can be simplified even
+ * more by command line define -DMB_CUR_MAX=1.  The compiler will then
+ * optimise away the constant condition.			
+ */
+
+
+#if ! (defined (__NO_CTYPE_INLINES) || defined (__STRICT_ANSI__ ))
+/* use  simple lookup if SB locale, else  _isctype()  */
+#define __ISCTYPE(c, mask)  (MB_CUR_MAX == 1 ? (_pctype[c] & mask) : _isctype(c, mask))
+extern __inline__ int isalnum(int c) {return __ISCTYPE(c, (_ALPHA|_DIGIT));}
+extern __inline__ int isalpha(int c) {return __ISCTYPE(c, _ALPHA);}
+extern __inline__ int iscntrl(int c) {return __ISCTYPE(c, _CONTROL);}
+extern __inline__ int isdigit(int c) {return __ISCTYPE(c, _DIGIT);}
+extern __inline__ int isgraph(int c) {return __ISCTYPE(c, (_PUNCT|_ALPHA|_DIGIT));}
+extern __inline__ int islower(int c) {return __ISCTYPE(c, _LOWER);}
+extern __inline__ int isprint(int c) {return __ISCTYPE(c, (_BLANK|_PUNCT|_ALPHA|_DIGIT));}
+extern __inline__ int ispunct(int c) {return __ISCTYPE(c, _PUNCT);}
+extern __inline__ int isspace(int c) {return __ISCTYPE(c, _SPACE);}
+extern __inline__ int isupper(int c) {return __ISCTYPE(c, _UPPER);}
+extern __inline__ int isxdigit(int c) {return __ISCTYPE(c, _HEX);}
+
+/* these reproduce behaviour of lib underscored versions  */
+extern __inline__ int _tolower(int c) {return ( c -'A'+'a');}
+extern __inline__ int _toupper(int c) {return ( c -'a'+'A');}
+
+/* TODO? Is it worth inlining ANSI tolower, toupper? Probably only
+   if we only want C-locale. */
+
+#endif /* _NO_CTYPE_INLINES */
+
+/* Wide character equivalents */
+
+#ifndef WEOF
+#define	WEOF	(wchar_t)(0xFFFF)
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+typedef wchar_t wctype_t;
+#define _WCTYPE_T_DEFINED
+#endif
+
+int	iswalnum(wint_t);
+int	iswalpha(wint_t);
+int	iswascii(wint_t);
+int	iswcntrl(wint_t);
+int	iswctype(wint_t, wctype_t);
+int	is_wctype(wint_t, wctype_t);	/* Obsolete! */
+int	iswdigit(wint_t);
+int	iswgraph(wint_t);
+int	iswlower(wint_t);
+int	iswprint(wint_t);
+int	iswpunct(wint_t);
+int	iswspace(wint_t);
+int	iswupper(wint_t);
+int	iswxdigit(wint_t);
+
+wchar_t	towlower(wchar_t);
+wchar_t	towupper(wchar_t);
+
+int	isleadbyte (int);
+
+/* Also in wctype.h */
+#if ! (defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED))
+#define __WCTYPE_INLINES_DEFINED
+extern __inline__ int iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));}
+extern __inline__ int iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));}
+extern __inline__ int iswascii(wint_t wc) {return (((unsigned)wc & 0x7F) ==0);}
+extern __inline__ int iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));}
+extern __inline__ int iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));}
+extern __inline__ int iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));}
+extern __inline__ int iswlower(wint_t wc) {return (iswctype(wc,_LOWER));}
+extern __inline__ int iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));}
+extern __inline__ int iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));}
+extern __inline__ int iswspace(wint_t wc) {return (iswctype(wc,_SPACE));}
+extern __inline__ int iswupper(wint_t wc) {return (iswctype(wc,_UPPER));}
+extern __inline__ int iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));}
+extern __inline__ int isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);}
+#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */
+
+#ifndef	__STRICT_ANSI__
+int	__isascii (int);
+int	__toascii (int);
+int	__iscsymf (int);	/* Valid first character in C symbol */
+int	__iscsym (int);		/* Valid character in C symbol (after first) */
+
+#ifndef __NO_CTYPE_INLINES
+extern __inline__ int __isascii(int c) {return (((unsigned)c & ~0x7F) == 0);} 
+extern __inline__ int __toascii(int c) {return (c & 0x7F);}
+extern __inline__ int __iscsymf(int c) {return (isalpha(c) || (c == '_'));}
+extern __inline__ int __iscsym(int c)  {return  (isalnum(c) || (c == '_'));}
+#endif /* __NO_CTYPE_INLINES */
+
+#ifndef	_NO_OLDNAMES
+int	isascii (int);
+int	toascii (int);
+int	iscsymf (int);
+int	iscsym (int);
+#endif	/* Not _NO_OLDNAMES */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _CTYPE_H_ */
+
diff --git a/tinyc/win32/include/dir.h b/tinyc/win32/include/dir.h
new file mode 100755
index 000000000..d759a0a61
--- /dev/null
+++ b/tinyc/win32/include/dir.h
@@ -0,0 +1,26 @@
+/* 
+ * dir.h
+ *
+ * This file OBSOLESCENT and only provided for backward compatibility.
+ * Please use io.h instead.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *             Mumit Khan <khan@xraylith.wisc.edu>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <io.h>
+
diff --git a/tinyc/win32/include/direct.h b/tinyc/win32/include/direct.h
new file mode 100755
index 000000000..925f4c54c
--- /dev/null
+++ b/tinyc/win32/include/direct.h
@@ -0,0 +1,95 @@
+/*
+ * direct.h
+ *
+ * Functions for manipulating paths and directories (included from io.h)
+ * plus functions for setting the current drive.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef	_DIRECT_H_
+#define	_DIRECT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_wchar_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef _DISKFREE_T_DEFINED
+/* needed by _getdiskfree (also in dos.h) */
+struct _diskfree_t {
+	unsigned total_clusters;
+	unsigned avail_clusters;
+	unsigned sectors_per_cluster;
+	unsigned bytes_per_sector;
+};
+#define _DISKFREE_T_DEFINED
+#endif  
+
+/*
+ * You really shouldn't be using these. Use the Win32 API functions instead.
+ * However, it does make it easier to port older code.
+ */
+int	_getdrive (void);
+unsigned long _getdrives(void);
+int	_chdrive (int);
+char*	_getdcwd (int, char*, int);
+unsigned _getdiskfree (unsigned, struct _diskfree_t *);
+
+#ifndef	_NO_OLDNAMES
+# define diskfree_t _diskfree_t
+#endif
+
+#ifndef _WDIRECT_DEFINED
+/* wide character versions. Also in wchar.h */
+#ifdef __MSVCRT__ 
+int _wchdir(const wchar_t*);
+wchar_t* _wgetcwd(wchar_t*, int);
+wchar_t* _wgetdcwd(int, wchar_t*, int);
+int _wmkdir(const wchar_t*);
+int _wrmdir(const wchar_t*);
+#endif	/* __MSVCRT__ */
+#define _WDIRECT_DEFINED
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _DIRECT_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/dirent.h b/tinyc/win32/include/dirent.h
new file mode 100755
index 000000000..41c3dd715
--- /dev/null
+++ b/tinyc/win32/include/dirent.h
@@ -0,0 +1,96 @@
+/*
+ * DIRENT.H (formerly DIRLIB.H)
+ *
+ * by M. J. Weinstein   Released to public domain 1-Jan-89
+ *
+ * Because I have heard that this feature (opendir, readdir, closedir)
+ * it so useful for programmers coming from UNIX or attempting to port
+ * UNIX code, and because it is reasonably light weight, I have included
+ * it in the Mingw32 package. I have also added an implementation of
+ * rewinddir, seekdir and telldir.
+ *   - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  This code is distributed in the hope that is will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includeds but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dirent
+{
+	long		d_ino;		/* Always zero. */
+	unsigned short	d_reclen;	/* Always zero. */
+	unsigned short	d_namlen;	/* Length of name in d_name. */
+	char*		d_name;		/* File name. */
+	/* NOTE: The name in the dirent structure points to the name in the
+	 *       finddata_t structure in the DIR. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+	/* disk transfer area for this dir */
+	struct _finddata_t	dd_dta;
+
+	/* dirent struct to return from dir (NOTE: this makes this thread
+	 * safe as long as only one thread uses a particular DIR struct at
+	 * a time) */
+	struct dirent		dd_dir;
+
+	/* _findnext handle */
+	long			dd_handle;
+
+	/*
+         * Status of search:
+	 *   0 = not started yet (next entry to read is first entry)
+	 *  -1 = off the end
+	 *   positive = 0 based index of next entry
+	 */
+	short			dd_stat;
+
+	/* given path for dir with search pattern (struct is extended) */
+	char			dd_name[1];
+} DIR;
+
+
+DIR*		opendir (const char*);
+struct dirent*	readdir (DIR*);
+int		closedir (DIR*);
+void		rewinddir (DIR*);
+long		telldir (DIR*);
+void		seekdir (DIR*, long);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _DIRENT_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/dos.h b/tinyc/win32/include/dos.h
new file mode 100755
index 000000000..2cb380fba
--- /dev/null
+++ b/tinyc/win32/include/dos.h
@@ -0,0 +1,110 @@
+/*
+ * dos.h
+ *
+ * DOS-specific functions and structures.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by J.J. van der Heijden <J.J.vanderHeijden@student.utwente.nl>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_DOS_H_
+#define	_DOS_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_wchar_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+/* For DOS file attributes */
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __MSVCRT__ /* these are in CRTDLL, but not MSVCRT */
+#ifndef __DECLSPEC_SUPPORTED
+extern unsigned int *__imp__basemajor_dll;
+extern unsigned int *__imp__baseminor_dll;
+extern unsigned int *__imp__baseversion_dll;
+extern unsigned int *__imp__osmajor_dll;
+extern unsigned int *__imp__osminor_dll;
+extern unsigned int *__imp__osmode_dll;
+
+#define _basemajor (*__imp__basemajor_dll)
+#define _baseminor (*__imp__baseminor_dll)
+#define _baseversion (*__imp__baseversion_dll)
+#define _osmajor (*__imp__osmajor_dll)
+#define _osminor (*__imp__osminor_dll)
+#define _osmode (*__imp__osmode_dll)
+
+#else /* __DECLSPEC_SUPPORTED */
+
+__MINGW_IMPORT unsigned int _basemajor_dll;
+__MINGW_IMPORT unsigned int _baseminor_dll;
+__MINGW_IMPORT unsigned int _baseversion_dll;
+__MINGW_IMPORT unsigned int _osmajor_dll;
+__MINGW_IMPORT unsigned int _osminor_dll;
+__MINGW_IMPORT unsigned int _osmode_dll;
+
+#define _basemajor _basemajor_dll
+#define _baseminor _baseminor_dll
+#define _baseversion _baseversion_dll
+#define _osmajor _osmajor_dll
+#define _osminor _osminor_dll
+#define _osmode _osmode_dll
+
+#endif /* __DECLSPEC_SUPPORTED */
+#endif /* ! __MSVCRT__ */
+
+#ifndef _DISKFREE_T_DEFINED
+/* needed by _getdiskfree (also in direct.h) */
+struct _diskfree_t {
+	unsigned total_clusters;
+	unsigned avail_clusters;
+	unsigned sectors_per_cluster;
+	unsigned bytes_per_sector;
+};
+#define _DISKFREE_T_DEFINED
+#endif  
+
+unsigned _getdiskfree (unsigned, struct _diskfree_t *);
+
+#ifndef	_NO_OLDNAMES
+# define diskfree_t _diskfree_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _DOS_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/errno.h b/tinyc/win32/include/errno.h
new file mode 100755
index 000000000..b41a70e01
--- /dev/null
+++ b/tinyc/win32/include/errno.h
@@ -0,0 +1,117 @@
+/* 
+ * errno.h
+ *
+ * Error numbers and access to error reporting.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _ERRNO_H_
+#define	_ERRNO_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * Error numbers.
+ * TODO: Can't be sure of some of these assignments, I guessed from the
+ * names given by strerror and the defines in the Cygnus errno.h. A lot
+ * of the names from the Cygnus errno.h are not represented, and a few
+ * of the descriptions returned by strerror do not obviously match
+ * their error naming.
+ */
+#define EPERM		1	/* Operation not permitted */
+#define	ENOFILE		2	/* No such file or directory */
+#define	ENOENT		2
+#define	ESRCH		3	/* No such process */
+#define	EINTR		4	/* Interrupted function call */
+#define	EIO		5	/* Input/output error */
+#define	ENXIO		6	/* No such device or address */
+#define	E2BIG		7	/* Arg list too long */
+#define	ENOEXEC		8	/* Exec format error */
+#define	EBADF		9	/* Bad file descriptor */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Resource temporarily unavailable */
+#define	ENOMEM		12	/* Not enough space */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+/* 15 - Unknown Error */
+#define	EBUSY		16	/* strerror reports "Resource device" */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Improper link (cross-device link?) */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* Too many open files in system */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Inappropriate I/O control operation */
+/* 26 - Unknown Error */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Invalid seek (seek on a pipe?) */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Domain error (math functions) */
+#define	ERANGE		34	/* Result too large (possibly too small) */
+/* 35 - Unknown Error */
+#define	EDEADLOCK	36	/* Resource deadlock avoided (non-Cyg) */
+#define	EDEADLK		36
+/* 37 - Unknown Error */
+#define	ENAMETOOLONG	38	/* Filename too long (91 in Cyg?) */
+#define	ENOLCK		39	/* No locks available (46 in Cyg?) */
+#define	ENOSYS		40	/* Function not implemented (88 in Cyg?) */
+#define	ENOTEMPTY	41	/* Directory not empty (90 in Cyg?) */
+#define	EILSEQ		42	/* Illegal byte sequence */
+
+/*
+ * NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the
+ *       sockets.h header provided with windows32api-0.1.2.
+ *       You should go and put an #if 0 ... #endif around the whole block
+ *       of errors (look at the comment above them).
+ */
+
+#ifndef	RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see
+ * stdlib.h.
+ */
+#ifdef _UWIN
+#undef errno
+extern int errno;
+#else
+int*	_errno(void);
+#define	errno		(*_errno())
+#endif
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _ERRNO_H_ */
diff --git a/tinyc/win32/include/excpt.h b/tinyc/win32/include/excpt.h
new file mode 100755
index 000000000..774612458
--- /dev/null
+++ b/tinyc/win32/include/excpt.h
@@ -0,0 +1,20 @@
+#ifndef _EXCPT_H
+#define _EXCPT_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+/* FIXME: This will make some code compile. The programs will most
+   likely crash when an exception is raised, but at least they will
+   compile. */
+#ifdef __GNUC__
+#define __try
+#define __except(x) if (0) /* don't execute handler */
+#define __finally
+
+#define _try __try
+#define _except __except
+#define _finally __finally
+#endif
+
+#endif
diff --git a/tinyc/win32/include/fcntl.h b/tinyc/win32/include/fcntl.h
new file mode 100755
index 000000000..32f4a90e8
--- /dev/null
+++ b/tinyc/win32/include/fcntl.h
@@ -0,0 +1,135 @@
+/*
+ * fcntl.h
+ *
+ * Access constants for _open. Note that the permissions constants are
+ * in sys/stat.h (ick).
+ *
+ * This code is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _FCNTL_H_
+#define _FCNTL_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * It appears that fcntl.h should include io.h for compatibility...
+ */
+#include <io.h>
+
+/* Specifiy one of these flags to define the access mode. */
+#define	_O_RDONLY	0
+#define _O_WRONLY	1
+#define _O_RDWR		2
+
+/* Mask for access mode bits in the _open flags. */
+#define _O_ACCMODE	(_O_RDONLY|_O_WRONLY|_O_RDWR)
+
+#define	_O_APPEND	0x0008	/* Writes will add to the end of the file. */
+
+#define	_O_RANDOM	0x0010
+#define	_O_SEQUENTIAL	0x0020
+#define	_O_TEMPORARY	0x0040	/* Make the file dissappear after closing.
+				 * WARNING: Even if not created by _open! */
+#define	_O_NOINHERIT	0x0080
+
+#define	_O_CREAT	0x0100	/* Create the file if it does not exist. */
+#define	_O_TRUNC	0x0200	/* Truncate the file if it does exist. */
+#define	_O_EXCL		0x0400	/* Open only if the file does not exist. */
+
+/* NOTE: Text is the default even if the given _O_TEXT bit is not on. */
+#define	_O_TEXT		0x4000	/* CR-LF in file becomes LF in memory. */
+#define	_O_BINARY	0x8000	/* Input and output is not translated. */
+#define	_O_RAW		_O_BINARY
+
+#ifndef	_NO_OLDNAMES
+
+/* POSIX/Non-ANSI names for increased portability */
+#define	O_RDONLY	_O_RDONLY
+#define O_WRONLY	_O_WRONLY
+#define O_RDWR		_O_RDWR
+#define O_ACCMODE	_O_ACCMODE
+#define	O_APPEND	_O_APPEND
+#define	O_CREAT		_O_CREAT
+#define	O_TRUNC		_O_TRUNC
+#define	O_EXCL		_O_EXCL
+#define	O_TEXT		_O_TEXT
+#define	O_BINARY	_O_BINARY
+#define	O_TEMPORARY	_O_TEMPORARY
+#define O_NOINHERIT	_O_NOINHERIT
+#define O_SEQENTIAL	_O_SEQUENTIAL
+#define	O_RANDOM	_O_RANDOM
+
+#endif	/* Not _NO_OLDNAMES */
+
+
+#ifndef RC_INVOKED
+
+/*
+ * This variable determines the default file mode.
+ * TODO: Which flags work?
+ */
+#ifndef __DECLSPEC_SUPPORTED
+
+#ifdef __MSVCRT__
+extern unsigned int* __imp__fmode;
+#define	_fmode	(*__imp__fmode)
+#else
+/* CRTDLL */
+extern unsigned int* __imp__fmode_dll;
+#define	_fmode	(*__imp__fmode_dll)
+#endif
+
+#else /* __DECLSPEC_SUPPORTED */
+
+#ifdef __MSVCRT__
+__MINGW_IMPORT unsigned int _fmode;
+#else /* ! __MSVCRT__ */
+__MINGW_IMPORT unsigned int _fmode_dll;
+#define	_fmode	_fmode_dll
+#endif /* ! __MSVCRT__ */
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int	_setmode (int, int);
+
+#ifndef	_NO_OLDNAMES
+int	setmode (int, int);
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _FCNTL_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/fenv.h b/tinyc/win32/include/fenv.h
new file mode 100755
index 000000000..ddc43dfc8
--- /dev/null
+++ b/tinyc/win32/include/fenv.h
@@ -0,0 +1,85 @@
+#ifndef _FENV_H
+#define _FENV_H
+
+/*
+  For now, support only for the basic abstraction of flags that are
+  either set or clear. fexcept_t could be  structure that holds more info
+  about the fp environment.
+*/
+typedef unsigned short fexcept_t;
+
+/* This 28-byte struct represents the entire floating point
+   environment as stored by fnstenv or fstenv */
+typedef struct
+{
+  unsigned short __control_word;
+  unsigned short __unused0;
+  unsigned short __status_word;
+  unsigned short __unused1;
+  unsigned short __tag_word;
+  unsigned short __unused2;  
+  unsigned int	 __ip_offset;    /* instruction pointer offset */
+  unsigned short __ip_selector;  
+  unsigned short __opcode;
+  unsigned int	 __data_offset;
+  unsigned short __data_selector;  
+  unsigned short __unused3;
+} fenv_t;
+
+
+/* FPU status word exception flags */
+#define FE_INVALID	0x01
+#define FE_DENORMAL	0x02
+#define FE_DIVBYZERO	0x04
+#define FE_OVERFLOW	0x08
+#define FE_UNDERFLOW	0x10
+#define FE_INEXACT	0x20
+#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \
+		       | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
+
+/* FPU control word rounding flags */
+#define FE_TONEAREST	0x0000
+#define FE_DOWNWARD	0x0400
+#define FE_UPWARD	0x0800
+#define FE_TOWARDZERO	0x0c00
+
+
+/* The default floating point environment */
+#define FE_DFL_ENV ((const fenv_t *)-1)
+
+
+#ifndef RC_INVOKED
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*TODO: Some of these could be inlined */
+/* 7.6.2 Exception */
+
+extern int feclearexcept (int);
+extern int fegetexceptflag (fexcept_t * flagp, int excepts);
+extern int feraiseexcept (int excepts );
+extern int fesetexceptflag (const fexcept_t *, int);
+extern int fetestexcept (int excepts);
+
+
+/* 7.6.3 Rounding */
+
+extern int fegetround (void);
+extern int fesetround (int mode);
+
+
+/* 7.6.4 Environment */
+
+extern int fegetenv (fenv_t * envp);
+extern int fesetenv (const fenv_t * );
+extern int feupdateenv (const fenv_t *);
+extern int feholdexcept (fenv_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif	/* Not RC_INVOKED */
+
+#endif /* ndef _FENV_H */
diff --git a/tinyc/win32/include/float.h b/tinyc/win32/include/float.h
new file mode 100755
index 000000000..a6fb6dbe0
--- /dev/null
+++ b/tinyc/win32/include/float.h
@@ -0,0 +1,224 @@
+/* 
+ * float.h
+ *
+ * Constants related to floating point arithmetic.
+ *
+ * Also included here are some non-ANSI bits for accessing the floating
+ * point controller.
+ *
+ * NOTE: GCC provides float.h, and it is probably more accurate than this,
+ *       but it doesn't include the non-standard stuff for accessing the
+ *       fp controller. (TODO: Move those bits elsewhere?) Thus it is
+ *       probably not a good idea to use the GCC supplied version instead
+ *       of this header.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define FLT_ROUNDS	1
+#define FLT_GUARD	1
+#define FLT_NORMALIZE	1
+
+/*
+ * The characteristics of float.
+ */
+
+/* The radix for floating point representation. */
+#define FLT_RADIX	2
+
+/* Decimal digits of precision. */
+#define FLT_DIG		6
+
+/* Smallest number such that 1+x != 1 */
+#define FLT_EPSILON	1.19209290e-07F
+
+/* The number of base FLT_RADIX digits in the mantissa. */
+#define FLT_MANT_DIG	24
+
+/* The maximum floating point number. */
+#define FLT_MAX		3.40282347e+38F
+
+/* Maximum n such that FLT_RADIX^n - 1 is representable. */
+#define FLT_MAX_EXP	128
+
+/* Maximum n such that 10^n is representable. */
+#define FLT_MAX_10_EXP	38
+
+/* Minimum normalized floating-point number. */
+#define FLT_MIN		1.17549435e-38F
+
+/* Minimum n such that FLT_RADIX^n is a normalized number. */
+#define FLT_MIN_EXP	(-125)
+
+/* Minimum n such that 10^n is a normalized number. */
+#define FLT_MIN_10_EXP	(-37)
+
+
+/*
+ * The characteristics of double.
+ */
+#define DBL_DIG		15
+#define DBL_EPSILON	1.1102230246251568e-16
+#define DBL_MANT_DIG	53
+#define DBL_MAX		1.7976931348623157e+308
+#define DBL_MAX_EXP	1024
+#define DBL_MAX_10_EXP	308
+#define DBL_MIN		2.2250738585072014e-308
+#define DBL_MIN_EXP	(-1021)
+#define DBL_MIN_10_EXP	(-307)
+
+
+/*
+ * The characteristics of long double.
+ * NOTE: long double is the same as double.
+ */
+#define LDBL_DIG	15
+#define LDBL_EPSILON	1.1102230246251568e-16L
+#define LDBL_MANT_DIG	53
+#define LDBL_MAX	1.7976931348623157e+308L
+#define LDBL_MAX_EXP	1024
+#define LDBL_MAX_10_EXP	308
+#define LDBL_MIN	2.2250738585072014e-308L
+#define LDBL_MIN_EXP	(-1021)
+#define LDBL_MIN_10_EXP	(-307)
+
+
+/*
+ * Functions and definitions for controlling the FPU.
+ */
+#ifndef	__STRICT_ANSI__
+
+/* TODO: These constants are only valid for x86 machines */
+
+/* Control word masks for unMask */
+#define	_MCW_EM		0x0008001F	/* Error masks */
+#define	_MCW_IC		0x00040000	/* Infinity */
+#define	_MCW_RC		0x00000300	/* Rounding */
+#define	_MCW_PC		0x00030000	/* Precision */
+
+/* Control word values for unNew (use with related unMask above) */
+#define	_EM_INVALID	0x00000010
+#define	_EM_DENORMAL	0x00080000
+#define	_EM_ZERODIVIDE	0x00000008
+#define	_EM_OVERFLOW	0x00000004
+#define	_EM_UNDERFLOW	0x00000002
+#define	_EM_INEXACT	0x00000001
+#define	_IC_AFFINE	0x00040000
+#define	_IC_PROJECTIVE	0x00000000
+#define	_RC_CHOP	0x00000300
+#define	_RC_UP		0x00000200
+#define	_RC_DOWN	0x00000100
+#define	_RC_NEAR	0x00000000
+#define	_PC_24		0x00020000
+#define	_PC_53		0x00010000
+#define	_PC_64		0x00000000
+
+/* These are also defined in Mingw math.h, needed to work around
+   GCC build issues.  */
+/* Return values for fpclass. */
+#ifndef __MINGW_FPCLASS_DEFINED
+#define __MINGW_FPCLASS_DEFINED 1
+#define	_FPCLASS_SNAN	0x0001	/* Signaling "Not a Number" */
+#define	_FPCLASS_QNAN	0x0002	/* Quiet "Not a Number" */
+#define	_FPCLASS_NINF	0x0004	/* Negative Infinity */
+#define	_FPCLASS_NN	0x0008	/* Negative Normal */
+#define	_FPCLASS_ND	0x0010	/* Negative Denormal */
+#define	_FPCLASS_NZ	0x0020	/* Negative Zero */
+#define	_FPCLASS_PZ	0x0040	/* Positive Zero */
+#define	_FPCLASS_PD	0x0080	/* Positive Denormal */
+#define	_FPCLASS_PN	0x0100	/* Positive Normal */
+#define	_FPCLASS_PINF	0x0200	/* Positive Infinity */
+#endif /* __MINGW_FPCLASS_DEFINED */
+
+/* invalid subconditions (_SW_INVALID also set) */
+#define _SW_UNEMULATED		0x0040  /* unemulated instruction */
+#define _SW_SQRTNEG		0x0080  /* square root of a neg number */
+#define _SW_STACKOVERFLOW	0x0200  /* FP stack overflow */
+#define _SW_STACKUNDERFLOW	0x0400  /* FP stack underflow */
+
+/*  Floating point error signals and return codes */
+#define _FPE_INVALID		0x81
+#define _FPE_DENORMAL		0x82
+#define _FPE_ZERODIVIDE		0x83
+#define _FPE_OVERFLOW		0x84
+#define _FPE_UNDERFLOW		0x85
+#define _FPE_INEXACT		0x86
+#define _FPE_UNEMULATED		0x87
+#define _FPE_SQRTNEG		0x88
+#define _FPE_STACKOVERFLOW	0x8a
+#define _FPE_STACKUNDERFLOW	0x8b
+#define _FPE_EXPLICITGEN	0x8c    /* raise( SIGFPE ); */
+
+#ifndef RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask),
+ * i.e. change the bits in unMask to have the values they have in unNew,
+ * leaving other bits unchanged. */
+unsigned int	_controlfp (unsigned int unNew, unsigned int unMask);
+unsigned int	_control87 (unsigned int unNew, unsigned int unMask);
+
+
+unsigned int	_clearfp (void);	/* Clear the FPU status word */
+unsigned int	_statusfp (void);	/* Report the FPU status word */
+#define		_clear87	_clearfp
+#define		_status87	_statusfp
+
+void		_fpreset (void);	/* Reset the FPU */
+void		fpreset (void);
+
+/* Global 'variable' for the current floating point error code. */
+int *	__fpecode(void);
+#define	_fpecode	(*(__fpecode()))
+
+/*
+ * IEEE recommended functions
+ */
+
+double	_chgsign	(double);
+double	_copysign	(double, double);
+double	_logb		(double);
+double	_nextafter	(double, double);
+double	_scalb		(double, long);
+
+int	_finite		(double);
+int	_fpclass	(double);
+int	_isnan		(double);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+#endif /* _FLOAT_H_ */
+
diff --git a/tinyc/win32/include/inttypes.h b/tinyc/win32/include/inttypes.h
new file mode 100755
index 000000000..74944f14b
--- /dev/null
+++ b/tinyc/win32/include/inttypes.h
@@ -0,0 +1,275 @@
+/* 7.8 Format conversion of integer types <inttypes.h> */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#include <stdint.h>
+#define __need_wchar_t
+#include <stddef.h>
+
+#ifdef	__cplusplus
+extern	"C"	{
+#endif
+
+typedef struct {
+	intmax_t quot;
+	intmax_t rem;
+	} imaxdiv_t;
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+
+/* 7.8.1 Macros for format specifiers
+ * 
+ * MS runtime does not yet understand C9x standard "ll"
+ * length specifier. It appears to treat "ll" as "l".
+ * The non-standard I64 length specifier causes warning in GCC,
+ * but understood by MS runtime functions.
+ */
+
+/* fprintf macros for signed types */
+#define PRId8 "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 "I64d"
+
+#define PRIdLEAST8 "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 "I64d"
+
+#define PRIdFAST8 "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 "I64d"
+
+#define PRIdMAX "I64d"
+#define PRIdPTR "d"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 "I64i"
+
+#define PRIiLEAST8 "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 "I64i"
+
+#define PRIiFAST8 "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 "I64i"
+
+#define PRIiMAX "I64i"
+#define PRIiPTR "i"
+
+#define PRIo8 "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 "I64o"
+
+#define PRIoLEAST8 "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 "I64o"
+
+#define PRIoFAST8 "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 "I64o"
+
+#define PRIoMAX "I64o"
+
+#define PRIoPTR "o"
+
+/* fprintf macros for unsigned types */
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "I64u"
+
+
+#define PRIuLEAST8 "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 "I64u"
+
+#define PRIuFAST8 "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 "I64u"
+
+#define PRIuMAX "I64u"
+#define PRIuPTR "u"
+
+#define PRIx8 "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 "I64x"
+
+#define PRIxLEAST8 "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 "I64x"
+
+#define PRIxFAST8 "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 "I64x"
+
+#define PRIxMAX "I64x"
+#define PRIxPTR "x"
+
+#define PRIX8 "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 "I64X"
+
+#define PRIXLEAST8 "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 "I64X"
+
+#define PRIXFAST8 "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 "I64X"
+
+#define PRIXMAX "I64X"
+#define PRIXPTR "X"
+
+/*
+ *   fscanf macros for signed int types
+ *   NOTE: if 32-bit int is used for int_fast8_t and int_fast16_t
+ *   (see stdint.h, 7.18.1.3), FAST8 and FAST16 should have
+ *   no length identifiers
+ */
+
+#define SCNd16 "hd"
+#define SCNd32 "d"
+#define SCNd64 "I64d"
+
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 "I64d"
+
+#define SCNdFAST16 "hd"
+#define SCNdFAST32 "d"
+#define SCNdFAST64 "I64d"
+
+#define SCNdMAX "I64d"
+#define SCNdPTR "d"
+
+#define SCNi16 "hi"
+#define SCNi32 "i"
+#define SCNi64 "I64i"
+
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 "I64i"
+
+#define SCNiFAST16 "hi"
+#define SCNiFAST32 "i"
+#define SCNiFAST64 "I64i"
+
+#define SCNiMAX "I64i"
+#define SCNiPTR "i"
+
+#define SCNo16 "ho"
+#define SCNo32 "o"
+#define SCNo64 "I64o"
+
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 "I64o"
+
+#define SCNoFAST16 "ho"
+#define SCNoFAST32 "o"
+#define SCNoFAST64 "I64o"
+
+#define SCNoMAX "I64o"
+#define SCNoPTR "o"
+
+#define SCNx16 "hx"
+#define SCNx32 "x"
+#define SCNx64 "I64x"
+
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 "I64x"
+
+#define SCNxFAST16 "hx"
+#define SCNxFAST32 "x"
+#define SCNxFAST64 "I64x"
+
+#define SCNxMAX "I64x"
+#define SCNxPTR "x"
+
+
+/* fscanf macros for unsigned int types */
+
+#define SCNu16 "hu"
+#define SCNu32 "u"
+#define SCNu64 "I64u"
+
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 "I64u"
+
+#define SCNuFAST16 "hu"
+#define SCNuFAST32 "u"
+#define SCNuFAST64 "I64u"
+
+#define SCNuMAX "I64u"
+#define SCNuPTR "u"
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+/*
+ * no length modifier for char types prior to C9x
+ * MS runtime  scanf appears to treat "hh" as "h" 
+ */
+
+/* signed char */
+#define SCNd8 "hhd"
+#define SCNdLEAST8 "hhd"
+#define SCNdFAST8 "hhd"
+
+#define SCNi8 "hhi"
+#define SCNiLEAST8 "hhi"
+#define SCNiFAST8 "hhi"
+
+#define SCNo8 "hho"
+#define SCNoLEAST8 "hho"
+#define SCNoFAST8 "hho"
+
+#define SCNx8 "hhx"
+#define SCNxLEAST8 "hhx"
+#define SCNxFAST8 "hhx"
+
+/* unsigned char */
+#define SCNu8 "hhu"
+#define SCNuLEAST8 "hhu"
+#define SCNuFAST8 "hhu"
+#endif /* __STDC_VERSION__ >= 199901 */
+
+#endif	/* !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) */
+
+extern inline intmax_t	imaxabs (intmax_t j)
+	{return	(j >= 0 ? j : -j);}
+imaxdiv_t imaxdiv (intmax_t numer, intmax_t denom);
+
+/* 7.8.2 Conversion functions for greatest-width integer types */
+
+intmax_t   strtoimax (const char* __restrict__ nptr, char** __restrict__ endptr, int base);
+uintmax_t  strtoumax (const char* __restrict__ nptr, char** __restrict__ endptr, int base);
+
+intmax_t wcstoimax (const wchar_t* __restrict__ nptr, wchar_t** __restrict__ endptr,
+	   int base);
+uintmax_t wcstoumax (const wchar_t* __restrict__ nptr, wchar_t** __restrict__ endptr,
+	   int base);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* ndef _INTTYPES_H */
diff --git a/tinyc/win32/include/io.h b/tinyc/win32/include/io.h
new file mode 100755
index 000000000..8d5115e6c
--- /dev/null
+++ b/tinyc/win32/include/io.h
@@ -0,0 +1,296 @@
+/* 
+ * io.h
+ *
+ * System level I/O functions and types.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_IO_H_
+#define	_IO_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/* We need the definition of FILE anyway... */
+#include <stdio.h>
+
+/* MSVC's io.h contains the stuff from dir.h, so I will too.
+ * NOTE: This also defines off_t, the file offset type, through
+ *       an inclusion of sys/types.h */
+#ifndef __STRICT_ANSI__
+
+#include <sys/types.h>	/* To get time_t. */
+
+/*
+ * Attributes of files as returned by _findfirst et al.
+ */
+#define	_A_NORMAL	0x00000000
+#define	_A_RDONLY	0x00000001
+#define	_A_HIDDEN	0x00000002
+#define	_A_SYSTEM	0x00000004
+#define	_A_VOLID	0x00000008
+#define	_A_SUBDIR	0x00000010
+#define	_A_ARCH		0x00000020
+
+
+#ifndef RC_INVOKED
+
+#ifndef	_FSIZE_T_DEFINED
+typedef	unsigned long	_fsize_t;
+#define _FSIZE_T_DEFINED
+#endif
+
+/*
+ * The following structure is filled in by _findfirst or _findnext when
+ * they succeed in finding a match.
+ */
+struct _finddata_t
+{
+	unsigned	attrib;		/* Attributes, see constants above. */
+	time_t		time_create;
+	time_t		time_access;	/* always midnight local time */
+	time_t		time_write;
+	_fsize_t	size;
+	char		name[FILENAME_MAX];	/* may include spaces. */
+};
+
+struct _finddatai64_t {
+    unsigned    attrib;
+    time_t      time_create;
+    time_t      time_access;
+    time_t      time_write;
+    __int64     size;
+    char        name[FILENAME_MAX];
+};
+
+
+#ifndef _WFINDDATA_T_DEFINED
+struct _wfinddata_t {
+    	unsigned	attrib;
+    	time_t		time_create;	/* -1 for FAT file systems */
+    	time_t		time_access;	/* -1 for FAT file systems */
+    	time_t		time_write;
+    	_fsize_t	size;
+    	wchar_t		name[FILENAME_MAX];	/* may include spaces. */
+};
+struct _wfinddatai64_t {
+    unsigned    attrib;
+    time_t      time_create;
+    time_t      time_access;
+    time_t      time_write;
+    __int64     size;
+    wchar_t     name[FILENAME_MAX];
+};
+
+#define _WFINDDATA_T_DEFINED
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Functions for searching for files. _findfirst returns -1 if no match
+ * is found. Otherwise it returns a handle to be used in _findnext and
+ * _findclose calls. _findnext also returns -1 if no match could be found,
+ * and 0 if a match was found. Call _findclose when you are finished.
+ */
+int	_findfirst (const char*, struct _finddata_t*);
+int	_findnext (int, struct _finddata_t*);
+int	_findclose (int);
+
+int	_chdir (const char*);
+char*	_getcwd (char*, int);
+int	_mkdir (const char*);
+char*	_mktemp (char*);
+int	_rmdir (const char*);
+
+
+#ifdef __MSVCRT__
+__int64  _filelengthi64(int);
+long _findfirsti64(const char*, struct _finddatai64_t*);
+int _findnexti64(long, struct _finddatai64_t*);
+__int64  _lseeki64(int, __int64, int);
+__int64  _telli64(int);
+#endif /* __MSVCRT__ */
+
+
+#ifndef _NO_OLDNAMES
+
+#ifndef _UWIN
+int	chdir (const char*);
+char*	getcwd (char*, int);
+int	mkdir (const char*);
+char*	mktemp (char*);
+int	rmdir (const char*);
+#endif /* _UWIN */
+
+#endif /* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+/* TODO: Maximum number of open handles has not been tested, I just set
+ * it the same as FOPEN_MAX. */
+#define	HANDLE_MAX	FOPEN_MAX
+
+
+/* Some defines for _access nAccessMode (MS doesn't define them, but
+ * it doesn't seem to hurt to add them). */
+#define	F_OK	0	/* Check for file existence */
+#define	X_OK	1	/* Check for execute permission. */
+#define	W_OK	2	/* Check for write permission */
+#define	R_OK	4	/* Check for read permission */
+
+#ifndef RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int		_access (const char*, int);
+int		_chsize (int, long);
+int		_close (int);
+int		_commit(int);
+
+/* NOTE: The only significant bit in unPermissions appears to be bit 7 (0x80),
+ *       the "owner write permission" bit (on FAT). */
+int		_creat (const char*, unsigned);
+
+int		_dup (int);
+int		_dup2 (int, int);
+long		_filelength (int);
+int		_fileno (FILE*);
+long		_get_osfhandle (int);
+int		_isatty (int);
+
+/* In a very odd turn of events this function is excluded from those
+ * files which define _STREAM_COMPAT. This is required in order to
+ * build GNU libio because of a conflict with _eof in streambuf.h
+ * line 107. Actually I might just be able to change the name of
+ * the enum member in streambuf.h... we'll see. TODO */
+#ifndef	_STREAM_COMPAT
+int		_eof (int);
+#endif
+
+/* LK_... locking commands defined in sys/locking.h. */
+int		_locking (int, int, long);
+
+long		_lseek (int, long, int);
+
+/* Optional third argument is unsigned unPermissions. */
+int		_open (const char*, int, ...);
+
+int		_open_osfhandle (long, int);
+int		_pipe (int *, unsigned int, int);
+int		_read (int, void*, unsigned int);
+
+/* SH_... flags for nShFlags defined in share.h
+ * Optional fourth argument is unsigned unPermissions */
+int		_sopen (const char*, int, int, ...);
+
+long		_tell (int);
+/* Should umask be in sys/stat.h and/or sys/types.h instead? */
+int		_umask (int);
+int		_unlink (const char*);
+int		_write (int, const void*, unsigned int);
+
+/* Wide character versions. Also declared in wchar.h. */
+/* Not in crtdll.dll */
+#if !defined (_WIO_DEFINED)
+#if defined (__MSVCRT__)
+int 		_waccess(const wchar_t*, int);
+int 		_wchmod(const wchar_t*, int);
+int 		_wcreat(const wchar_t*, int);
+long 		_wfindfirst(wchar_t*, struct _wfinddata_t*);
+int 		_wfindnext(long, struct _wfinddata_t *);
+int 		_wunlink(const wchar_t*);
+int 		_wopen(const wchar_t*, int, ...);
+int 		_wsopen(const wchar_t*, int, int, ...);
+wchar_t * 	_wmktemp(wchar_t*);
+long  _wfindfirsti64(const wchar_t*, struct _wfinddatai64_t*);
+int  _wfindnexti64(long, struct _wfinddatai64_t*);
+#endif /* defined (__MSVCRT__) */
+#define _WIO_DEFINED
+#endif /* _WIO_DEFINED */
+
+#ifndef	_NO_OLDNAMES
+/*
+ * Non-underscored versions of non-ANSI functions to improve portability.
+ * These functions live in libmoldname.a.
+ */
+
+#ifndef _UWIN
+int		access (const char*, int);
+int		chsize (int, long );
+int		close (int);
+int		creat (const char*, int);
+int		dup (int);
+int		dup2 (int, int);
+int		eof (int);
+long		filelength (int);
+int		fileno (FILE*);
+int		isatty (int);
+long		lseek (int, long, int);
+int		open (const char*, int, ...);
+int		read (int, void*, unsigned int);
+int		sopen (const char*, int, int, ...);
+long		tell (int);
+int		umask (int);
+int		unlink (const char*);
+int		write (int, const void*, unsigned int);
+#endif /* _UWIN */
+
+/* Wide character versions. Also declared in wchar.h. */
+/* Where do these live? Not in libmoldname.a nor in libmsvcrt.a */
+#if 0
+int 		waccess(const wchar_t *, int);
+int 		wchmod(const wchar_t *, int);
+int 		wcreat(const wchar_t *, int);
+long 		wfindfirst(wchar_t *, struct _wfinddata_t *);
+int 		wfindnext(long, struct _wfinddata_t *);
+int 		wunlink(const wchar_t *);
+int 		wrename(const wchar_t *, const wchar_t *);
+int 		wopen(const wchar_t *, int, ...);
+int 		wsopen(const wchar_t *, int, int, ...);
+wchar_t * 	wmktemp(wchar_t *);
+#endif
+
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* _IO_H_ not defined */
+
+#endif	/* Not strict ANSI */
+
diff --git a/tinyc/win32/include/limits.h b/tinyc/win32/include/limits.h
new file mode 100755
index 000000000..5dc6025fd
--- /dev/null
+++ b/tinyc/win32/include/limits.h
@@ -0,0 +1,115 @@
+/* 
+ * limits.h
+ *
+ * Defines constants for the sizes of integral types.
+ *
+ * NOTE: GCC should supply a version of this header and it should be safe to
+ *       use that version instead of this one (maybe safer).
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _LIMITS_H_
+#define _LIMITS_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * File system limits
+ *
+ * TODO: NAME_MAX and OPEN_MAX are file system limits or not? Are they the
+ *       same as FILENAME_MAX and FOPEN_MAX from stdio.h?
+ * NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
+ *       required for the NUL. TODO: Test?
+ */
+#define PATH_MAX	(259)
+
+/*
+ * Characteristics of the char data type.
+ *
+ * TODO: Is MB_LEN_MAX correct?
+ */
+#define CHAR_BIT	8
+#define MB_LEN_MAX	2
+
+#define SCHAR_MIN	(-128)
+#define SCHAR_MAX	127
+
+#define UCHAR_MAX	255
+
+/* TODO: Is this safe? I think it might just be testing the preprocessor,
+ *       not the compiler itself... */
+#if	('\x80' < 0)
+#define CHAR_MIN	SCHAR_MIN
+#define CHAR_MAX	SCHAR_MAX
+#else
+#define CHAR_MIN	0
+#define CHAR_MAX	UCHAR_MAX
+#endif
+
+/*
+ * Maximum and minimum values for ints.
+ */
+#define INT_MAX		2147483647
+#define INT_MIN		(-INT_MAX-1)
+
+#define UINT_MAX	0xffffffff
+
+/*
+ * Maximum and minimum values for shorts.
+ */
+#define SHRT_MAX	32767
+#define SHRT_MIN	(-SHRT_MAX-1)
+
+#define USHRT_MAX	0xffff
+
+/*
+ * Maximum and minimum values for longs and unsigned longs.
+ *
+ * TODO: This is not correct for Alphas, which have 64 bit longs.
+ */
+#define LONG_MAX	2147483647L
+
+#define LONG_MIN	(-LONG_MAX-1)
+
+#define ULONG_MAX	0xffffffffUL
+
+
+/*
+ * The GNU C compiler also allows 'long long int'
+ */
+#if	!defined(__STRICT_ANSI__) && defined(__GNUC__)
+
+#define LONG_LONG_MAX	9223372036854775807LL
+#define LONG_LONG_MIN	(-LONG_LONG_MAX-1)
+
+#define ULONG_LONG_MAX	(2ULL * LONG_LONG_MAX + 1)
+
+/* ISO C9x macro names */
+#define LLONG_MAX LONG_LONG_MAX
+#define LLONG_MIN LONG_LONG_MIN
+#define ULLONG_MAX ULONG_LONG_MAX
+
+#endif /* Not Strict ANSI and GNU C compiler */
+
+
+#endif /* not _LIMITS_H_ */
diff --git a/tinyc/win32/include/locale.h b/tinyc/win32/include/locale.h
new file mode 100755
index 000000000..d0da14d6b
--- /dev/null
+++ b/tinyc/win32/include/locale.h
@@ -0,0 +1,100 @@
+/* 
+ * locale.h
+ *
+ * Functions and types for localization (ie. changing the appearance of
+ * output based on the standards of a certain country).
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_LOCALE_H_
+#define	_LOCALE_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * NOTE: I have tried to test this, but I am limited by my knowledge of
+ *       locale issues. The structure does not bomb if you look at the
+ *       values, and 'decimal_point' even seems to be correct. But the
+ *       rest of the values are, by default, not particularly useful
+ *       (read meaningless and not related to the international settings
+ *       of the system).
+ */
+
+#define	LC_ALL		0
+#define LC_COLLATE	1
+#define LC_CTYPE	2
+#define	LC_MONETARY	3
+#define	LC_NUMERIC	4
+#define	LC_TIME		5
+#define	LC_MIN		LC_ALL
+#define	LC_MAX		LC_TIME
+
+#ifndef RC_INVOKED
+
+/*
+ * The structure returned by 'localeconv'.
+ */
+struct lconv
+{
+	char*	decimal_point;
+	char*	thousands_sep;
+	char*	grouping;
+	char*	int_curr_symbol;
+	char*	currency_symbol;
+	char*	mon_decimal_point;
+	char*	mon_thousands_sep;
+	char*	mon_grouping;
+	char*	positive_sign;
+	char*	negative_sign;
+	char	int_frac_digits;
+	char	frac_digits;
+	char	p_cs_precedes;
+	char	p_sep_by_space;
+	char	n_cs_precedes;
+	char	n_sep_by_space;
+	char	p_sign_posn;
+	char	n_sign_posn;
+};
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+char*		setlocale (int, const char*);
+struct lconv*	localeconv (void);
+
+#ifndef _WLOCALE_DEFINED  /* also declared in wchar.h */
+# define __need_wchar_t
+# include <stddef.h>
+  wchar_t* 	_wsetlocale(int, const wchar_t*);
+# define _WLOCALE_DEFINED
+#endif /* ndef _WLOCALE_DEFINED */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _LOCALE_H_ */
+
diff --git a/tinyc/win32/include/malloc.h b/tinyc/win32/include/malloc.h
new file mode 100755
index 000000000..ca4259689
--- /dev/null
+++ b/tinyc/win32/include/malloc.h
@@ -0,0 +1,87 @@
+/*
+ * malloc.h
+ *
+ * Support for programs which want to use malloc.h to get memory management
+ * functions. Unless you absolutely need some of these functions and they are
+ * not in the ANSI headers you should use the ANSI standard header files
+ * instead.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <stdlib.h>
+
+#ifndef RC_INVOKED
+
+/*
+ * The structure used to walk through the heap with _heapwalk.
+ */
+typedef	struct _heapinfo
+{
+	int*	_pentry;
+	size_t	_size;
+	int	_useflag;
+} _HEAPINFO;
+
+/* Values for _heapinfo.useflag */
+#define _USEDENTRY 0
+#define _FREEENTRY 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+/*
+   The _heap* memory allocation functions are supported on NT
+   but not W9x. On latter, they always set errno to ENOSYS.
+*/
+int	_heapwalk (_HEAPINFO*);
+
+#ifndef	_NO_OLDNAMES
+int	heapwalk (_HEAPINFO*);
+#endif	/* Not _NO_OLDNAMES */
+
+int	_heapchk (void);	/* Verify heap integrety. */
+int	_heapmin (void);	/* Return unused heap to the OS. */
+int	_heapset (unsigned int);
+
+size_t	_msize (void*);
+size_t	_get_sbh_threshold (void); 
+int	_set_sbh_threshold (size_t);
+void *	_expand (void*, size_t); 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* RC_INVOKED */
+
+#endif /* Not _MALLOC_H_ */
+
+#endif /* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/math.h b/tinyc/win32/include/math.h
new file mode 100755
index 000000000..ffb133a2f
--- /dev/null
+++ b/tinyc/win32/include/math.h
@@ -0,0 +1,438 @@
+/* 
+ * math.h
+ *
+ * Mathematical functions.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _MATH_H_
+#define _MATH_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * Types for the _exception structure.
+ */
+
+#define	_DOMAIN		1	/* domain error in argument */
+#define	_SING		2	/* singularity */
+#define	_OVERFLOW	3	/* range overflow */
+#define	_UNDERFLOW	4	/* range underflow */
+#define	_TLOSS		5	/* total loss of precision */
+#define	_PLOSS		6	/* partial loss of precision */
+
+/*
+ * Exception types with non-ANSI names for compatibility.
+ */
+
+#ifndef	__STRICT_ANSI__
+#ifndef	_NO_OLDNAMES
+
+#define	DOMAIN		_DOMAIN
+#define	SING		_SING
+#define	OVERFLOW	_OVERFLOW
+#define	UNDERFLOW	_UNDERFLOW
+#define	TLOSS		_TLOSS
+#define	PLOSS		_PLOSS
+
+#endif	/* Not _NO_OLDNAMES */
+#endif	/* Not __STRICT_ANSI__ */
+
+
+/* These are also defined in Mingw float.h; needed here as well to work 
+   around GCC build issues.  */
+#ifndef	__STRICT_ANSI__
+#ifndef __MINGW_FPCLASS_DEFINED
+#define __MINGW_FPCLASS_DEFINED 1
+/* IEEE 754 classication */
+#define	_FPCLASS_SNAN	0x0001	/* Signaling "Not a Number" */
+#define	_FPCLASS_QNAN	0x0002	/* Quiet "Not a Number" */
+#define	_FPCLASS_NINF	0x0004	/* Negative Infinity */
+#define	_FPCLASS_NN	0x0008	/* Negative Normal */
+#define	_FPCLASS_ND	0x0010	/* Negative Denormal */
+#define	_FPCLASS_NZ	0x0020	/* Negative Zero */
+#define	_FPCLASS_PZ	0x0040	/* Positive Zero */
+#define	_FPCLASS_PD	0x0080	/* Positive Denormal */
+#define	_FPCLASS_PN	0x0100	/* Positive Normal */
+#define	_FPCLASS_PINF	0x0200	/* Positive Infinity */
+#endif /* __MINGW_FPCLASS_DEFINED */
+#endif	/* Not __STRICT_ANSI__ */
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * HUGE_VAL is returned by strtod when the value would overflow the
+ * representation of 'double'. There are other uses as well.
+ *
+ * __imp__HUGE is a pointer to the actual variable _HUGE in
+ * MSVCRT.DLL. If we used _HUGE directly we would get a pointer
+ * to a thunk function.
+ *
+ * NOTE: The CRTDLL version uses _HUGE_dll instead.
+ */
+
+#ifndef __DECLSPEC_SUPPORTED
+
+#ifdef __MSVCRT__
+extern double*	__imp__HUGE;
+#define	HUGE_VAL	(*__imp__HUGE)
+#else
+/* CRTDLL */
+extern double*	__imp__HUGE_dll;
+#define	HUGE_VAL	(*__imp__HUGE_dll)
+#endif
+
+#else /* __DECLSPEC_SUPPORTED */
+
+#ifdef __MSVCRT__
+__MINGW_IMPORT double	_HUGE;
+#define	HUGE_VAL	_HUGE
+#else
+/* CRTDLL */
+__MINGW_IMPORT double	_HUGE_dll;
+#define	HUGE_VAL	_HUGE_dll
+#endif
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+struct _exception
+{
+	int	type;
+	char	*name;
+	double	arg1;
+	double	arg2;
+	double	retval;
+};
+
+
+double	sin (double);
+double	cos (double);
+double	tan (double);
+double	sinh (double);
+double	cosh (double);
+double	tanh (double);
+double	asin (double);
+double	acos (double);
+double	atan (double);
+double	atan2 (double, double);
+double	exp (double);
+double	log (double);
+double	log10 (double);
+double	pow (double, double);
+double	sqrt (double);
+double	ceil (double);
+double	floor (double);
+double	fabs (double);
+double	ldexp (double, int);
+double	frexp (double, int*);
+double	modf (double, double*);
+double	fmod (double, double);
+
+
+#ifndef	__STRICT_ANSI__
+
+/* Complex number (for cabs) */
+struct _complex
+{
+	double	x;	/* Real part */
+	double	y;	/* Imaginary part */
+};
+
+double	_cabs (struct _complex);
+double	_hypot (double, double);
+double	_j0 (double);
+double	_j1 (double);
+double	_jn (int, double);
+double	_y0 (double);
+double	_y1 (double);
+double	_yn (int, double);
+int	_matherr (struct _exception *);
+
+/* These are also declared in Mingw float.h; needed here as well to work 
+   around GCC build issues.  */
+/* BEGIN FLOAT.H COPY */
+/*
+ * IEEE recommended functions
+ */
+
+double	_chgsign	(double);
+double	_copysign	(double, double);
+double	_logb		(double);
+double	_nextafter	(double, double);
+double	_scalb		(double, long);
+
+int	_finite		(double);
+int	_fpclass	(double);
+int	_isnan		(double);
+
+/* END FLOAT.H COPY */
+
+#if !defined (_NO_OLDNAMES)  \
+   || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
+
+/*
+ * Non-underscored versions of non-ANSI functions. These reside in
+ * liboldnames.a. They are now also ISO C99 standand names.
+ * Provided for extra portability.
+ */
+
+double cabs (struct _complex);
+double hypot (double, double);
+double j0 (double);
+double j1 (double);
+double jn (int, double);
+double y0 (double);
+double y1 (double);
+double yn (int, double);
+
+#endif	/* Not _NO_OLDNAMES */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+#ifdef __cplusplus
+}
+#endif
+#endif	/* Not RC_INVOKED */
+
+
+#ifndef __NO_ISOCEXT
+
+#define INFINITY HUGE_VAL
+#define NAN (0.0F/0.0F)
+
+/*
+   Return values for fpclassify.
+   These are based on Intel x87 fpu condition codes
+   in the high byte of status word and differ from
+   the return values for MS IEEE 754 extension _fpclass()
+*/
+#define FP_NAN		0x0100
+#define FP_NORMAL	0x0400
+#define FP_INFINITE	(FP_NAN | FP_NORMAL)
+#define FP_ZERO		0x4000
+#define FP_SUBNORMAL	(FP_NORMAL | FP_ZERO)
+/* 0x0200 is signbit mask */
+
+#ifndef RC_INVOKED
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+double nan(const char *tagp);
+float nanf(const char *tagp);
+
+#ifndef __STRICT_ANSI__
+#define nan() nan("")
+#define nanf() nanf("")
+#endif
+
+
+/*
+  We can't inline float, because we want to ensure truncation
+  to semantic type before classification.  If we extend to long
+  double, we will also need to make double extern only.
+  (A normal long double value might become subnormal when 
+  converted to double, and zero when converted to float.)
+*/
+extern __inline__ int __fpclassify (double x){
+  unsigned short sw;
+  __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
+  return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
+}
+
+extern int __fpclassifyf (float);
+
+#define fpclassify(x) ((sizeof(x) == sizeof(float)) ? __fpclassifyf(x) \
+		       :  __fpclassify(x))
+
+/* We don't need to worry about trucation here:
+   A NaN stays a NaN. */
+
+extern __inline__ int __isnan (double _x)
+{
+  unsigned short sw;
+  __asm__ ("fxam;"
+	   "fstsw %%ax": "=a" (sw) : "t" (_x));
+  return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
+    == FP_NAN;
+}
+
+extern __inline__ int __isnanf (float _x)
+{
+  unsigned short sw;
+  __asm__ ("fxam;"
+	    "fstsw %%ax": "=a" (sw) : "t" (_x));
+  return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
+    == FP_NAN;
+}
+
+#define isnan(x) ((sizeof(x) == sizeof(float)) ? __isnanf(x) \
+		       :  __isnan(x))
+
+
+#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
+#define isinf(x) (fpclassify(x) == FP_INFINITE)
+#define isnormal(x) (fpclassify(x) == FP_NORMAL)
+
+
+extern __inline__ int __signbit (double x) {
+  unsigned short stw;
+  __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
+  return stw & 0x0200;
+}
+
+extern  __inline__ int __signbitf (float x) {
+  unsigned short stw;
+  __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
+  return stw & 0x0200;
+}
+
+#define signbit(x) ((sizeof(x) == sizeof(float)) ? __signbitf(x) \
+		    : __signbit(x))
+/* 
+ *  With these functions, comparisons involving quiet NaNs set the FP
+ *  condition code to "unordered".  The IEEE floating-point spec
+ *  dictates that the result of floating-point comparisons should be
+ *  false whenever a NaN is involved, with the exception of the !=, 
+ *  which always returns true.
+ */
+
+#if __GNUC__ >= 3
+
+#define isgreater(x, y) __builtin_isgreater(x, y)
+#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
+#define isless(x, y) __builtin_isless(x, y)
+#define islessequal(x, y) __builtin_islessequal(x, y)
+#define islessgreater(x, y) __builtin_islessgreater(x, y)
+#define isunordered(x, y) __builtin_isunordered(x, y)
+
+#else
+/*  helper  */
+extern  __inline__ int __fp_unordered_compare (double x,  double y){
+  unsigned short retval;
+  __asm__ ("fucom %%st(1);"
+	   "fnstsw;": "=a" (retval) : "t" (x), "u" (y));
+  return retval;
+}
+
+#define isgreater(x, y) ((__fp_unordered_compare(x, y) \
+			   & 0x4500) == 0)
+#define isless(x, y) ((__fp_unordered_compare (y, x) \
+                       & 0x4500) == 0)
+#define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
+                               & FP_INFINITE) == 0)
+#define islessequal(x, y) ((__fp_unordered_compare(y, x) \
+			    & FP_INFINITE) == 0)
+#define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
+			      & FP_SUBNORMAL) == 0)
+#define isunordered(x, y) ((__fp_unordered_compare(x, y) \
+			    & 0x4500) == 0x4500)
+
+#endif
+
+/* round, using fpu control word settings */
+extern  __inline__ double rint (double x)
+{
+  double retval;
+  __asm__ ("frndint;": "=t" (retval) : "0" (x));
+  return retval;
+}
+
+extern  __inline__ float rintf (float x)
+{
+  float retval;
+  __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
+  return retval;
+}
+
+/* round away from zero, regardless of fpu control word settings */
+extern double round (double);
+extern float roundf (float);
+
+/* round towards zero, regardless of fpu control word settings */
+extern double trunc (double);
+extern float truncf (float);
+
+
+/* fmax and fmin.
+   NaN arguments are treated as missing data: if one argument is a NaN and the other numeric, then the
+   these functions choose the numeric value.
+*/
+
+extern double fmax  (double, double);
+extern double fmin (double, double);
+extern float fmaxf (float, float);
+float fminf (float, float);
+
+/* return x * y + z as a ternary op */ 
+extern double fma (double, double, double);
+extern float fmaf (float, float, float);
+
+/* one lonely transcendental */
+extern double log2 (double _x);
+extern float log2f (float _x);
+
+/* The underscored versions are in MSVCRT.dll.
+   The stubs for these are in libmingwex.a */
+
+double copysign (double, double);
+float copysignf (float, float);
+double logb (double);
+float logbf (float);
+double nextafter (double, double);
+float nextafterf (float, float);
+double scalb (double, long);
+float scalbf (float, long);
+
+#if !defined (__STRICT_ANSI__)  /* inline using non-ANSI functions */
+extern  __inline__ double copysign (double x, double y)
+	{ return _copysign(x, y); }
+extern  __inline__ float copysignf (float x, float y)
+	{ return  _copysign(x, y); } 
+extern  __inline__ double logb (double x)
+	{ return _logb(x); }
+extern  __inline__ float logbf (float x)
+	{ return  _logb(x); }
+extern  __inline__ double nextafter(double x, double y)
+	{ return _nextafter(x, y); }
+extern  __inline__ float nextafterf(float x, float y)
+	{ return _nextafter(x, y); }
+extern  __inline__ double scalb (double x, long i)
+	{ return _scalb (x, i); }
+extern  __inline__ float scalbf (float x, long i)
+	{ return _scalb(x, i); }
+#endif /* (__STRICT_ANSI__)  */
+
+#ifdef __cplusplus
+}
+#endif
+#endif	/* Not RC_INVOKED */
+
+#endif /* __NO_ISOCEXT */
+
+#endif	/* Not _MATH_H_ */
+
diff --git a/tinyc/win32/include/mem.h b/tinyc/win32/include/mem.h
new file mode 100755
index 000000000..20c8fa4a5
--- /dev/null
+++ b/tinyc/win32/include/mem.h
@@ -0,0 +1,8 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * mem.h maps to string.h
+ */
+#ifndef	__STRICT_ANSI__
+#include <string.h>
+#endif
diff --git a/tinyc/win32/include/memory.h b/tinyc/win32/include/memory.h
new file mode 100755
index 000000000..e0c91d635
--- /dev/null
+++ b/tinyc/win32/include/memory.h
@@ -0,0 +1,9 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * memory.h maps to the standard string.h header.
+ */
+#ifndef	__STRICT_ANSI__
+#include	<string.h>
+#endif
+
diff --git a/tinyc/win32/include/process.h b/tinyc/win32/include/process.h
new file mode 100755
index 000000000..3d764df0f
--- /dev/null
+++ b/tinyc/win32/include/process.h
@@ -0,0 +1,158 @@
+/* 
+ * process.h
+ *
+ * Function calls for spawning child processes.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_PROCESS_H_
+#define	_PROCESS_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/* Includes a definition of _pid_t and pid_t */
+#include <sys/types.h>
+
+/*
+ * Constants for cwait actions.
+ * Obsolete for Win32.
+ */
+#define	_WAIT_CHILD		0
+#define	_WAIT_GRANDCHILD	1
+
+#ifndef	_NO_OLDNAMES
+#define	WAIT_CHILD		_WAIT_CHILD
+#define	WAIT_GRANDCHILD		_WAIT_GRANDCHILD
+#endif	/* Not _NO_OLDNAMES */
+
+/*
+ * Mode constants for spawn functions.
+ */
+#define	_P_WAIT		0
+#define	_P_NOWAIT	1
+#define	_P_OVERLAY	2
+#define	_OLD_P_OVERLAY	_P_OVERLAY
+#define	_P_NOWAITO	3
+#define	_P_DETACH	4
+
+#ifndef	_NO_OLDNAMES
+#define	P_WAIT		_P_WAIT
+#define	P_NOWAIT	_P_NOWAIT
+#define	P_OVERLAY	_P_OVERLAY
+#define	OLD_P_OVERLAY	_OLD_P_OVERLAY
+#define	P_NOWAITO	_P_NOWAITO
+#define	P_DETACH	_P_DETACH
+#endif	/* Not _NO_OLDNAMES */
+
+
+#ifndef RC_INVOKED
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void	_cexit(void);
+void	_c_exit(void);
+
+int	_cwait (int*, _pid_t, int);
+
+_pid_t	_getpid(void);
+
+int	_execl		(const char*, const char*, ...);
+int	_execle		(const char*, const char*, ...);
+int	_execlp		(const char*, const char*, ...);
+int	_execlpe	(const char*, const char*, ...);
+int	_execv		(const char*, char* const*);
+int	_execve		(const char*, char* const*, char* const*);
+int	_execvp		(const char*, char* const*);
+int	_execvpe	(const char*, char* const*, char* const*);
+
+int	_spawnl		(int, const char*, const char*, ...);
+int	_spawnle	(int, const char*, const char*, ...);
+int	_spawnlp	(int, const char*, const char*, ...);
+int	_spawnlpe	(int, const char*, const char*, ...);
+int	_spawnv		(int, const char*, char* const*);
+int	_spawnve	(int, const char*, char* const*, char* const*);
+int	_spawnvp	(int, const char*, char* const*);
+int	_spawnvpe	(int, const char*, char* const*, char* const*);
+
+/*
+ * The functions _beginthreadex and _endthreadex are not provided by CRTDLL.
+ * They are provided by MSVCRT.
+ *
+ * NOTE: Apparently _endthread calls CloseHandle on the handle of the thread,
+ * making for race conditions if you are not careful. Basically you have to
+ * make sure that no-one is going to do *anything* with the thread handle
+ * after the thread calls _endthread or returns from the thread function.
+ *
+ * NOTE: No old names for these functions. Use the underscore.
+ */
+unsigned long
+	_beginthread	(void (*)(void *), unsigned, void*);
+void	_endthread	(void);
+
+#ifdef	__MSVCRT__
+unsigned long
+	_beginthreadex	(void *, unsigned, unsigned (__stdcall *) (void *), 
+			 void*, unsigned, unsigned*);
+void	_endthreadex	(unsigned);
+#endif
+
+
+#ifndef	_NO_OLDNAMES
+/*
+ * Functions without the leading underscore, for portability. These functions
+ * live in liboldnames.a.
+ */
+int	cwait (int*, pid_t, int);
+pid_t	getpid (void);
+int	execl (const char*, const char*, ...);
+int	execle (const char*, const char*, ...);
+int	execlp (const char*, const char*, ...);
+int	execlpe (const char*, const char*, ...);
+int	execv (const char*, char* const*);
+int	execve (const char*, char* const*, char* const*);
+int	execvp (const char*, char* const*);
+int	execvpe (const char*, char* const*, char* const*);
+int	spawnl (int, const char*, const char*, ...);
+int	spawnle (int, const char*, const char*, ...);
+int	spawnlp (int, const char*, const char*, ...);
+int	spawnlpe (int, const char*, const char*, ...);
+int	spawnv (int, const char*, char* const*);
+int	spawnve (int, const char*, char* const*, char* const*);
+int	spawnvp (int, const char*, char* const*);
+int	spawnvpe (int, const char*, char* const*, char* const*);
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* _PROCESS_H_ not defined */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/setjmp.h b/tinyc/win32/include/setjmp.h
new file mode 100755
index 000000000..0d9897e63
--- /dev/null
+++ b/tinyc/win32/include/setjmp.h
@@ -0,0 +1,72 @@
+/* 
+ * setjmp.h
+ *
+ * Declarations supporting setjmp and longjump, a method for avoiding
+ * the normal function call return sequence. (Bleah!)
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The buffer used by setjmp to store the information used by longjmp
+ * to perform it's evil goto-like work. The size of this buffer was
+ * determined through experimentation; it's contents are a mystery.
+ * NOTE: This was determined on an i386 (actually a Pentium). The
+ *       contents could be different on an Alpha or something else.
+ */
+#define _JBLEN 16
+#define _JBTYPE int
+typedef _JBTYPE jmp_buf[_JBLEN];
+
+/*
+ * The function provided by CRTDLL which appears to do the actual work
+ * of setjmp.
+ */
+int	_setjmp (jmp_buf);
+
+#define	setjmp(x)	_setjmp(x)
+
+/*
+ * Return to the last setjmp call and act as if setjmp had returned
+ * nVal (which had better be non-zero!).
+ */
+void	longjmp (jmp_buf, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _SETJMP_H_ */
+
diff --git a/tinyc/win32/include/share.h b/tinyc/win32/include/share.h
new file mode 100755
index 000000000..dd5bd452a
--- /dev/null
+++ b/tinyc/win32/include/share.h
@@ -0,0 +1,44 @@
+/*
+ * share.h
+ *
+ * Constants for file sharing functions.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_SHARE_H_
+#define	_SHARE_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define SH_COMPAT	0x00	/* Compatibility */
+#define	SH_DENYRW	0x10	/* Deny read/write */
+#define	SH_DENYWR	0x20	/* Deny write */
+#define	SH_DENYRD	0x30	/* Deny read */
+#define	SH_DENYNO	0x40	/* Deny nothing */
+
+#endif	/* Not _SHARE_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/signal.h b/tinyc/win32/include/signal.h
new file mode 100755
index 000000000..4eced969a
--- /dev/null
+++ b/tinyc/win32/include/signal.h
@@ -0,0 +1,111 @@
+/* 
+ * signal.h
+ *
+ * A way to set handlers for exceptional conditions (also known as signals).
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_SIGNAL_H_
+#define	_SIGNAL_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * The actual signal values. Using other values with signal
+ * produces a SIG_ERR return value.
+ *
+ * NOTE: SIGINT is produced when the user presses Ctrl-C.
+ *       SIGILL has not been tested.
+ *       SIGFPE doesn't seem to work?
+ *       SIGSEGV does not catch writing to a NULL pointer (that shuts down
+ *               your app; can you say "segmentation violation core dump"?).
+ *       SIGTERM comes from what kind of termination request exactly?
+ *       SIGBREAK is indeed produced by pressing Ctrl-Break.
+ *       SIGABRT is produced by calling abort.
+ * TODO: The above results may be related to not installing an appropriate
+ *       structured exception handling frame. Results may be better if I ever
+ *       manage to get the SEH stuff down.
+ */
+#define	SIGINT		2	/* Interactive attention */
+#define	SIGILL		4	/* Illegal instruction */
+#define	SIGFPE		8	/* Floating point error */
+#define	SIGSEGV		11	/* Segmentation violation */
+#define	SIGTERM		15	/* Termination request */
+#define SIGBREAK	21	/* Control-break */
+#define	SIGABRT		22	/* Abnormal termination (abort) */
+
+#define NSIG 23     /* maximum signal number + 1 */
+
+#ifndef	RC_INVOKED
+
+#ifndef _SIG_ATOMIC_T_DEFINED
+typedef int sig_atomic_t;
+#define _SIG_ATOMIC_T_DEFINED
+#endif
+
+/*
+ * The prototypes (below) are the easy part. The hard part is figuring
+ * out what signals are available and what numbers they are assigned
+ * along with appropriate values of SIG_DFL and SIG_IGN.
+ */
+
+/*
+ * A pointer to a signal handler function. A signal handler takes a
+ * single int, which is the signal it handles.
+ */
+typedef	void (*__p_sig_fn_t)(int);
+
+/*
+ * These are special values of signal handler pointers which are
+ * used to send a signal to the default handler (SIG_DFL), ignore
+ * the signal (SIG_IGN), or indicate an error return (SIG_ERR).
+ */
+#define	SIG_DFL	((__p_sig_fn_t) 0)
+#define	SIG_IGN	((__p_sig_fn_t) 1)
+#define	SIG_ERR ((__p_sig_fn_t) -1)
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * Call signal to set the signal handler for signal sig to the
+ * function pointed to by handler. Returns a pointer to the
+ * previous handler, or SIG_ERR if an error occurs. Initially
+ * unhandled signals defined above will return SIG_DFL.
+ */
+__p_sig_fn_t	signal(int, __p_sig_fn_t);
+
+/*
+ * Raise the signal indicated by sig. Returns non-zero on success.
+ */
+int	raise (int);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _SIGNAL_H_ */
+
diff --git a/tinyc/win32/include/stdarg.h b/tinyc/win32/include/stdarg.h
new file mode 100755
index 000000000..a9b22b7b6
--- /dev/null
+++ b/tinyc/win32/include/stdarg.h
@@ -0,0 +1,16 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+typedef char *va_list;
+
+/* only correct for i386 */
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+
+/* fix a buggy dependency on GCC in libio.h */
+typedef va_list __gnuc_va_list;
+#define _VA_LIST_DEFINED
+
+#endif
diff --git a/tinyc/win32/include/stdbool.h b/tinyc/win32/include/stdbool.h
new file mode 100755
index 000000000..6ed13a611
--- /dev/null
+++ b/tinyc/win32/include/stdbool.h
@@ -0,0 +1,10 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+/* ISOC99 boolean */
+
+#define bool	_Bool
+#define true	1
+#define false	0
+
+#endif /* _STDBOOL_H */
diff --git a/tinyc/win32/include/stddef.h b/tinyc/win32/include/stddef.h
new file mode 100755
index 000000000..6e4e2c88e
--- /dev/null
+++ b/tinyc/win32/include/stddef.h
@@ -0,0 +1,23 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#define NULL ((void *)0)
+typedef __SIZE_TYPE__ size_t;
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+
+/* need to do that because of glibc 2.1 bug (should have a way to test
+   presence of 'long long' without __GNUC__, or TCC should define
+   __GNUC__ ? */
+#if !defined(__int8_t_defined) && !defined(__dietlibc__)
+#define __int8_t_defined
+typedef char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+#endif
+
+void *alloca(size_t);
+
+#endif
diff --git a/tinyc/win32/include/stdint.h b/tinyc/win32/include/stdint.h
new file mode 100755
index 000000000..71c6708ff
--- /dev/null
+++ b/tinyc/win32/include/stdint.h
@@ -0,0 +1,184 @@
+/* ISO C9x  7.18  Integer types <stdint.h>
+ * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *  Date: 2000-12-02
+ */
+
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+/* 7.18.1.1  Exact-width integer types */
+typedef signed char int8_t;
+typedef unsigned char   uint8_t;
+typedef short  int16_t;
+typedef unsigned short  uint16_t;
+typedef int  int32_t;
+typedef unsigned   uint32_t;
+typedef long long  int64_t;
+typedef unsigned long long   uint64_t;
+
+/* 7.18.1.2  Minimum-width integer types */
+typedef signed char int_least8_t;
+typedef unsigned char   uint_least8_t;
+typedef short  int_least16_t;
+typedef unsigned short  uint_least16_t;
+typedef int  int_least32_t;
+typedef unsigned   uint_least32_t;
+typedef long long  int_least64_t;
+typedef unsigned long long   uint_least64_t;
+
+/*  7.18.1.3  Fastest minimum-width integer types 
+ *  Not actually guaranteed to be fastest for all purposes
+ *  Here we use the exact-width types for 8 and 16-bit ints. 
+ */
+typedef char int_fast8_t;
+typedef unsigned char uint_fast8_t;
+typedef short  int_fast16_t;
+typedef unsigned short  uint_fast16_t;
+typedef int  int_fast32_t;
+typedef unsigned  int  uint_fast32_t;
+typedef long long  int_fast64_t;
+typedef unsigned long long   uint_fast64_t;
+
+/* 7.18.1.4  Integer types capable of holding object pointers */
+typedef int intptr_t;
+typedef unsigned uintptr_t;
+
+/* 7.18.1.5  Greatest-width integer types */
+typedef long long  intmax_t;
+typedef unsigned long long   uintmax_t;
+
+/* 7.18.2  Limits of specified-width integer types */
+#if !defined ( __cplusplus) || defined (__STDC_LIMIT_MACROS)
+
+/* 7.18.2.1  Limits of exact-width integer types */
+#define INT8_MIN (-128) 
+#define INT16_MIN (-32768)
+#define INT32_MIN (-2147483647 - 1)
+#define INT64_MIN  (-9223372036854775807LL - 1)
+
+#define INT8_MAX 127
+#define INT16_MAX 32767
+#define INT32_MAX 2147483647
+#define INT64_MAX 9223372036854775807LL
+
+#define UINT8_MAX 0xff /* 255U */
+#define UINT16_MAX 0xffff /* 65535U */
+#define UINT32_MAX 0xffffffff  /* 4294967295U */
+#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
+
+/* 7.18.2.2  Limits of minimum-width integer types */
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+/* 7.18.2.3  Limits of fastest minimum-width integer types */
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST64_MIN INT64_MIN
+
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MAX INT64_MAX
+
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+/* 7.18.2.4  Limits of integer types capable of holding
+    object pointers */ 
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+
+/* 7.18.2.5  Limits of greatest-width integer types */
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+/* 7.18.3  Limits of other integer types */
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+
+#define SIG_ATOMIC_MIN INT32_MIN
+#define SIG_ATOMIC_MAX INT32_MAX
+
+#define SIZE_MAX UINT32_MAX
+
+#ifndef WCHAR_MIN  /* also in wchar.h */ 
+#define WCHAR_MIN 0
+#define WCHAR_MAX ((wchar_t)-1) /* UINT16_MAX */
+#endif
+
+/*
+ * wint_t is unsigned int in __MINGW32__,
+ * but unsigned short in MS runtime
+ */
+#define WINT_MIN 0
+#define WINT_MAX UINT32_MAX
+
+#endif /* !defined ( __cplusplus) || defined __STDC_LIMIT_MACROS */
+
+
+/* 7.18.4  Macros for integer constants */
+#if !defined ( __cplusplus) || defined (__STDC_CONSTANT_MACROS)
+
+/* 7.18.4.1  Macros for minimum-width integer constants
+
+    Accoding to Douglas Gwyn <gwyn@arl.mil>:
+	"This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
+	9899:1999 as initially published, the expansion was required
+	to be an integer constant of precisely matching type, which
+	is impossible to accomplish for the shorter types on most
+	platforms, because C99 provides no standard way to designate
+	an integer constant with width less than that of type int.
+	TC1 changed this to require just an integer constant
+	*expression* with *promoted* type."
+
+	The trick used here is from Clive D W Feather.
+*/
+
+#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
+#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
+#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
+#define INT64_C(val) (INT_LEAST64_MAX-INT_LEAST64_MAX+(val))
+
+#define UINT8_C(val) (UINT_LEAST8_MAX-UINT_LEAST8_MAX+(val))
+#define UINT16_C(val) (UINT_LEAST16_MAX-UINT_LEAST16_MAX+(val))
+#define UINT32_C(val) (UINT_LEAST32_MAX-UINT_LEAST32_MAX+(val))
+#define UINT64_C(val) (UINT_LEAST64_MAX-UINT_LEAST64_MAX+(val))
+
+/* 7.18.4.2  Macros for greatest-width integer constants */
+#define INTMAX_C(val) (INTMAX_MAX-INTMAX_MAX+(val))
+#define UINTMAX_C(val) (UINTMAX_MAX-UINTMAX_MAX+(val))
+
+#endif  /* !defined ( __cplusplus) || defined __STDC_CONSTANT_MACROS */
+
+#endif
diff --git a/tinyc/win32/include/stdio.h b/tinyc/win32/include/stdio.h
new file mode 100755
index 000000000..2d97e668c
--- /dev/null
+++ b/tinyc/win32/include/stdio.h
@@ -0,0 +1,413 @@
+/*
+ * stdio.h
+ *
+ * Definitions of types and prototypes of functions for standard input and
+ * output.
+ *
+ * NOTE: The file manipulation functions provided by Microsoft seem to
+ * work with either slash (/) or backslash (\) as the path separator.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _STDIO_H_
+#define	_STDIO_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_size_t
+#define __need_NULL
+#define __need_wchar_t
+#define	__need_wint_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+
+/* Flags for the iobuf structure  */
+#define	_IOREAD	1
+#define	_IOWRT	2
+#define	_IORW	0x0080 /* opened as "r+w" */
+
+
+/*
+ * The three standard file pointers provided by the run time library.
+ * NOTE: These will go to the bit-bucket silently in GUI applications!
+ */
+#define	STDIN_FILENO	0
+#define	STDOUT_FILENO	1
+#define	STDERR_FILENO	2
+
+/* Returned by various functions on end of file condition or error. */
+#define	EOF	(-1)
+
+/*
+ * The maximum length of a file name. You should use GetVolumeInformation
+ * instead of this constant. But hey, this works.
+ *
+ * NOTE: This is used in the structure _finddata_t (see io.h) so changing it
+ *       is probably not a good idea.
+ */
+#define	FILENAME_MAX	(260)
+
+/*
+ * The maximum number of files that may be open at once. I have set this to
+ * a conservative number. The actual value may be higher.
+ */
+#define FOPEN_MAX	(20)
+
+/* After creating this many names, tmpnam and tmpfile return NULL */
+#define TMP_MAX	32767
+/*
+ * Tmpnam, tmpfile and, sometimes, _tempnam try to create
+ * temp files in the root directory of the current drive
+ * (not in pwd, as suggested by some older MS doc's).
+ * Redefining these macros does not effect the CRT functions.
+ */
+#define _P_tmpdir   "\\"
+#define _wP_tmpdir  L"\\"
+
+/*
+ * The maximum size of name (including NUL) that will be put in the user
+ * supplied buffer caName for tmpnam.
+ * Inferred from the size of the static buffer returned by tmpnam
+ * when passed a NULL argument. May actually be smaller.
+ */
+#define L_tmpnam (16)
+
+#define _IOFBF		0x0000
+#define _IOLBF		0x0040
+#define _IONBF		0x0004
+
+/*
+ * The buffer size as used by setbuf such that it is equivalent to
+ * (void) setvbuf(fileSetBuffer, caBuffer, _IOFBF, BUFSIZ).
+ */
+#define	BUFSIZ	512
+
+/* Constants for nOrigin indicating the position relative to which fseek
+ * sets the file position. Enclosed in ifdefs because io.h could also
+ * define them. (Though not anymore since io.h includes this file now.) */
+#ifndef	SEEK_SET
+#define SEEK_SET	(0)
+#endif
+
+#ifndef	SEEK_CUR
+#define	SEEK_CUR	(1)
+#endif
+
+#ifndef	SEEK_END
+#define SEEK_END	(2)
+#endif
+
+
+#ifndef	RC_INVOKED
+
+/*
+ * I used to include stdarg.h at this point, in order to allow for the
+ * functions later on in the file which use va_list. That conflicts with
+ * using stdio.h and varargs.h in the same file, so I do the typedef myself.
+ */
+#ifndef	_VA_LIST
+#define _VA_LIST
+#if defined __GNUC__ && __GNUC__ >= 3
+typedef __builtin_va_list va_list;
+#else
+typedef char* va_list;
+#endif
+#endif
+/*
+ * The structure underlying the FILE type.
+ *
+ * I still believe that nobody in their right mind should make use of the
+ * internals of this structure. Provided by Pedro A. Aranda Gutiirrez
+ * <paag@tid.es>.
+ */
+#ifndef _FILE_DEFINED
+#define	_FILE_DEFINED
+typedef struct _iobuf
+{
+	char*	_ptr;
+	int	_cnt;
+	char*	_base;
+	int	_flag;
+	int	_file;
+	int	_charbuf;
+	int	_bufsiz;
+	char*	_tmpfname;
+} FILE;
+#endif	/* Not _FILE_DEFINED */
+
+
+/*
+ * The standard file handles
+ */
+#ifndef __DECLSPEC_SUPPORTED
+
+extern FILE (*__imp__iob)[];	/* A pointer to an array of FILE */
+
+#define _iob	(*__imp__iob)	/* An array of FILE */
+
+#else /* __DECLSPEC_SUPPORTED */
+
+__MINGW_IMPORT FILE _iob[];	/* An array of FILE imported from DLL. */
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+#define stdin	(&_iob[STDIN_FILENO])
+#define stdout	(&_iob[STDOUT_FILENO])
+#define stderr	(&_iob[STDERR_FILENO])
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * File Operations
+ */
+FILE*	fopen (const char*, const char*);
+FILE*	freopen (const char*, const char*, FILE*);
+int	fflush (FILE*);
+int	fclose (FILE*);
+/* MS puts remove & rename (but not wide versions) in io.h  also */
+int	remove (const char*);
+int	rename (const char*, const char*);
+FILE*	tmpfile (void);
+char*	tmpnam (char*);
+char*	_tempnam (const char*, const char*);
+
+#ifndef	NO_OLDNAMES
+char*	tempnam (const char*, const char*);
+#endif
+
+int	setvbuf (FILE*, char*, int, size_t);
+
+void	setbuf (FILE*, char*);
+
+/*
+ * Formatted Output
+ */
+
+int	fprintf (FILE*, const char*, ...);
+int	printf (const char*, ...);
+int	sprintf (char*, const char*, ...);
+int	_snprintf (char*, size_t, const char*, ...);
+int	vfprintf (FILE*, const char*, va_list);
+int	vprintf (const char*, va_list);
+int	vsprintf (char*, const char*, va_list);
+int	_vsnprintf (char*, size_t, const char*, va_list);
+
+#ifndef __NO_ISOCEXT  /* externs in libmingwex.a */
+int snprintf(char* s, size_t n, const char*  format, ...);
+extern inline int vsnprintf (char* s, size_t n, const char* format,
+			   va_list arg)
+  { return _vsnprintf ( s, n, format, arg); }
+#endif
+
+/*
+ * Formatted Input
+ */
+
+int	fscanf (FILE*, const char*, ...);
+int	scanf (const char*, ...);
+int	sscanf (const char*, const char*, ...);
+/*
+ * Character Input and Output Functions
+ */
+
+int	fgetc (FILE*);
+char*	fgets (char*, int, FILE*);
+int	fputc (int, FILE*);
+int	fputs (const char*, FILE*);
+int	getc (FILE*);
+int	getchar (void);
+char*	gets (char*);
+int	putc (int, FILE*);
+int	putchar (int);
+int	puts (const char*);
+int	ungetc (int, FILE*);
+
+/*
+ * Direct Input and Output Functions
+ */
+
+size_t	fread (void*, size_t, size_t, FILE*);
+size_t	fwrite (const void*, size_t, size_t, FILE*);
+
+/*
+ * File Positioning Functions
+ */
+
+int	fseek (FILE*, long, int);
+long	ftell (FILE*);
+void	rewind (FILE*);
+
+#ifdef __USE_MINGW_FSEEK  /* These are in libmingwex.a */
+/*
+ * Workaround for limitations on win9x where a file contents are
+ * not zero'd out if you seek past the end and then write.
+ */
+
+int __mingw_fseek (FILE *, long, int);
+int __mingw_fwrite (const void*, size_t, size_t, FILE*);
+#define fseek(fp, offset, whence)  __mingw_fseek(fp, offset, whence)
+#define fwrite(buffer, size, count, fp)  __mingw_fwrite(buffer, size, count, fp)
+#endif /* __USE_MINGW_FSEEK */
+
+
+/*
+ * An opaque data type used for storing file positions... The contents of
+ * this type are unknown, but we (the compiler) need to know the size
+ * because the programmer using fgetpos and fsetpos will be setting aside
+ * storage for fpos_t structres. Actually I tested using a byte array and
+ * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL).
+ * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in
+ * MSVCRT however, and for now `long long' will do.
+ */
+#ifdef __MSVCRT__
+typedef long long fpos_t;
+#else
+typedef long	fpos_t;
+#endif
+
+int	fgetpos	(FILE*, fpos_t*);
+int	fsetpos (FILE*, const fpos_t*);
+
+/*
+ * Error Functions
+ */
+
+void	clearerr (FILE*);
+int	feof (FILE*);
+int	ferror (FILE*);
+void	perror (const char*);
+
+
+#ifndef __STRICT_ANSI__
+/*
+ * Pipes
+ */
+FILE*	_popen (const char*, const char*);
+int	_pclose (FILE*);
+
+#ifndef NO_OLDNAMES
+FILE*	popen (const char*, const char*);
+int	pclose (FILE*);
+#endif
+
+/*
+ * Other Non ANSI functions
+ */
+int	_flushall (void);
+int	_fgetchar (void);
+int	_fputchar (int);
+FILE*	_fdopen (int, const char*);
+int	_fileno (FILE*);
+
+#ifndef _NO_OLDNAMES
+int	fgetchar (void);
+int	fputchar (int);
+FILE*	fdopen (int, const char*);
+int	fileno (FILE*);
+#endif	/* Not _NO_OLDNAMES */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+/* Wide  versions */
+
+#ifndef _WSTDIO_DEFINED
+/*  also in wchar.h - keep in sync */
+int	fwprintf (FILE*, const wchar_t*, ...);
+int	wprintf (const wchar_t*, ...);
+int	swprintf (wchar_t*, const wchar_t*, ...);
+int	_snwprintf (wchar_t*, size_t, const wchar_t*, ...);
+int	vfwprintf (FILE*, const wchar_t*, va_list);
+int	vwprintf (const wchar_t*, va_list);
+int	vswprintf (wchar_t*, const wchar_t*, va_list);
+int	_vsnwprintf (wchar_t*, size_t, const wchar_t*, va_list);
+int	fwscanf (FILE*, const wchar_t*, ...);
+int	wscanf (const wchar_t*, ...);
+int	swscanf (const wchar_t*, const wchar_t*, ...);
+wint_t	fgetwc (FILE*);
+wint_t	fputwc (wchar_t, FILE*);
+wint_t	ungetwc (wchar_t, FILE*);
+#ifdef __MSVCRT__ 
+wchar_t* fgetws (wchar_t*, int, FILE*);
+int	fputws (const wchar_t*, FILE*);
+wint_t	getwc (FILE*);
+wint_t	getwchar (void);
+wchar_t* _getws (wchar_t*);
+wint_t	putwc (wint_t, FILE*);
+int	_putws (const wchar_t*);
+wint_t	putwchar (wint_t);
+FILE*	_wfopen (const wchar_t*, const wchar_t*);
+FILE*	_wfreopen (const wchar_t*, const wchar_t*, FILE*);
+FILE*	_wfsopen (const wchar_t*, const wchar_t*, int);
+wchar_t* _wtmpnam (wchar_t*);
+wchar_t* _wtempnam (const wchar_t*, const wchar_t*);
+int	_wrename (const wchar_t*, const wchar_t*);
+int	_wremove (const wchar_t*);
+void	_wperror (const wchar_t*);
+FILE*	_wpopen (const wchar_t*, const wchar_t*);
+#endif	/* __MSVCRT__ */
+
+#ifndef __NO_ISOCEXT  /* externs in libmingwex.a */
+int snwprintf(wchar_t* s, size_t n, const wchar_t*  format, ...);
+extern inline int vsnwprintf (wchar_t* s, size_t n, const wchar_t* format,
+			   va_list arg)
+  { return _vsnwprintf ( s, n, format, arg); }
+#endif
+
+#define _WSTDIO_DEFINED
+#endif /* _WSTDIO_DEFINED */
+
+#ifndef __STRICT_ANSI__
+#ifdef __MSVCRT__
+#ifndef NO_OLDNAMES
+FILE*	wpopen (const wchar_t*, const wchar_t*);
+#endif /* not NO_OLDNAMES */
+#endif /* MSVCRT runtime */
+
+/*
+ * Other Non ANSI wide functions
+ */
+wint_t	_fgetwchar (void);
+wint_t	_fputwchar (wint_t);
+int	_getw (FILE*);
+int	_putw (int, FILE*);
+
+#ifndef _NO_OLDNAMES
+wint_t	fgetwchar (void);
+wint_t	fputwchar (wint_t);
+int	getw (FILE*);
+int	putw (int, FILE*);
+#endif	/* Not _NO_OLDNAMES */
+
+#endif /* __STRICT_ANSI */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif /* _STDIO_H_ */
diff --git a/tinyc/win32/include/stdlib.h b/tinyc/win32/include/stdlib.h
new file mode 100755
index 000000000..37fae4879
--- /dev/null
+++ b/tinyc/win32/include/stdlib.h
@@ -0,0 +1,482 @@
+/*
+ * stdlib.h
+ *
+ * Definitions for common types, variables, and functions.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+
+#define __need_size_t
+#define __need_wchar_t
+#define __need_NULL
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif /* RC_INVOKED */
+
+/*
+ * RAND_MAX is the maximum value that may be returned by rand.
+ * The minimum is zero.
+ */
+#define	RAND_MAX	0x7FFF
+
+/*
+ * These values may be used as exit status codes.
+ */
+#define	EXIT_SUCCESS	0
+#define	EXIT_FAILURE	1
+
+/*
+ * Definitions for path name functions.
+ * NOTE: All of these values have simply been chosen to be conservatively high.
+ *       Remember that with long file names we can no longer depend on
+ *       extensions being short.
+ */
+#ifndef __STRICT_ANSI__
+
+#ifndef MAX_PATH
+#define	MAX_PATH	(260)
+#endif
+
+#define	_MAX_PATH	MAX_PATH
+#define	_MAX_DRIVE	(3)
+#define	_MAX_DIR	256
+#define	_MAX_FNAME	256
+#define	_MAX_EXT	256
+
+#endif	/* Not __STRICT_ANSI__ */
+
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This seems like a convenient place to declare these variables, which
+ * give programs using WinMain (or main for that matter) access to main-ish
+ * argc and argv. environ is a pointer to a table of environment variables.
+ * NOTE: Strings in _argv and environ are ANSI strings.
+ */
+extern int	_argc;
+extern char**	_argv;
+
+/* imports from runtime dll of the above variables */
+#ifdef __MSVCRT__
+
+extern int*     __p___argc(void);
+extern char***   __p___argv(void);
+extern wchar_t***   __p___wargv(void);
+
+#define __argc (*__p___argc())
+#define __argv (*__p___argv())
+#define __wargv (*__p___wargv())
+
+#else /* !MSVCRT */
+
+#ifndef __DECLSPEC_SUPPORTED
+
+extern int*    __imp___argc_dll;
+extern char***  __imp___argv_dll;
+#define __argc (*__imp___argc_dll)
+#define __argv (*__imp___argv_dll)
+
+#else /* __DECLSPEC_SUPPORTED */
+
+__MINGW_IMPORT int    __argc_dll;
+__MINGW_IMPORT char**  __argv_dll;
+#define __argc __argc_dll
+#define __argv __argv_dll
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+#endif /* __MSVCRT */
+
+/*
+ * Also defined in ctype.h.
+ */
+
+#ifndef MB_CUR_MAX
+# ifdef __MSVCRT__
+#  define MB_CUR_MAX __mb_cur_max
+   __MINGW_IMPORT int __mb_cur_max;
+# else /* not __MSVCRT */
+#  define MB_CUR_MAX __mb_cur_max_dll
+   __MINGW_IMPORT int __mb_cur_max_dll;
+# endif /* not __MSVCRT */
+#endif  /* MB_CUR_MAX */
+
+/* 
+ * MS likes to declare errno in stdlib.h as well. 
+ */
+
+#ifdef _UWIN
+#undef errno
+extern int errno;
+#else
+int*	_errno(void);
+#define	errno		(*_errno())
+#endif
+int*	__doserrno(void);
+#define	_doserrno	(*__doserrno())
+
+/*
+ * Use environ from the DLL, not as a global. 
+ */
+
+#ifdef __MSVCRT__
+  extern char *** __p__environ(void);
+  extern wchar_t *** __p__wenviron(void);
+# define _environ (*__p__environ())
+# define _wenviron (*__p__wenviron())
+#else /* ! __MSVCRT__ */
+# ifndef __DECLSPEC_SUPPORTED
+    extern char *** __imp__environ_dll;
+#   define _environ (*__imp__environ_dll)
+# else /* __DECLSPEC_SUPPORTED */
+    __MINGW_IMPORT char ** _environ_dll;
+#   define _environ _environ_dll
+# endif /* __DECLSPEC_SUPPORTED */
+#endif /* ! __MSVCRT__ */
+
+#define environ _environ
+
+#ifdef	__MSVCRT__
+/* One of the MSVCRTxx libraries */
+
+#ifndef __DECLSPEC_SUPPORTED
+  extern int*	__imp__sys_nerr;
+# define	sys_nerr	(*__imp__sys_nerr)
+#else /* __DECLSPEC_SUPPORTED */
+  __MINGW_IMPORT int	_sys_nerr;
+# ifndef _UWIN
+#   define	sys_nerr	_sys_nerr
+# endif /* _UWIN */
+#endif /* __DECLSPEC_SUPPORTED */
+
+#else /* ! __MSVCRT__ */
+
+/* CRTDLL run time library */
+
+#ifndef __DECLSPEC_SUPPORTED
+  extern int*	__imp__sys_nerr_dll;
+# define sys_nerr	(*__imp__sys_nerr_dll)
+#else /* __DECLSPEC_SUPPORTED */
+  __MINGW_IMPORT int	_sys_nerr_dll;
+# define sys_nerr	_sys_nerr_dll
+#endif /* __DECLSPEC_SUPPORTED */
+
+#endif /* ! __MSVCRT__ */
+
+#ifndef __DECLSPEC_SUPPORTED
+extern char***	__imp__sys_errlist;
+#define	sys_errlist	(*__imp__sys_errlist)
+#else /* __DECLSPEC_SUPPORTED */
+__MINGW_IMPORT char*	_sys_errlist[];
+#ifndef _UWIN
+#define	sys_errlist	_sys_errlist
+#endif /* _UWIN */
+#endif /* __DECLSPEC_SUPPORTED */
+
+/*
+ * OS version and such constants.
+ */
+#ifndef __STRICT_ANSI__
+
+#ifdef	__MSVCRT__
+/* msvcrtxx.dll */
+
+extern unsigned int*	__p__osver(void);
+extern unsigned int*	__p__winver(void);
+extern unsigned int*	__p__winmajor(void);
+extern unsigned int*	__p__winminor(void);
+
+#define _osver		(*__p__osver())
+#define _winver		(*__p__winver())
+#define _winmajor	(*__p__winmajor())
+#define _winminor	(*__p__winminor())
+
+#else
+/* Not msvcrtxx.dll, thus crtdll.dll */
+
+#ifndef __DECLSPEC_SUPPORTED
+
+extern unsigned int*	_imp___osver_dll;
+extern unsigned int*	_imp___winver_dll;
+extern unsigned int*	_imp___winmajor_dll;
+extern unsigned int*	_imp___winminor_dll;
+
+#define _osver		(*_imp___osver_dll)
+#define _winver		(*_imp___winver_dll)
+#define _winmajor	(*_imp___winmajor_dll)
+#define _winminor	(*_imp___winminor_dll)
+
+#else /* __DECLSPEC_SUPPORTED */
+
+__MINGW_IMPORT unsigned int	_osver_dll;
+__MINGW_IMPORT unsigned int	_winver_dll;
+__MINGW_IMPORT unsigned int	_winmajor_dll;
+__MINGW_IMPORT unsigned int	_winminor_dll;
+
+#define _osver		_osver_dll
+#define _winver		_winver_dll
+#define _winmajor	_winmajor_dll
+#define _winminor	_winminor_dll
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+#endif
+
+#if defined  __MSVCRT__
+/* although the _pgmptr is exported as DATA,
+ * be safe and use the access function __p__pgmptr() to get it. */
+char**  __p__pgmptr(void);
+#define _pgmptr     (*__p__pgmptr())
+wchar_t**  __p__wpgmptr(void);
+#define _wpgmptr    (*__p__wpgmptr())
+#else /* ! __MSVCRT__ */
+# ifndef __DECLSPEC_SUPPORTED
+  extern char** __imp__pgmptr_dll;
+# define _pgmptr (*__imp__pgmptr_dll)
+# else /* __DECLSPEC_SUPPORTED */
+ __MINGW_IMPORT char* _pgmptr_dll;
+# define _pgmptr _pgmptr_dll
+# endif /* __DECLSPEC_SUPPORTED */
+/* no wide version in CRTDLL */
+#endif /* __MSVCRT__ */
+
+#endif /* Not __STRICT_ANSI__ */
+
+#ifdef	__GNUC__
+#define	_ATTRIB_NORETURN	__attribute__ ((noreturn))
+#else	/* Not __GNUC__ */
+#define	_ATTRIB_NORETURN
+#endif	/* __GNUC__ */
+
+double	atof	(const char*);
+int	atoi	(const char*);
+long	atol	(const char*);
+int	_wtoi (const wchar_t *);
+long _wtol (const wchar_t *);
+
+double	strtod	(const char*, char**);
+#if !defined __NO_ISOCEXT  /* extern stubs in static libmingwex.a */
+extern __inline__ float strtof (const char *nptr, char **endptr)
+  { return (strtod (nptr, endptr));}
+#endif /* __NO_ISOCEXT */
+
+long	strtol	(const char*, char**, int);
+unsigned long	strtoul	(const char*, char**, int);
+
+#ifndef _WSTDLIB_DEFINED
+/*  also declared in wchar.h */
+double	wcstod	(const wchar_t*, wchar_t**);
+#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
+extern __inline__ float wcstof( const wchar_t *nptr, wchar_t **endptr)
+{  return (wcstod(nptr, endptr)); }
+#endif /* __NO_ISOCEXT */
+
+long	wcstol	(const wchar_t*, wchar_t**, int);
+unsigned long	wcstoul (const wchar_t*, wchar_t**, int);
+#define _WSTDLIB_DEFINED
+#endif
+
+size_t	wcstombs	(char*, const wchar_t*, size_t);
+int	wctomb		(char*, wchar_t);
+
+int	mblen		(const char*, size_t);
+size_t	mbstowcs	(wchar_t*, const char*, size_t);
+int	mbtowc		(wchar_t*, const char*, size_t);
+
+int	rand	(void);
+void	srand	(unsigned int);
+
+void*	calloc	(size_t, size_t);
+void*	malloc	(size_t);
+void*	realloc	(void*, size_t);
+void	free	(void*);
+
+void	abort	(void) _ATTRIB_NORETURN;
+void	exit	(int) _ATTRIB_NORETURN;
+int	atexit	(void (*)(void));
+
+int	system	(const char*);
+char*	getenv	(const char*);
+
+void*	bsearch	(const void*, const void*, size_t, size_t, 
+                 int (*)(const void*, const void*));
+void	qsort	(const void*, size_t, size_t,
+                 int (*)(const void*, const void*));
+
+int	abs	(int);
+long	labs	(long);
+
+/*
+ * div_t and ldiv_t are structures used to return the results of div and
+ * ldiv.
+ *
+ * NOTE: div and ldiv appear not to work correctly unless
+ *       -fno-pcc-struct-return is specified. This is included in the
+ *       mingw32 specs file.
+ */
+typedef struct { int quot, rem; } div_t;
+typedef struct { long quot, rem; } ldiv_t;
+
+div_t	div	(int, int);
+ldiv_t	ldiv	(long, long);
+
+#ifndef	__STRICT_ANSI__
+
+/*
+ * NOTE: Officially the three following functions are obsolete. The Win32 API
+ *       functions SetErrorMode, Beep and Sleep are their replacements.
+ */
+void	_beep (unsigned int, unsigned int);
+void	_seterrormode (int);
+void	_sleep (unsigned long);
+
+void	_exit	(int) _ATTRIB_NORETURN;
+#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
+/* C99 function name */
+void _Exit(int) _ATTRIB_NORETURN; /* Declare to get noreturn attribute.  */
+extern __inline__ void _Exit(int status)
+	{  _exit(status); }
+#endif
+/* _onexit is MS extension. Use atexit for portability.  */
+typedef  int (* _onexit_t)(void); 
+_onexit_t _onexit( _onexit_t );
+
+int	_putenv	(const char*);
+void	_searchenv (const char*, const char*, char*);
+
+
+char*	_ecvt (double, int, int*, int*);
+char*	_fcvt (double, int, int*, int*);
+char*	_gcvt (double, int, char*);
+
+void	_makepath (char*, const char*, const char*, const char*, const char*);
+void	_splitpath (const char*, char*, char*, char*, char*);
+char*	_fullpath (char*, const char*, size_t);
+
+
+char*	_itoa (int, char*, int);
+char*	_ltoa (long, char*, int);
+char*   _ultoa(unsigned long, char*, int);
+wchar_t*  _itow (int, wchar_t*, int);
+wchar_t*  _ltow (long, wchar_t*, int);
+wchar_t*  _ultow (unsigned long, wchar_t*, int);
+
+#ifdef __MSVCRT__
+__int64	_atoi64(const char *);
+char*	_i64toa(__int64, char *, int);
+char*	_ui64toa(unsigned __int64, char *, int);
+__int64	_wtoi64(const wchar_t *);
+wchar_t* _i64tow(__int64, wchar_t *, int);
+wchar_t* _ui64tow(unsigned __int64, wchar_t *, int);
+
+wchar_t* _wgetenv(const wchar_t*);
+int	 _wputenv(const wchar_t*);
+void	_wsearchenv(const wchar_t*, const wchar_t*, wchar_t*);
+void    _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*);
+void	_wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*);
+wchar_t*    _wfullpath (wchar_t*, const wchar_t*, size_t);
+#endif
+
+#ifndef	_NO_OLDNAMES
+
+int	putenv (const char*);
+void	searchenv (const char*, const char*, char*);
+
+char*	itoa (int, char*, int);
+char*	ltoa (long, char*, int);
+
+#ifndef _UWIN
+char*	ecvt (double, int, int*, int*);
+char*	fcvt (double, int, int*, int*);
+char*	gcvt (double, int, char*);
+#endif /* _UWIN */
+#endif	/* Not _NO_OLDNAMES */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+/* C99 names */
+
+#if !defined __NO_ISOCEXT /* externs in static libmingwex.a */
+
+typedef struct { long long quot, rem; } lldiv_t;
+
+lldiv_t	lldiv (long long, long long);
+
+extern __inline__ long long llabs(long long _j)
+  {return (_j >= 0 ? _j : -_j);}
+
+long long strtoll (const char* __restrict__, char** __restrict, int);
+unsigned long long strtoull (const char* __restrict__, char** __restrict__, int);
+
+#if defined (__MSVCRT__) /* these are stubs for MS _i64 versions */ 
+long long atoll (const char *);
+
+#if !defined (__STRICT_ANSI__)
+long long wtoll(const wchar_t *);
+char* lltoa(long long, char *, int);
+char* ulltoa(unsigned long long , char *, int);
+wchar_t* lltow(long long, wchar_t *, int);
+wchar_t* ulltow(unsigned long long, wchar_t *, int);
+
+  /* inline using non-ansi functions */
+extern __inline__ long long atoll (const char * _c)
+	{ return _atoi64 (_c); }
+extern __inline__ char* lltoa(long long _n, char * _c, int _i)
+	{ return _i64toa (_n, _c, _i); }
+extern __inline__ char* ulltoa(unsigned long long _n, char * _c, int _i)
+	{ return _ui64toa (_n, _c, _i); }
+extern __inline__ long long wtoll(const wchar_t * _w)
+ 	{ return _wtoi64 (_w); }
+extern __inline__ wchar_t* lltow(long long _n, wchar_t * _w, int _i)
+	{ return _i64tow (_n, _w, _i); } 
+extern __inline__ wchar_t* ulltow(unsigned long long _n, wchar_t * _w, int _i)
+	{ return _ui64tow (_n, _w, _i); } 
+#endif /* (__STRICT_ANSI__)  */
+
+#endif /* __MSVCRT__ */
+
+#endif /* !__NO_ISOCEXT */
+
+/*
+ * Undefine the no return attribute used in some function definitions
+ */
+#undef	_ATTRIB_NORETURN
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _STDLIB_H_ */
+
diff --git a/tinyc/win32/include/string.h b/tinyc/win32/include/string.h
new file mode 100755
index 000000000..03dd48f8c
--- /dev/null
+++ b/tinyc/win32/include/string.h
@@ -0,0 +1,206 @@
+/*
+ * string.h
+ *
+ * Definitions for memory and string functions.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef _STRING_H_
+#define	_STRING_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * Define size_t, wchar_t and NULL
+ */
+#define __need_size_t
+#define __need_wchar_t
+#define	__need_NULL
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Prototypes of the ANSI Standard C library string functions.
+ */
+void*	memchr (const void*, int, size_t);
+int 	memcmp (const void*, const void*, size_t);
+void* 	memcpy (void*, const void*, size_t);
+void*	memmove (void*, const void*, size_t);
+void*	memset (void*, int, size_t);
+char*	strcat (char*, const char*);
+char*	strchr (const char*, int);
+int	strcmp (const char*, const char*);
+int	strcoll (const char*, const char*);	/* Compare using locale */
+char*	strcpy (char*, const char*);
+size_t	strcspn (const char*, const char*);
+char*	strerror (int); /* NOTE: NOT an old name wrapper. */
+char*	_strerror (const char *);
+size_t	strlen (const char*);
+char*	strncat (char*, const char*, size_t);
+int	strncmp (const char*, const char*, size_t);
+char*	strncpy (char*, const char*, size_t);
+char*	strpbrk (const char*, const char*);
+char*	strrchr (const char*, int);
+size_t	strspn (const char*, const char*);
+char*	strstr (const char*, const char*);
+char*	strtok (char*, const char*);
+size_t	strxfrm (char*, const char*, size_t);
+
+#ifndef __STRICT_ANSI__
+/*
+ * Extra non-ANSI functions provided by the CRTDLL library
+ */
+void*	_memccpy (void*, const void*, int, size_t);
+int 	_memicmp (const void*, const void*, size_t);
+char* 	_strdup (const char*);
+int	_strcmpi (const char*, const char*);
+int	_stricmp (const char*, const char*);
+int	_stricoll (const char*, const char*);
+char*	_strlwr (char*);
+int	_strnicmp (const char*, const char*, size_t);
+char*	_strnset (char*, int, size_t);
+char*	_strrev (char*);
+char*	_strset (char*, int);
+char*	_strupr (char*);
+void	_swab (const char*, char*, size_t);
+
+/*
+ * Multi-byte character functions
+ */
+unsigned char*	_mbschr (unsigned char*, unsigned char*);
+unsigned char*	_mbsncat (unsigned char*, const unsigned char*, size_t);
+unsigned char*	_mbstok (unsigned char*, unsigned char*);
+
+#ifdef __MSVCRT__
+int  _strncoll(const char*, const char*, size_t);
+int  _strnicoll(const char*, const char*, size_t);
+#endif
+
+#endif	/* Not __STRICT_ANSI__ */
+
+/*
+ * Unicode versions of the standard calls.
+ */
+wchar_t* wcscat (wchar_t*, const wchar_t*);
+wchar_t* wcschr (const wchar_t*, wchar_t);
+int	wcscmp (const wchar_t*, const wchar_t*);
+int	wcscoll (const wchar_t*, const wchar_t*);
+wchar_t* wcscpy (wchar_t*, const wchar_t*);
+size_t	wcscspn (const wchar_t*, const wchar_t*);
+/* Note: No wcserror in CRTDLL. */
+size_t	wcslen (const wchar_t*);
+wchar_t* wcsncat (wchar_t*, const wchar_t*, size_t);
+int	wcsncmp(const wchar_t*, const wchar_t*, size_t);
+wchar_t* wcsncpy(wchar_t*, const wchar_t*, size_t);
+wchar_t* wcspbrk(const wchar_t*, const wchar_t*);
+wchar_t* wcsrchr(const wchar_t*, wchar_t);
+size_t	wcsspn(const wchar_t*, const wchar_t*);
+wchar_t* wcsstr(const wchar_t*, const wchar_t*);
+wchar_t* wcstok(wchar_t*, const wchar_t*);
+size_t	wcsxfrm(wchar_t*, const wchar_t*, size_t);
+
+#ifndef	__STRICT_ANSI__
+/*
+ * Unicode versions of non-ANSI functions provided by CRTDLL.
+ */
+
+/* NOTE: _wcscmpi not provided by CRTDLL, this define is for portability */
+#define		_wcscmpi	_wcsicmp
+
+wchar_t* _wcsdup (wchar_t*);
+int	_wcsicmp (const wchar_t*, const wchar_t*);
+int	_wcsicoll (const wchar_t*, const wchar_t*);
+wchar_t* _wcslwr (wchar_t*);
+int	_wcsnicmp (const wchar_t*, const wchar_t*, size_t);
+wchar_t* _wcsnset (wchar_t*, wchar_t, size_t);
+wchar_t* _wcsrev (wchar_t*);
+wchar_t* _wcsset (wchar_t*, wchar_t);
+wchar_t* _wcsupr (wchar_t*);
+
+#ifdef __MSVCRT__
+int  _wcsncoll(const wchar_t*, const wchar_t*, size_t);
+int  _wcsnicoll(const wchar_t*, const wchar_t*, size_t);
+#endif
+
+
+#endif	/* Not __STRICT_ANSI__ */
+
+
+#ifndef	__STRICT_ANSI__
+#ifndef	_NO_OLDNAMES
+
+/*
+ * Non-underscored versions of non-ANSI functions. They live in liboldnames.a
+ * and provide a little extra portability. Also a few extra UNIX-isms like
+ * strcasecmp.
+ */
+
+void*	memccpy (void*, const void*, int, size_t);
+int	memicmp (const void*, const void*, size_t);
+char*	strdup (const char*);
+int	strcmpi (const char*, const char*);
+int	stricmp (const char*, const char*);
+int	strcasecmp (const char*, const char*);
+int	stricoll (const char*, const char*);
+char*	strlwr (char*);
+int	strnicmp (const char*, const char*, size_t);
+int	strncasecmp (const char*, const char*, size_t);
+char*	strnset (char*, int, size_t);
+char*	strrev (char*);
+char*	strset (char*, int);
+char*	strupr (char*);
+#ifndef _UWIN
+void	swab (const char*, char*, size_t);
+#endif /* _UWIN */
+
+/* NOTE: There is no _wcscmpi, but this is for compatibility. */
+int	wcscmpi	(const wchar_t*, const wchar_t*);
+wchar_t* wcsdup (wchar_t*);
+int	wcsicmp (const wchar_t*, const wchar_t*);
+int	wcsicoll (const wchar_t*, const wchar_t*);
+wchar_t* wcslwr (wchar_t*);
+int	wcsnicmp (const wchar_t*, const wchar_t*, size_t);
+wchar_t* wcsnset (wchar_t*, wchar_t, size_t);
+wchar_t* wcsrev (wchar_t*);
+wchar_t* wcsset (wchar_t*, wchar_t);
+wchar_t* wcsupr (wchar_t*);
+
+#endif	/* Not _NO_OLDNAMES */
+#endif	/* Not strict ANSI */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _STRING_H_ */
+
diff --git a/tinyc/win32/include/sys/fcntl.h b/tinyc/win32/include/sys/fcntl.h
new file mode 100755
index 000000000..b343f272f
--- /dev/null
+++ b/tinyc/win32/include/sys/fcntl.h
@@ -0,0 +1,8 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * This fcntl.h maps to the root fcntl.h
+ */
+#ifndef __STRICT_ANSI__
+#include <fcntl.h>
+#endif
diff --git a/tinyc/win32/include/sys/file.h b/tinyc/win32/include/sys/file.h
new file mode 100755
index 000000000..96c49e117
--- /dev/null
+++ b/tinyc/win32/include/sys/file.h
@@ -0,0 +1,9 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * This file.h maps to the root fcntl.h
+ * TODO?
+ */
+#ifndef __STRICT_ANSI__
+#include <fcntl.h>
+#endif
diff --git a/tinyc/win32/include/sys/locking.h b/tinyc/win32/include/sys/locking.h
new file mode 100755
index 000000000..2ecd11628
--- /dev/null
+++ b/tinyc/win32/include/sys/locking.h
@@ -0,0 +1,52 @@
+/*
+ * locking.h
+ *
+ * Constants for the mode parameter of the locking function.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_LOCKING_H_
+#define	_LOCKING_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define	_LK_UNLCK	0	/* Unlock */
+#define	_LK_LOCK	1	/* Lock */
+#define	_LK_NBLCK	2	/* Non-blocking lock */
+#define	_LK_RLCK	3	/* Lock for read only */
+#define	_LK_NBRLCK	4	/* Non-blocking lock for read only */
+
+#ifndef	NO_OLDNAMES
+#define	LK_UNLCK	_LK_UNLCK
+#define	LK_LOCK		_LK_LOCK
+#define	LK_NBLCK	_LK_NBLCK
+#define	LK_RLCK		_LK_RLCK
+#define	LK_NBRLCK	_LK_NBRLCK
+#endif	/* Not NO_OLDNAMES */
+
+#endif	/* Not _LOCKING_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/sys/stat.h b/tinyc/win32/include/sys/stat.h
new file mode 100755
index 000000000..0e2054942
--- /dev/null
+++ b/tinyc/win32/include/sys/stat.h
@@ -0,0 +1,190 @@
+/*
+ * stat.h
+ *
+ * Symbolic constants for opening and creating files, also stat, fstat and
+ * chmod functions.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _STAT_H_
+#define _STAT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_size_t
+#define __need_wchar_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif /* Not RC_INVOKED */
+
+#include <sys/types.h>
+
+/*
+ * Constants for the stat st_mode member.
+ */
+#define	_S_IFIFO	0x1000	/* FIFO */
+#define	_S_IFCHR	0x2000	/* Character */
+#define	_S_IFBLK	0x3000	/* Block: Is this ever set under w32? */
+#define	_S_IFDIR	0x4000	/* Directory */
+#define	_S_IFREG	0x8000	/* Regular */
+
+#define	_S_IFMT		0xF000	/* File type mask */
+
+#define	_S_IEXEC	0x0040
+#define	_S_IWRITE	0x0080
+#define	_S_IREAD	0x0100
+
+#define	_S_IRWXU	(_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define	_S_IXUSR	_S_IEXEC
+#define	_S_IWUSR	_S_IWRITE
+#define	_S_IRUSR	_S_IREAD
+
+#define	_S_ISDIR(m)	(((m) & _S_IFMT) == _S_IFDIR)
+#define	_S_ISFIFO(m)	(((m) & _S_IFMT) == _S_IFIFO)
+#define	_S_ISCHR(m)	(((m) & _S_IFMT) == _S_IFCHR)
+#define	_S_ISBLK(m)	(((m) & _S_IFMT) == _S_IFBLK)
+#define	_S_ISREG(m)	(((m) & _S_IFMT) == _S_IFREG)
+
+#ifndef _NO_OLDNAMES
+
+#define	S_IFIFO		_S_IFIFO
+#define	S_IFCHR		_S_IFCHR
+#define	S_IFBLK		_S_IFBLK
+#define	S_IFDIR		_S_IFDIR
+#define	S_IFREG		_S_IFREG
+#define	S_IFMT		_S_IFMT
+#define	S_IEXEC		_S_IEXEC
+#define	S_IWRITE	_S_IWRITE
+#define	S_IREAD		_S_IREAD
+#define	S_IRWXU		_S_IRWXU
+#define	S_IXUSR		_S_IXUSR
+#define	S_IWUSR		_S_IWUSR
+#define	S_IRUSR		_S_IRUSR
+
+#define	S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
+#define	S_ISFIFO(m)	(((m) & S_IFMT) == S_IFIFO)
+#define	S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)
+#define	S_ISBLK(m)	(((m) & S_IFMT) == S_IFBLK)
+#define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)
+
+#endif	/* Not _NO_OLDNAMES */
+
+#ifndef RC_INVOKED
+
+#ifndef _STAT_DEFINED
+/*
+ * The structure manipulated and returned by stat and fstat.
+ *
+ * NOTE: If called on a directory the values in the time fields are not only
+ * invalid, they will cause localtime et. al. to return NULL. And calling
+ * asctime with a NULL pointer causes an Invalid Page Fault. So watch it!
+ */
+struct _stat
+{
+	_dev_t	st_dev;		/* Equivalent to drive number 0=A 1=B ... */
+	_ino_t	st_ino;		/* Always zero ? */
+	_mode_t	st_mode;	/* See above constants */
+	short	st_nlink;	/* Number of links. */
+	short	st_uid;		/* User: Maybe significant on NT ? */
+	short	st_gid;		/* Group: Ditto */
+	_dev_t	st_rdev;	/* Seems useless (not even filled in) */
+	_off_t	st_size;	/* File size in bytes */
+	time_t	st_atime;	/* Accessed date (always 00:00 hrs local
+				 * on FAT) */
+	time_t	st_mtime;	/* Modified time */
+	time_t	st_ctime;	/* Creation time */
+};
+
+struct stat
+{
+	_dev_t	st_dev;		/* Equivalent to drive number 0=A 1=B ... */
+	_ino_t	st_ino;		/* Always zero ? */
+	_mode_t	st_mode;	/* See above constants */
+	short	st_nlink;	/* Number of links. */
+	short	st_uid;		/* User: Maybe significant on NT ? */
+	short	st_gid;		/* Group: Ditto */
+	_dev_t	st_rdev;	/* Seems useless (not even filled in) */
+	_off_t	st_size;	/* File size in bytes */
+	time_t	st_atime;	/* Accessed date (always 00:00 hrs local
+				 * on FAT) */
+	time_t	st_mtime;	/* Modified time */
+	time_t	st_ctime;	/* Creation time */
+};
+#if defined (__MSVCRT__)
+struct _stati64 {
+    _dev_t st_dev;
+    _ino_t st_ino;
+    unsigned short st_mode;
+    short st_nlink;
+    short st_uid;
+    short st_gid;
+    _dev_t st_rdev;
+    __int64 st_size;
+    time_t st_atime;
+    time_t st_mtime;
+    time_t st_ctime;
+};
+#endif /* __MSVCRT__ */
+#define _STAT_DEFINED
+#endif /* _STAT_DEFINED */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int	_fstat (int, struct _stat*);
+int	_chmod (const char*, int);
+int	_stat (const char*, struct _stat*);
+
+#if defined (__MSVCRT__)
+int  _fstati64(int, struct _stati64 *);
+int  _stati64(const char *, struct _stati64 *);
+#if !defined ( _WSTAT_DEFINED) /* also declared in wchar.h */
+int	_wstat(const wchar_t*, struct _stat*);
+int	_wstati64 (const wchar_t*, struct _stati64*);
+#define _WSTAT_DEFINED
+#endif /* _WSTAT_DEFIND */
+#endif /* __MSVCRT__ */
+
+#ifndef	_NO_OLDNAMES
+
+/* These functions live in liboldnames.a. */
+int	fstat (int, struct stat*);
+int	chmod (const char*, int);
+int	stat (const char*, struct stat*);
+
+#endif	/* Not _NO_OLDNAMES */
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _STAT_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/sys/time.h b/tinyc/win32/include/sys/time.h
new file mode 100755
index 000000000..39d85f67b
--- /dev/null
+++ b/tinyc/win32/include/sys/time.h
@@ -0,0 +1,3 @@
+
+#include <time.h>
+
diff --git a/tinyc/win32/include/sys/timeb.h b/tinyc/win32/include/sys/timeb.h
new file mode 100755
index 000000000..b5bb0fc3d
--- /dev/null
+++ b/tinyc/win32/include/sys/timeb.h
@@ -0,0 +1,82 @@
+/*
+ * timeb.h
+ *
+ * Support for the UNIX System V ftime system call.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_TIMEB_H_
+#define	_TIMEB_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifndef	RC_INVOKED
+
+/*
+ * TODO: Structure not tested.
+ */
+struct _timeb
+{
+	long	time;
+	short	millitm;
+	short	timezone;
+	short	dstflag;
+};
+
+#ifndef	_NO_OLDNAMES
+/*
+ * TODO: Structure not tested.
+ */
+struct timeb
+{
+	long	time;
+	short	millitm;
+	short	timezone;
+	short	dstflag;
+};
+#endif
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* TODO: Not tested. */
+void	_ftime (struct _timeb*);
+
+#ifndef	_NO_OLDNAMES
+void	ftime (struct timeb*);
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _TIMEB_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/sys/types.h b/tinyc/win32/include/sys/types.h
new file mode 100755
index 000000000..0679ac9b3
--- /dev/null
+++ b/tinyc/win32/include/sys/types.h
@@ -0,0 +1,118 @@
+/*
+ * types.h
+ *
+ * The definition of constants, data types and global variables.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *  Lots of types supplied by Pedro A. Aranda <paag@tid.es>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warrenties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_TYPES_H_
+#define	_TYPES_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_wchar_t
+#define __need_size_t
+#define __need_ptrdiff_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+#ifndef RC_INVOKED
+
+#ifndef _TIME_T_DEFINED
+typedef	long	time_t;
+#define	_TIME_T_DEFINED
+#endif
+
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_OFF_T_
+#define	_OFF_T_
+typedef long _off_t;
+
+#ifndef	_NO_OLDNAMES
+typedef _off_t	off_t;
+#endif
+#endif	/* Not _OFF_T_ */
+
+
+#ifndef _DEV_T_
+#define	_DEV_T_
+#ifdef __MSVCRT__
+typedef unsigned int _dev_t;
+#else
+typedef short _dev_t;
+#endif
+
+#ifndef	_NO_OLDNAMES
+typedef _dev_t	dev_t;
+#endif
+#endif	/* Not _DEV_T_ */
+
+
+#ifndef _INO_T_
+#define	_INO_T_
+typedef short _ino_t;
+
+#ifndef	_NO_OLDNAMES
+typedef _ino_t	ino_t;
+#endif
+#endif	/* Not _INO_T_ */
+
+
+#ifndef _PID_T_
+#define	_PID_T_
+typedef int	_pid_t;
+
+#ifndef	_NO_OLDNAMES
+typedef _pid_t	pid_t;
+#endif
+#endif	/* Not _PID_T_ */
+
+
+#ifndef _MODE_T_
+#define	_MODE_T_
+typedef unsigned short _mode_t;
+
+#ifndef	_NO_OLDNAMES
+typedef _mode_t	mode_t;
+#endif
+#endif	/* Not _MODE_T_ */
+
+
+#ifndef _SIGSET_T_
+#define	_SIGSET_T_
+typedef int	_sigset_t;
+
+#ifndef	_NO_OLDNAMES
+typedef _sigset_t	sigset_t;
+#endif
+#endif	/* Not _SIGSET_T_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _TYPES_H_ */
diff --git a/tinyc/win32/include/sys/unistd.h b/tinyc/win32/include/sys/unistd.h
new file mode 100755
index 000000000..ed122d9dd
--- /dev/null
+++ b/tinyc/win32/include/sys/unistd.h
@@ -0,0 +1,9 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * unistd.h maps (roughly) to io.h
+ */
+#ifndef __STRICT_ANSI__
+#include <io.h>
+#endif
+
diff --git a/tinyc/win32/include/sys/utime.h b/tinyc/win32/include/sys/utime.h
new file mode 100755
index 000000000..049524bed
--- /dev/null
+++ b/tinyc/win32/include/sys/utime.h
@@ -0,0 +1,89 @@
+/*
+ * utime.h
+ *
+ * Support for the utime function.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_UTIME_H_
+#define	_UTIME_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_wchar_t
+#define __need_size_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+#include <sys/types.h>
+
+#ifndef	RC_INVOKED
+
+/*
+ * Structure used by _utime function.
+ */
+struct _utimbuf
+{
+	time_t	actime;		/* Access time */
+	time_t	modtime;	/* Modification time */
+};
+
+
+#ifndef	_NO_OLDNAMES
+/* NOTE: Must be the same as _utimbuf above. */
+struct utimbuf
+{
+	time_t	actime;
+	time_t	modtime;
+};
+#endif	/* Not _NO_OLDNAMES */
+
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+int	_utime (const char*, struct _utimbuf*);
+int	_futime (int, struct _utimbuf*);
+
+/* The wide character version, only available for MSVCRT versions of the
+ * C runtime library. */
+#ifdef __MSVCRT__
+int	_wutime (const wchar_t*, struct _utimbuf*);
+#endif /* MSVCRT runtime */
+#ifndef	_NO_OLDNAMES
+int	utime (const char*, struct utimbuf*);
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _UTIME_H_ */
+
+#endif	/* Not __STRICT_ANSI__ */
+
diff --git a/tinyc/win32/include/tchar.h b/tinyc/win32/include/tchar.h
new file mode 100755
index 000000000..72c1b3c81
--- /dev/null
+++ b/tinyc/win32/include/tchar.h
@@ -0,0 +1,367 @@
+/* 
+ * tchar.h
+ *
+ * Unicode mapping layer for the standard C library. By including this
+ * file and using the 't' names for string functions
+ * (eg. _tprintf) you can make code which can be easily adapted to both
+ * Unicode and non-unicode environments. In a unicode enabled compile define
+ * _UNICODE before including tchar.h, otherwise the standard non-unicode
+ * library functions will be used.
+ *
+ * Note that you still need to include string.h or stdlib.h etc. to define
+ * the appropriate functions. Also note that there are several defines
+ * included for non-ANSI functions which are commonly available (but using
+ * the convention of prepending an underscore to non-ANSI library function
+ * names).
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_TCHAR_H_
+#define _TCHAR_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+/*
+ * NOTE: This tests _UNICODE, which is different from the UNICODE define
+ *       used to differentiate Win32 API calls.
+ */
+#ifdef	_UNICODE
+
+
+/*
+ * Use TCHAR instead of char or wchar_t. It will be appropriately translated
+ * if _UNICODE is correctly defined (or not).
+ */
+#ifndef _TCHAR_DEFINED
+#ifndef RC_INVOKED
+typedef	wchar_t	TCHAR;
+typedef wchar_t _TCHAR;
+#endif	/* Not RC_INVOKED */
+#define _TCHAR_DEFINED
+#endif
+
+
+/*
+ * __TEXT is a private macro whose specific use is to force the expansion of a
+ * macro passed as an argument to the macros _T or _TEXT.  DO NOT use this
+ * macro within your programs.  It's name and function could change without
+ * notice.
+ */
+#define	__TEXT(x)	L##x
+
+/*  for porting from other Windows compilers */
+#if 0  // no  wide startup module
+#define _tmain      wmain
+#define _tWinMain   wWinMain
+#define _tenviron   _wenviron
+#define __targv     __wargv
+#endif
+
+/*
+ * Unicode functions
+ */
+#define	_tprintf	wprintf
+#define	_ftprintf	fwprintf
+#define	_stprintf	swprintf
+#define	_sntprintf	_snwprintf
+#define	_vtprintf	vwprintf
+#define	_vftprintf	vfwprintf
+#define _vstprintf	vswprintf
+#define	_vsntprintf	_vsnwprintf
+#define	_tscanf		wscanf
+#define	_ftscanf	fwscanf
+#define	_stscanf	swscanf
+#define	_fgettc		fgetwc
+#define	_fgettchar	_fgetwchar
+#define	_fgetts		fgetws
+#define	_fputtc		fputwc
+#define	_fputtchar	_fputwchar
+#define	_fputts		fputws
+#define	_gettc		getwc
+#define	_getts		getws
+#define	_puttc		putwc
+#define	_putts		putws
+#define	_ungettc	ungetwc
+#define	_tcstod		wcstod
+#define	_tcstol		wcstol
+#define _tcstoul	wcstoul
+#define	_itot		_itow
+#define	_ltot		_ltow
+#define	_ultot		_ultow
+#define	_ttoi		_wtoi
+#define	_ttol		_wtol
+#define	_tcscat		wcscat
+#define _tcschr		wcschr
+#define _tcscmp		wcscmp
+#define _tcscpy		wcscpy
+#define _tcscspn	wcscspn
+#define	_tcslen		wcslen
+#define	_tcsncat	wcsncat
+#define	_tcsncmp	wcsncmp
+#define	_tcsncpy	wcsncpy
+#define	_tcspbrk	wcspbrk
+#define	_tcsrchr	wcsrchr
+#define _tcsspn		wcsspn
+#define	_tcsstr		wcsstr
+#define _tcstok		wcstok
+#define	_tcsdup		_wcsdup
+#define	_tcsicmp	_wcsicmp
+#define	_tcsnicmp	_wcsnicmp
+#define	_tcsnset	_wcsnset
+#define	_tcsrev		_wcsrev
+#define _tcsset		_wcsset
+#define	_tcslwr		_wcslwr
+#define	_tcsupr		_wcsupr
+#define	_tcsxfrm	wcsxfrm
+#define	_tcscoll	wcscoll
+#define	_tcsicoll	_wcsicoll
+#define	_istalpha	iswalpha
+#define	_istupper	iswupper
+#define	_istlower	iswlower
+#define	_istdigit	iswdigit
+#define	_istxdigit	iswxdigit
+#define	_istspace	iswspace
+#define	_istpunct	iswpunct
+#define	_istalnum	iswalnum
+#define	_istprint	iswprint
+#define	_istgraph	iswgraph
+#define	_istcntrl	iswcntrl
+#define	_istascii	iswascii
+#define _totupper	towupper
+#define	_totlower	towlower
+#define _tcsftime	wcsftime
+/* Macro functions */ 
+#define _tcsdec     _wcsdec
+#define _tcsinc     _wcsinc
+#define _tcsnbcnt   _wcsncnt
+#define _tcsnccnt   _wcsncnt
+#define _tcsnextc   _wcsnextc
+#define _tcsninc    _wcsninc
+#define _tcsspnp    _wcsspnp
+#define _wcsdec(_wcs1, _wcs2) ((_wcs1)>=(_wcs2) ? NULL : (_wcs2)-1)
+#define _wcsinc(_wcs)  ((_wcs)+1)
+#define _wcsnextc(_wcs) ((unsigned int) *(_wcs))
+#define _wcsninc(_wcs, _inc) (((_wcs)+(_inc)))
+#define _wcsncnt(_wcs, _cnt) ((wcslen(_wcs)>_cnt) ? _count : wcslen(_wcs))
+#define _wcsspnp(_wcs1, _wcs2) ((*((_wcs1)+wcsspn(_wcs1,_wcs2))) ? ((_wcs1)+wcsspn(_wcs1,_wcs2)) : NULL)
+
+#if 1  // defined __MSVCRT__
+/*
+ *   These wide functions not in crtdll.dll.
+ *   Define macros anyway so that _wfoo rather than _tfoo is undefined
+ */
+#define _ttoi64     _wtoi64
+#define _i64tot     _i64tow
+#define _ui64tot    _ui64tow
+#define	_tasctime	_wasctime
+#define	_tctime		_wctime
+#define	_tstrdate	_wstrdate
+#define	_tstrtime	_wstrtime
+#define	_tutime		_wutime
+#define _tcsnccoll  _wcsncoll
+#define _tcsncoll   _wcsncoll
+#define _tcsncicoll _wcsnicoll
+#define _tcsnicoll  _wcsnicoll
+#define _taccess    _waccess
+#define _tchmod     _wchmod
+#define _tcreat     _wcreat
+#define _tfindfirst _wfindfirst
+#define _tfindnext  _wfindnext
+#define _tfopen     _wfopen
+#define _tgetenv    _wgetenv
+#define _tmktemp    _wmktemp
+#define _topen      _wopen
+#define _tremove    _wremove
+#define _trename    _wrename
+#define _tsopen     _wsopen
+#define _tsetlocale _wsetlocale
+#define _tunlink    _wunlink
+#define _tfinddata_t    _wfinddata_t
+#define _tfindfirsti64  _wfindfirsti64
+#define _tfindnexti64   _wfindnexti64
+#define _tfinddatai64_t _wfinddatai64_t
+#endif  /* __MSVCRT__ */
+
+#else	/* Not _UNICODE */
+
+/*
+ * TCHAR, the type you should use instead of char.
+ */
+#ifndef _TCHAR_DEFINED
+#ifndef RC_INVOKED
+typedef char	TCHAR;
+typedef char	_TCHAR;
+#endif
+#define _TCHAR_DEFINED
+#endif
+
+/*
+ * __TEXT is a private macro whose specific use is to force the expansion of a
+ * macro passed as an argument to the macros _T or _TEXT.  DO NOT use this
+ * macro within your programs.  It's name and function could change without
+ * notice.
+ */
+#define	__TEXT(x)	x
+
+/*  for porting from other Windows compilers */
+#define _tmain      main
+#define _tWinMain   WinMain
+#define _tenviron  _environ
+#define __targv     __argv
+
+/*
+ * Non-unicode (standard) functions
+ */
+
+#define	_tprintf	printf
+#define _ftprintf	fprintf
+#define	_stprintf	sprintf
+#define	_sntprintf	_snprintf
+#define	_vtprintf	vprintf
+#define	_vftprintf	vfprintf
+#define _vstprintf	vsprintf
+#define	_vsntprintf	_vsnprintf
+#define	_tscanf		scanf
+#define	_ftscanf	fscanf
+#define	_stscanf	sscanf
+#define	_fgettc		fgetc
+#define	_fgettchar	_fgetchar
+#define	_fgetts		fgets
+#define	_fputtc		fputc
+#define	_fputtchar	_fputchar
+#define	_fputts		fputs
+#define	_tfopen		fopen
+#define	_tgetenv	getenv
+#define	_gettc		getc
+#define	_getts		gets
+#define	_puttc		putc
+#define	_putts		puts
+#define	_ungettc	ungetc
+#define	_tcstod		strtod
+#define	_tcstol		strtol
+#define _tcstoul	strtoul
+#define	_itot		_itoa
+#define	_ltot		_ltoa
+#define	_ultot		_ultoa
+#define	_ttoi		atoi
+#define	_ttol		atol
+#define	_tcscat		strcat
+#define _tcschr		strchr
+#define _tcscmp		strcmp
+#define _tcscpy		strcpy
+#define _tcscspn	strcspn
+#define	_tcslen		strlen
+#define	_tcsncat	strncat
+#define	_tcsncmp	strncmp
+#define	_tcsncpy	strncpy
+#define	_tcspbrk	strpbrk
+#define	_tcsrchr	strrchr
+#define _tcsspn		strspn
+#define	_tcsstr		strstr
+#define _tcstok		strtok
+#define	_tcsdup		_strdup
+#define	_tcsicmp	_stricmp
+#define	_tcsnicmp	_strnicmp
+#define	_tcsnset	_strnset
+#define	_tcsrev		_strrev
+#define _tcsset		_strset
+#define	_tcslwr		_strlwr
+#define	_tcsupr		_strupr
+#define	_tcsxfrm	strxfrm
+#define	_tcscoll	strcoll
+#define	_tcsicoll	_stricoll
+#define	_istalpha	isalpha
+#define	_istupper	isupper
+#define	_istlower	islower
+#define	_istdigit	isdigit
+#define	_istxdigit	isxdigit
+#define	_istspace	isspace
+#define	_istpunct	ispunct
+#define	_istalnum	isalnum
+#define	_istprint	isprint
+#define	_istgraph	isgraph
+#define	_istcntrl	iscntrl
+#define	_istascii	isascii
+#define _totupper	toupper
+#define	_totlower	tolower
+#define	_tasctime	asctime
+#define	_tctime		ctime
+#define	_tstrdate	_strdate
+#define	_tstrtime	_strtime
+#define	_tutime		_utime
+#define _tcsftime	strftime
+/* Macro functions */ 
+#define _tcsdec     _strdec
+#define _tcsinc     _strinc
+#define _tcsnbcnt   _strncnt
+#define _tcsnccnt   _strncnt
+#define _tcsnextc   _strnextc
+#define _tcsninc    _strninc
+#define _tcsspnp    _strspnp
+#define _strdec(_str1, _str2) ((_str1)>=(_str2) ? NULL : (_str2)-1)
+#define _strinc(_str)  ((_str)+1)
+#define _strnextc(_str) ((unsigned int) *(_str))
+#define _strninc(_str, _inc) (((_str)+(_inc)))
+#define _strncnt(_str, _cnt) ((strlen(_str)>_cnt) ? _count : strlen(_str))
+#define _strspnp(_str1, _str2) ((*((_str1)+strspn(_str1,_str2))) ? ((_str1)+strspn(_str1,_str2)) : NULL)
+
+#define _tchmod     _chmod
+#define _tcreat     _creat
+#define _tfindfirst _findfirst
+#define _tfindnext  _findnext
+#define _tmktemp    _mktemp
+#define _topen      _open
+#define _taccess    _access
+#define _tremove    remove
+#define _trename    rename
+#define _tsopen     _sopen
+#define _tsetlocale setlocale
+#define _tunlink    _unlink
+#define _tfinddata_t    _finddata_t
+
+
+#if 1  // defined __MSVCRT__
+/* Not in crtdll.dll. Define macros anyway? */
+#define _ttoi64     _atoi64
+#define _i64tot     _i64toa
+#define _ui64tot    _ui64toa
+#define _tcsnccoll  _strncoll
+#define _tcsncoll   _strncoll
+#define _tcsncicoll _strnicoll
+#define _tcsnicoll  _strnicoll
+#define _tfindfirsti64  _findfirsti64
+#define _tfindnexti64   _findnexti64
+#define _tfinddatai64_t _finddatai64_t
+#endif  /* __MSVCRT__ */
+
+#endif	/* Not _UNICODE */
+
+/*
+ * UNICODE a constant string when _UNICODE is defined else returns the string
+ * unmodified.  Also defined in w32api/winnt.h.
+ */
+#define _TEXT(x)	__TEXT(x)
+#define	_T(x)		__TEXT(x)
+
+#endif	/* Not _TCHAR_H_ */
+
diff --git a/tinyc/win32/include/time.h b/tinyc/win32/include/time.h
new file mode 100755
index 000000000..ade7f6db7
--- /dev/null
+++ b/tinyc/win32/include/time.h
@@ -0,0 +1,219 @@
+/* 
+ * time.h
+ *
+ * Date and time functions and types.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_TIME_H_
+#define	_TIME_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define __need_wchar_t
+#define __need_size_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+/*
+ * Need a definition of time_t.
+ */
+#include <sys/types.h>
+
+/*
+ * Number of clock ticks per second. A clock tick is the unit by which
+ * processor time is measured and is returned by 'clock'.
+ */
+#define	CLOCKS_PER_SEC	((clock_t)1000)
+#define	CLK_TCK		CLOCKS_PER_SEC
+
+
+#ifndef RC_INVOKED
+
+/*
+ * A type for storing the current time and date. This is the number of
+ * seconds since midnight Jan 1, 1970.
+ * NOTE: Normally this is defined by the above include of sys/types.h
+ */
+#ifndef _TIME_T_DEFINED
+typedef	long	time_t;
+#define _TIME_T_DEFINED
+#endif
+
+/*
+ * A type for measuring processor time (in clock ticks).
+ */
+#ifndef _CLOCK_T_DEFINED
+typedef	long	clock_t;
+#define _CLOCK_T_DEFINED
+#endif
+
+
+/*
+ * A structure for storing all kinds of useful information about the
+ * current (or another) time.
+ */
+struct tm
+{
+	int	tm_sec;		/* Seconds: 0-59 (K&R says 0-61?) */
+	int	tm_min;		/* Minutes: 0-59 */
+	int	tm_hour;	/* Hours since midnight: 0-23 */
+	int	tm_mday;	/* Day of the month: 1-31 */
+	int	tm_mon;		/* Months *since* january: 0-11 */
+	int	tm_year;	/* Years since 1900 */
+	int	tm_wday;	/* Days since Sunday (0-6) */
+	int	tm_yday;	/* Days since Jan. 1: 0-365 */
+	int	tm_isdst;	/* +1 Daylight Savings Time, 0 No DST,
+				 * -1 don't know */
+};
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+clock_t	clock (void);
+time_t	time (time_t*);
+double	difftime (time_t, time_t);
+time_t	mktime (struct tm*);
+
+/*
+ * These functions write to and return pointers to static buffers that may
+ * be overwritten by other function calls. Yikes!
+ *
+ * NOTE: localtime, and perhaps the others of the four functions grouped
+ * below may return NULL if their argument is not 'acceptable'. Also note
+ * that calling asctime with a NULL pointer will produce an Invalid Page
+ * Fault and crap out your program. Guess how I know. Hint: stat called on
+ * a directory gives 'invalid' times in st_atime etc...
+ */
+char*		asctime (const struct tm*);
+char*		ctime (const time_t*);
+struct tm*	gmtime (const time_t*);
+struct tm*	localtime (const time_t*);
+
+
+size_t	strftime (char*, size_t, const char*, const struct tm*);
+
+size_t	wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*);
+
+#ifndef __STRICT_ANSI__
+extern void	_tzset (void);
+
+#ifndef _NO_OLDNAMES
+extern void	tzset (void);
+#endif
+
+size_t	strftime(char*, size_t, const char*, const struct tm*);
+char*	_strdate(char*);
+char*	_strtime(char*);
+
+#endif	/* Not __STRICT_ANSI__ */
+
+/*
+ * _daylight: non zero if daylight savings time is used.
+ * _timezone: difference in seconds between GMT and local time.
+ * _tzname: standard/daylight savings time zone names (an array with two
+ *          elements).
+ */
+#ifdef __MSVCRT__
+
+/* These are for compatibility with pre-VC 5.0 suppied MSVCRT. */
+extern int*	__p__daylight (void);
+extern long*	__p__timezone (void);
+extern char**	__p__tzname (void);
+
+__MINGW_IMPORT int	_daylight;
+__MINGW_IMPORT long	_timezone;
+__MINGW_IMPORT char 	*_tzname[2];
+
+#else /* not __MSVCRT (ie. crtdll) */
+
+#ifndef __DECLSPEC_SUPPORTED
+
+extern int*	__imp__daylight_dll;
+extern long*	__imp__timezone_dll;
+extern char**	__imp__tzname;
+
+#define _daylight	(*__imp__daylight_dll)
+#define _timezone	(*__imp__timezone_dll)
+#define _tzname		(__imp__tzname)
+
+#else /* __DECLSPEC_SUPPORTED */
+
+__MINGW_IMPORT int	_daylight_dll;
+__MINGW_IMPORT long	_timezone_dll;
+__MINGW_IMPORT char*	_tzname[2];
+
+#define _daylight	_daylight_dll
+#define _timezone	_timezone_dll
+
+#endif /* __DECLSPEC_SUPPORTED */
+
+#endif /* not __MSVCRT__ */
+
+#ifndef _NO_OLDNAMES
+
+#ifdef __MSVCRT__
+
+/* These go in the oldnames import library for MSVCRT. */
+__MINGW_IMPORT int	daylight;
+__MINGW_IMPORT long	timezone;
+__MINGW_IMPORT char 	*tzname[2];
+
+#ifndef _WTIME_DEFINED
+
+/* wide function prototypes, also declared in wchar.h */
+
+wchar_t *	_wasctime(const struct tm*);
+wchar_t *	_wctime(const time_t*);
+wchar_t*	_wstrdate(wchar_t*);
+wchar_t*	_wstrtime(wchar_t*);
+
+#define _WTIME_DEFINED
+#endif /* _WTIME_DEFINED */ 
+
+
+#else /* not __MSVCRT__ */
+
+/* CRTDLL is royally messed up when it comes to these macros.
+   TODO: import and alias these via oldnames import library instead 
+   of macros.  */
+
+#define daylight        _daylight
+/* NOTE: timezone not defined because it would conflict with sys/timeb.h.
+   Also, tzname used to a be macro, but now it's in moldname. */
+__MINGW_IMPORT char 	*tzname[2];
+
+#endif /* not __MSVCRT__ */
+
+#endif	/* Not _NO_OLDNAMES */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _TIME_H_ */
+
diff --git a/tinyc/win32/include/unistd.h b/tinyc/win32/include/unistd.h
new file mode 100755
index 000000000..8f51f7661
--- /dev/null
+++ b/tinyc/win32/include/unistd.h
@@ -0,0 +1,10 @@
+/*
+ * This file is part of the Mingw32 package.
+ *
+ * unistd.h maps (roughly) to io.h
+ */
+
+#ifndef __STRICT_ANSI__
+#include <io.h>
+#endif
+
diff --git a/tinyc/win32/include/values.h b/tinyc/win32/include/values.h
new file mode 100755
index 000000000..10e16a281
--- /dev/null
+++ b/tinyc/win32/include/values.h
@@ -0,0 +1,4 @@
+/*
+ * TODO: Nothing here yet. Should provide UNIX compatibility constants
+ * comparible to those in limits.h and float.h.
+ */
diff --git a/tinyc/win32/include/varargs.h b/tinyc/win32/include/varargs.h
new file mode 100755
index 000000000..daee29e87
--- /dev/null
+++ b/tinyc/win32/include/varargs.h
@@ -0,0 +1,11 @@
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#include <stdarg.h>
+
+#define va_dcl
+#define va_alist __va_alist
+#undef va_start
+#define va_start(ap) ap = __builtin_varargs_start
+
+#endif
diff --git a/tinyc/win32/include/wchar.h b/tinyc/win32/include/wchar.h
new file mode 100755
index 000000000..4ad2ab9bf
--- /dev/null
+++ b/tinyc/win32/include/wchar.h
@@ -0,0 +1,318 @@
+/*
+ * wchar.h
+ *
+ * Defines of all functions for supporting wide characters. Actually it
+ * just includes all those headers, which is not a good thing to do from a
+ * processing time point of view, but it does mean that everything will be
+ * in sync.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.2 $
+ * $Author: bellard $
+ * $Date: 2005/04/17 13:14:29 $
+ *
+ */
+
+#ifndef	_WCHAR_H_
+#define	_WCHAR_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+
+#define __need_size_t
+#define __need_wint_t
+#define __need_wchar_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif /* Not RC_INVOKED */
+
+#define WCHAR_MIN	0
+#define WCHAR_MAX	((wchar_t)-1)
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+#ifndef	__STRICT_ANSI__
+
+#ifndef	_FSIZE_T_DEFINED
+typedef	unsigned long	_fsize_t;
+#define _FSIZE_T_DEFINED
+#endif
+
+#ifndef _WFINDDATA_T_DEFINED
+struct _wfinddata_t {
+    	unsigned	attrib;
+    	time_t		time_create;	/* -1 for FAT file systems */
+    	time_t		time_access;	/* -1 for FAT file systems */
+    	time_t		time_write;
+    	_fsize_t	size;
+    	wchar_t		name[FILENAME_MAX];	/* may include spaces. */
+};
+struct _wfinddatai64_t {
+    unsigned    attrib;
+    time_t      time_create;
+    time_t      time_access;
+    time_t      time_write;
+    __int64     size;
+    wchar_t     name[FILENAME_MAX];
+};
+#define _WFINDDATA_T_DEFINED
+#endif
+
+/* Wide character versions. Also defined in io.h. */
+/* CHECK: I believe these only exist in MSVCRT, and not in CRTDLL. Also
+   applies to other wide character versions? */
+#if !defined (_WIO_DEFINED)
+#if defined (__MSVCRT__)
+int	 _waccess (const wchar_t*, int);
+int	_wchmod (const wchar_t*, int);
+int	_wcreat (const wchar_t*, int);
+long	_wfindfirst (wchar_t*, struct _wfinddata_t *);
+int	_wfindnext (long, struct _wfinddata_t *);
+int	_wunlink (const wchar_t*);
+int	_wopen (const wchar_t*, int, ...);
+int	_wsopen (const wchar_t*, int, int, ...);
+wchar_t* _wmktemp (wchar_t*);
+long	_wfindfirsti64 (const wchar_t*, struct _wfinddatai64_t*);
+int 	_wfindnexti64 (long, struct _wfinddatai64_t*);
+#endif /* defined (__MSVCRT__) */
+#define _WIO_DEFINED
+#endif /* _WIO_DEFINED */
+
+#ifndef _WSTDIO_DEFINED
+/* also in stdio.h - keep in sync */
+int	fwprintf (FILE*, const wchar_t*, ...);
+int	wprintf (const wchar_t*, ...);
+int	swprintf (wchar_t*, const wchar_t*, ...);
+int	_snwprintf (wchar_t*, size_t, const wchar_t*, ...);
+int	vfwprintf (FILE*, const wchar_t*, va_list);
+int	vwprintf (const wchar_t*, va_list);
+int	vswprintf (wchar_t*, const wchar_t*, va_list);
+int	_vsnwprintf (wchar_t*, size_t, const wchar_t*, va_list);
+int	fwscanf (FILE*, const wchar_t*, ...);
+int	wscanf (const wchar_t*, ...);
+int	swscanf (const wchar_t*, const wchar_t*, ...);
+wint_t	fgetwc (FILE*);
+wint_t	fputwc (wchar_t, FILE*);
+wint_t	ungetwc (wchar_t, FILE*);
+
+#ifndef __NO_ISOCEXT  /* externs in libmingwex.a */
+int snwprintf(wchar_t* s, size_t n, const wchar_t*  format, ...);
+extern inline int vsnwprintf (wchar_t* s, size_t n, const wchar_t* format,
+			   va_list arg)
+  { return _vsnwprintf ( s, n, format, arg); }
+#endif
+
+#ifdef __MSVCRT__ 
+wchar_t* fgetws (wchar_t*, int, FILE*);
+int	fputws (const wchar_t*, FILE*);
+wint_t	getwc (FILE*);
+wint_t  getwchar (void);
+wchar_t* _getws (wchar_t*);
+wint_t	putwc (wint_t, FILE*);
+int	_putws (const wchar_t*);
+wint_t	putwchar (wint_t);
+
+FILE*	_wfopen (const wchar_t*, const wchar_t*);
+FILE*	_wfreopen (const wchar_t*, const wchar_t*, FILE*);
+FILE*   _wfsopen (const wchar_t*, const wchar_t*, int);
+wchar_t* _wtmpnam (wchar_t*);
+wchar_t* _wtempnam (const wchar_t*, const wchar_t*);
+int 	_wrename (const wchar_t*, const wchar_t*);
+int	_wremove (const wchar_t*)
+
+FILE*	  _wpopen (const wchar_t*, const wchar_t*)
+void	  _wperror (const wchar_t*);
+#endif	/* __MSVCRT__ */
+#define _WSTDIO_DEFINED
+#endif /* _WSTDIO_DEFINED */
+
+#ifndef _WDIRECT_DEFINED
+/* Also in direct.h */
+#ifdef __MSVCRT__ 
+int	  _wchdir (const wchar_t*);
+wchar_t*  _wgetcwd (wchar_t*, int);
+wchar_t*  _wgetdcwd (int, wchar_t*, int);
+int	  _wmkdir (const wchar_t*);
+int	  _wrmdir (const wchar_t*);
+#endif	/* __MSVCRT__ */
+#define _WDIRECT_DEFINED
+#endif /* _WDIRECT_DEFINED */
+
+#ifndef _STAT_DEFINED
+/*
+ * The structure manipulated and returned by stat and fstat.
+ *
+ * NOTE: If called on a directory the values in the time fields are not only
+ * invalid, they will cause localtime et. al. to return NULL. And calling
+ * asctime with a NULL pointer causes an Invalid Page Fault. So watch it!
+ */
+struct _stat
+{
+	_dev_t	st_dev;		/* Equivalent to drive number 0=A 1=B ... */
+	_ino_t	st_ino;		/* Always zero ? */
+	_mode_t	st_mode;	/* See above constants */
+	short	st_nlink;	/* Number of links. */
+	short	st_uid;		/* User: Maybe significant on NT ? */
+	short	st_gid;		/* Group: Ditto */
+	_dev_t	st_rdev;	/* Seems useless (not even filled in) */
+	_off_t	st_size;	/* File size in bytes */
+	time_t	st_atime;	/* Accessed date (always 00:00 hrs local
+				 * on FAT) */
+	time_t	st_mtime;	/* Modified time */
+	time_t	st_ctime;	/* Creation time */
+};
+
+struct stat
+{
+	_dev_t	st_dev;		/* Equivalent to drive number 0=A 1=B ... */
+	_ino_t	st_ino;		/* Always zero ? */
+	_mode_t	st_mode;	/* See above constants */
+	short	st_nlink;	/* Number of links. */
+	short	st_uid;		/* User: Maybe significant on NT ? */
+	short	st_gid;		/* Group: Ditto */
+	_dev_t	st_rdev;	/* Seems useless (not even filled in) */
+	_off_t	st_size;	/* File size in bytes */
+	time_t	st_atime;	/* Accessed date (always 00:00 hrs local
+				 * on FAT) */
+	time_t	st_mtime;	/* Modified time */
+	time_t	st_ctime;	/* Creation time */
+};
+#if defined (__MSVCRT__)
+struct _stati64 {
+    _dev_t st_dev;
+    _ino_t st_ino;
+    unsigned short st_mode;
+    short st_nlink;
+    short st_uid;
+    short st_gid;
+    _dev_t st_rdev;
+    __int64 st_size;
+    time_t st_atime;
+    time_t st_mtime;
+    time_t st_ctime;
+    };
+#endif  /* __MSVCRT__ */
+#define _STAT_DEFINED
+#endif /* _STAT_DEFINED */
+
+#if !defined ( _WSTAT_DEFINED)
+/* also declared in sys/stat.h */
+#if defined __MSVCRT__
+int	_wstat (const wchar_t*, struct _stat*);
+int	_wstati64 (const wchar_t*, struct _stati64*);
+#endif  /* __MSVCRT__ */
+#define _WSTAT_DEFINED
+#endif /* ! _WSTAT_DEFIND  */
+
+#ifndef _WTIME_DEFINED
+#ifdef __MSVCRT__
+/* wide function prototypes, also declared in time.h */
+wchar_t*	_wasctime (const struct tm*);
+wchar_t*	_wctime (const time_t*);
+wchar_t*	_wstrdate (wchar_t*);
+wchar_t*	_wstrtime (wchar_t*);
+#endif /* __MSVCRT__ */
+size_t		wcsftime (wchar_t*, size_t, const wchar_t*, const struct tm*);
+#define _WTIME_DEFINED
+#endif /* _WTIME_DEFINED */ 
+
+#ifndef _WLOCALE_DEFINED  /* also declared in locale.h */
+wchar_t* _wsetlocale (int, const wchar_t*);
+#define _WLOCALE_DEFINED
+#endif
+
+#ifndef _WSTDLIB_DEFINED /* also declared in stdlib.h */
+long	wcstol	(const wchar_t*, wchar_t**, int);
+unsigned long	wcstoul (const wchar_t*, wchar_t**, int);
+double	wcstod	(const wchar_t*, wchar_t**);
+#if !defined __NO_ISOCEXT /* extern stub in static libmingwex.a */
+extern __inline__ float wcstof( const wchar_t *nptr, wchar_t **endptr)
+{  return (wcstod(nptr, endptr)); }
+#endif /* __NO_ISOCEXT */
+#define  _WSTDLIB_DEFINED
+#endif
+
+
+#ifndef	_NO_OLDNAMES
+
+/* Wide character versions. Also declared in io.h. */
+/* CHECK: Are these in the oldnames???  NO! */
+#if (0)
+int		waccess (const wchar_t *, int);
+int		wchmod (const wchar_t *, int);
+int		wcreat (const wchar_t *, int);
+long		wfindfirst (wchar_t *, struct _wfinddata_t *);
+int		wfindnext (long, struct _wfinddata_t *);
+int		wunlink (const wchar_t *);
+int		wrename (const wchar_t *, const wchar_t *);
+int		wremove (const wchar_t *);
+int		wopen (const wchar_t *, int, ...);
+int		wsopen (const wchar_t *, int, int, ...);
+wchar_t*	wmktemp (wchar_t *);
+#endif
+#endif /* _NO_OLDNAMES */
+
+#endif /* not __STRICT_ANSI__ */
+
+/* These are resolved by -lmsvcp60 */
+/* If you don't have msvcp60.dll in your windows system directory, you can
+   easily obtain it with a search from your favorite search engine. */
+typedef int mbstate_t;
+typedef wchar_t _Wint_t;
+
+wint_t  btowc(int);
+size_t  mbrlen(const char *, size_t, mbstate_t *);
+size_t  mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
+size_t  mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *);
+
+size_t  wcrtomb(char *, wchar_t, mbstate_t *);
+size_t  wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *);
+int  	wctob(wint_t);
+
+#ifndef __NO_ISOCEXT /* these need static lib libmingwex.a */
+extern inline int fwide(FILE* stream, int mode) {return -1;} /* limited to byte orientation */ 
+extern inline int mbsinit(const mbstate_t* ps) {return 1;}
+wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);
+wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
+int wmemcmp(const wchar_t* s1, const wchar_t * s2, size_t n);
+wchar_t* wmemcpy(wchar_t* __restrict__ s1, const wchar_t* __restrict__ s2,
+		 size_t n);
+wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);
+long long wcstoll(const wchar_t* __restrict__ nptr,
+		  wchar_t** __restrict__ endptr, int base);
+unsigned long long wcstoull(const wchar_t* __restrict__ nptr,
+			    wchar_t ** __restrict__ endptr, int base);
+
+#endif /* __NO_ISOCEXT */
+
+
+#ifdef __cplusplus
+}	/* end of extern "C" */
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* not _WCHAR_H_ */
+
diff --git a/tinyc/win32/include/wctype.h b/tinyc/win32/include/wctype.h
new file mode 100755
index 000000000..1fb00fb3c
--- /dev/null
+++ b/tinyc/win32/include/wctype.h
@@ -0,0 +1,127 @@
+/* 
+ * wctype.h
+ *
+ * Functions for testing wide character types and converting characters.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Mumit Khan <khan@xraylith.wisc.edu>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAIMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef _WCTYPE_H_
+#define _WCTYPE_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#define	__need_wchar_t
+#define	__need_wint_t
+#ifndef RC_INVOKED
+#include <stddef.h>
+#endif	/* Not RC_INVOKED */
+
+/*
+ * The following flags are used to tell iswctype and _isctype what character
+ * types you are looking for.
+ */
+#define	_UPPER		0x0001
+#define	_LOWER		0x0002
+#define	_DIGIT		0x0004
+#define	_SPACE		0x0008
+#define	_PUNCT		0x0010
+#define	_CONTROL	0x0020
+#define	_BLANK		0x0040
+#define	_HEX		0x0080
+#define	_LEADBYTE	0x8000
+
+#define	_ALPHA		0x0103
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WEOF
+#define	WEOF	(wchar_t)(0xFFFF)
+#endif
+
+#ifndef _WCTYPE_T_DEFINED
+typedef wchar_t wctype_t;
+#define _WCTYPE_T_DEFINED
+#endif
+
+/* Wide character equivalents - also in ctype.h */
+int	iswalnum(wint_t);
+int	iswalpha(wint_t);
+int	iswascii(wint_t);
+int	iswcntrl(wint_t);
+int	iswctype(wint_t, wctype_t);
+int	is_wctype(wint_t, wctype_t);	/* Obsolete! */
+int	iswdigit(wint_t);
+int	iswgraph(wint_t);
+int	iswlower(wint_t);
+int	iswprint(wint_t);
+int	iswpunct(wint_t);
+int	iswspace(wint_t);
+int	iswupper(wint_t);
+int	iswxdigit(wint_t);
+
+wchar_t	towlower(wchar_t);
+wchar_t	towupper(wchar_t);
+
+int	isleadbyte (int);
+
+/* Also in ctype.h */
+
+__MINGW_IMPORT unsigned short _ctype[];
+#ifdef __MSVCRT__
+__MINGW_IMPORT unsigned short* _pctype;
+#else
+__MINGW_IMPORT unsigned short* _pctype_dll;
+#define  _pctype _pctype_dll
+#endif
+
+#if !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED))
+#define __WCTYPE_INLINES_DEFINED
+extern inline int iswalnum(wint_t wc) {return (iswctype(wc,_ALPHA|_DIGIT));}
+extern inline int iswalpha(wint_t wc) {return (iswctype(wc,_ALPHA));}
+extern inline int iswascii(wint_t wc) {return (((unsigned)wc & 0x7F) ==0);}
+extern inline int iswcntrl(wint_t wc) {return (iswctype(wc,_CONTROL));}
+extern inline int iswdigit(wint_t wc) {return (iswctype(wc,_DIGIT));}
+extern inline int iswgraph(wint_t wc) {return (iswctype(wc,_PUNCT|_ALPHA|_DIGIT));}
+extern inline int iswlower(wint_t wc) {return (iswctype(wc,_LOWER));}
+extern inline int iswprint(wint_t wc) {return (iswctype(wc,_BLANK|_PUNCT|_ALPHA|_DIGIT));}
+extern inline int iswpunct(wint_t wc) {return (iswctype(wc,_PUNCT));}
+extern inline int iswspace(wint_t wc) {return (iswctype(wc,_SPACE));}
+extern inline int iswupper(wint_t wc) {return (iswctype(wc,_UPPER));}
+extern inline int iswxdigit(wint_t wc) {return (iswctype(wc,_HEX));}
+extern inline int isleadbyte(int c) {return (_pctype[(unsigned char)(c)] & _LEADBYTE);}
+#endif /* !(defined(__NO_CTYPE_INLINES) || defined(__WCTYPE_INLINES_DEFINED)) */
+
+
+typedef wchar_t wctrans_t;
+wint_t 		towctrans(wint_t, wctrans_t);
+wctrans_t	wctrans(const char*);
+wctype_t	wctype(const char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* Not RC_INVOKED */
+
+#endif	/* Not _WCTYPE_H_ */
+
diff --git a/tinyc/win32/include/winapi/basetsd.h b/tinyc/win32/include/winapi/basetsd.h
new file mode 100755
index 000000000..d9c375dd9
--- /dev/null
+++ b/tinyc/win32/include/winapi/basetsd.h
@@ -0,0 +1,119 @@
+#ifndef _BASETSD_H
+#define _BASETSD_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __GNUC__
+#ifndef __int64
+#define __int64 long long
+#endif
+#endif
+
+#if defined(_WIN64)
+#define __int3264   __int64
+#define ADDRESS_TAG_BIT 0x40000000000UI64
+#else /*  !_WIN64 */
+#define __int3264   __int32
+#define ADDRESS_TAG_BIT 0x80000000UL
+#define HandleToUlong( h ) ((ULONG)(ULONG_PTR)(h) )
+#define HandleToLong( h ) ((LONG)(LONG_PTR) (h) )
+#define LongToHandle( h) ((HANDLE)(LONG_PTR) (h))
+#define PtrToUlong( p ) ((ULONG)(ULONG_PTR) (p) )
+#define PtrToLong( p ) ((LONG)(LONG_PTR) (p) )
+#define PtrToUint( p ) ((UINT)(UINT_PTR) (p) )
+#define PtrToInt( p ) ((INT)(INT_PTR) (p) )
+#define PtrToUshort( p ) ((unsigned short)(ULONG_PTR)(p) )
+#define PtrToShort( p ) ((short)(LONG_PTR)(p) )
+#define IntToPtr( i )    ((VOID*)(INT_PTR)((int)i))
+#define UIntToPtr( ui )  ((VOID*)(UINT_PTR)((unsigned int)ui))
+#define LongToPtr( l )   ((VOID*)(LONG_PTR)((long)l))
+#define ULongToPtr( ul )  ((VOID*)(ULONG_PTR)((unsigned long)ul))
+#endif /* !_WIN64 */
+
+#define UlongToPtr(ul) ULongToPtr(ul)
+#define UintToPtr(ui) UIntToPtr(ui)
+#define MAXUINT_PTR  (~((UINT_PTR)0))
+#define MAXINT_PTR   ((INT_PTR)(MAXUINT_PTR >> 1))
+#define MININT_PTR   (~MAXINT_PTR)
+#define MAXULONG_PTR (~((ULONG_PTR)0))
+#define MAXLONG_PTR  ((LONG_PTR)(MAXULONG_PTR >> 1))
+#define MINLONG_PTR  (~MAXLONG_PTR)
+#define MAXUHALF_PTR ((UHALF_PTR)~0)
+#define MAXHALF_PTR  ((HALF_PTR)(MAXUHALF_PTR >> 1))
+#define MINHALF_PTR  (~MAXHALF_PTR)
+
+#ifndef RC_INVOKED
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef int LONG32, *PLONG32;
+#ifndef XFree86Server
+typedef int INT32, *PINT32;
+#endif /* ndef XFree86Server */
+typedef unsigned int ULONG32, *PULONG32;
+typedef unsigned int DWORD32, *PDWORD32;
+typedef unsigned int UINT32, *PUINT32;
+
+#if defined(_WIN64)
+typedef __int64 INT_PTR, *PINT_PTR;
+typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
+typedef __int64 LONG_PTR, *PLONG_PTR;
+typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
+typedef unsigned __int64 HANDLE_PTR;
+typedef unsigned int UHALF_PTR, *PUHALF_PTR;
+typedef int HALF_PTR, *PHALF_PTR;
+
+#if 0 /* TODO when WIN64 is here */
+inline unsigned long HandleToUlong(const void* h )
+    { return((unsigned long) h ); }
+inline long HandleToLong( const void* h )
+    { return((long) h ); }
+inline void* LongToHandle( const long h )
+    { return((void*) (INT_PTR) h ); }
+inline unsigned long PtrToUlong( const void* p)
+    { return((unsigned long) p ); }
+inline unsigned int PtrToUint( const void* p )
+    { return((unsigned int) p ); }
+inline unsigned short PtrToUshort( const void* p )
+    { return((unsigned short) p ); }
+inline long PtrToLong( const void* p )
+    { return((long) p ); }
+inline int PtrToInt( const void* p )
+    { return((int) p ); }
+inline short PtrToShort( const void* p )
+    { return((short) p ); }
+inline void* IntToPtr( const int i )
+    { return( (void*)(INT_PTR)i ); }
+inline void* UIntToPtr(const unsigned int ui)
+    { return( (void*)(UINT_PTR)ui ); }
+inline void* LongToPtr( const long l )
+    { return( (void*)(LONG_PTR)l ); }
+inline void* ULongToPtr( const unsigned long ul )
+    { return( (void*)(ULONG_PTR)ul ); }
+#endif /* 0_ */
+
+#else /*  !_WIN64 */
+typedef  int INT_PTR, *PINT_PTR;
+typedef  unsigned int UINT_PTR, *PUINT_PTR;
+typedef  long LONG_PTR, *PLONG_PTR;
+typedef  unsigned long ULONG_PTR, *PULONG_PTR;
+typedef unsigned short UHALF_PTR, *PUHALF_PTR;
+typedef short HALF_PTR, *PHALF_PTR;
+typedef unsigned long HANDLE_PTR;
+#endif /* !_WIN64 */
+
+typedef ULONG_PTR SIZE_T, *PSIZE_T;
+typedef LONG_PTR SSIZE_T, *PSSIZE_T;
+typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
+typedef __int64 LONG64, *PLONG64;
+typedef __int64 INT64,  *PINT64;
+typedef unsigned __int64 ULONG64, *PULONG64;
+typedef unsigned __int64 DWORD64, *PDWORD64;
+typedef unsigned __int64 UINT64,  *PUINT64;
+#ifdef __cplusplus
+}
+#endif
+#endif /* !RC_INVOKED */
+
+#endif /* _BASETSD_H */
diff --git a/tinyc/win32/include/winapi/basetyps.h b/tinyc/win32/include/winapi/basetyps.h
new file mode 100755
index 000000000..e1e36501b
--- /dev/null
+++ b/tinyc/win32/include/winapi/basetyps.h
@@ -0,0 +1,144 @@
+#ifndef _BASETYPS_H
+#define _BASETYPS_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifndef __OBJC__
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C extern
+#endif  /* __cplusplus */ 
+#define STDMETHODCALLTYPE	__stdcall
+#define STDMETHODVCALLTYPE	__cdecl
+#define STDAPICALLTYPE	__stdcall
+#define STDAPIVCALLTYPE	__cdecl
+#define STDAPI	EXTERN_C HRESULT STDAPICALLTYPE
+#define STDAPI_(t)	EXTERN_C t STDAPICALLTYPE
+#define STDMETHODIMP	HRESULT STDMETHODCALLTYPE
+#define STDMETHODIMP_(t)	t STDMETHODCALLTYPE
+#define STDAPIV	EXTERN_C HRESULT STDAPIVCALLTYPE
+#define STDAPIV_(t)	EXTERN_C t STDAPIVCALLTYPE
+#define STDMETHODIMPV	HRESULT STDMETHODVCALLTYPE
+#define STDMETHODIMPV_(t)	t STDMETHODVCALLTYPE
+#define interface	struct
+#if defined(__cplusplus) && !defined(CINTERFACE)
+#define STDMETHOD(m)	virtual HRESULT STDMETHODCALLTYPE m
+#define STDMETHOD_(t,m)	virtual t STDMETHODCALLTYPE m
+#define PURE	=0
+#define THIS_
+#define THIS	void
+/*
+ __attribute__((com_interface)) is obsolete in __GNUC__ >= 3
+ g++ vtables are now COM-compatible by default
+*/
+#if defined(__GNUC__) &&  __GNUC__ < 3 && !defined(NOCOMATTRIBUTE)
+#define DECLARE_INTERFACE(i) interface __attribute__((com_interface)) i
+#define DECLARE_INTERFACE_(i,b) interface __attribute__((com_interface)) i : public b
+#else
+#define DECLARE_INTERFACE(i) interface i
+#define DECLARE_INTERFACE_(i,b) interface i : public b
+#endif
+#else
+#define STDMETHOD(m)	HRESULT(STDMETHODCALLTYPE *m)
+#define STDMETHOD_(t,m)	t(STDMETHODCALLTYPE *m)
+#define PURE
+#define THIS_	INTERFACE *,
+#define THIS	INTERFACE *
+#ifndef CONST_VTABLE
+#define CONST_VTABLE
+#endif
+#define DECLARE_INTERFACE(i) \
+typedef interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; } i; \
+typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
+CONST_VTABLE struct i##Vtbl
+#define DECLARE_INTERFACE_(i,b) DECLARE_INTERFACE(i)
+#endif
+#define BEGIN_INTERFACE
+#define END_INTERFACE
+
+#define FWD_DECL(i) typedef interface i i
+#if defined(__cplusplus) && !defined(CINTERFACE)
+#define IENUM_THIS(T)
+#define IENUM_THIS_(T)
+#else
+#define IENUM_THIS(T) T*
+#define IENUM_THIS_(T) T*,
+#endif
+#define DECLARE_ENUMERATOR_(I,T) \
+DECLARE_INTERFACE_(I,IUnknown) \
+{ \
+	STDMETHOD(QueryInterface)(IENUM_THIS_(I) REFIID,PVOID*) PURE; \
+	STDMETHOD_(ULONG,AddRef)(IENUM_THIS(I)) PURE; \
+	STDMETHOD_(ULONG,Release)(IENUM_THIS(I)) PURE; \
+	STDMETHOD(Next)(IENUM_THIS_(I) ULONG,T*,ULONG*) PURE; \
+	STDMETHOD(Skip)(IENUM_THIS_(I) ULONG) PURE; \
+	STDMETHOD(Reset)(IENUM_THIS(I)) PURE; \
+	STDMETHOD(Clone)(IENUM_THIS_(I) I**) PURE; \
+}
+#define DECLARE_ENUMERATOR(T) DECLARE_ENUMERATOR_(IEnum##T,T)
+
+#endif /* __OBJC__ */
+
+#ifndef _GUID_DEFINED /* also defined in winnt.h */
+#define _GUID_DEFINED
+typedef struct _GUID
+{
+    unsigned long Data1;
+    unsigned short Data2;
+    unsigned short Data3;
+    unsigned char Data4[8];
+} GUID,*REFGUID,*LPGUID;
+#endif /* _GUID_DEFINED */
+#ifndef UUID_DEFINED
+#define UUID_DEFINED
+typedef GUID UUID;
+#endif /* UUID_DEFINED */
+typedef GUID IID;
+typedef GUID CLSID;
+typedef CLSID *LPCLSID;
+typedef IID *LPIID;
+typedef IID *REFIID;
+typedef CLSID *REFCLSID;
+typedef GUID FMTID;
+typedef FMTID *REFFMTID;
+typedef unsigned long error_status_t;
+#define uuid_t UUID
+typedef unsigned long PROPID;
+
+#ifndef _REFGUID_DEFINED
+#if defined (__cplusplus) && !defined (CINTERFACE)
+#define REFGUID const GUID&
+#define REFIID const IID&
+#define REFCLSID const CLSID&
+#else
+#define REFGUID const GUID* const
+#define REFIID const IID* const
+#define REFCLSID const CLSID* const
+#endif
+#define _REFGUID_DEFINED
+#define _REFGIID_DEFINED
+#define _REFCLSID_DEFINED
+#endif
+#ifndef GUID_SECTION
+#define GUID_SECTION ".text"
+#endif
+#ifdef __GNUC__
+#define GUID_SECT __attribute__ ((section (GUID_SECTION)))
+#else
+#define GUID_SECT
+#endif
+#if !defined(INITGUID) || (defined(INITGUID) && defined(__cplusplus))
+#define GUID_EXT EXTERN_C
+#else
+#define GUID_EXT
+#endif
+#ifdef INITGUID
+#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+#define DEFINE_OLEGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46)
+#else
+#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) GUID_EXT const GUID n
+#define DEFINE_OLEGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46)
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/winbase.h b/tinyc/win32/include/winapi/winbase.h
new file mode 100755
index 000000000..b3fab6c3d
--- /dev/null
+++ b/tinyc/win32/include/winapi/winbase.h
@@ -0,0 +1,1852 @@
+#ifndef _WINBASE_H
+#define _WINBASE_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#define WINBASEAPI DECLSPEC_IMPORT
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SP_SERIALCOMM 1
+#define PST_UNSPECIFIED	0
+#define PST_RS232	1
+#define PST_PARALLELPORT	2
+#define PST_RS422	3
+#define PST_RS423	4
+#define PST_RS449	5
+#define PST_MODEM	6
+#define PST_FAX	0x21
+#define PST_SCANNER	0x22
+#define PST_NETWORK_BRIDGE	0x100
+#define PST_LAT	0x101
+#define PST_TCPIP_TELNET	0x102
+#define PST_X25	0x103
+#define BAUD_075	1
+#define BAUD_110	2
+#define BAUD_134_5	4
+#define BAUD_150	8
+#define BAUD_300	16
+#define BAUD_600	32
+#define BAUD_1200	64
+#define BAUD_1800	128
+#define BAUD_2400	256
+#define BAUD_4800	512
+#define BAUD_7200	1024
+#define BAUD_9600	2048
+#define BAUD_14400	4096
+#define BAUD_19200	8192
+#define BAUD_38400	16384
+#define BAUD_56K	32768
+#define BAUD_128K	65536
+#define BAUD_115200	131072
+#define BAUD_57600	262144
+#define BAUD_USER	0x10000000
+#define PCF_DTRDSR	1
+#define PCF_RTSCTS	2
+#define PCF_RLSD	4
+#define PCF_PARITY_CHECK	8
+#define PCF_XONXOFF	16
+#define PCF_SETXCHAR	32
+#define PCF_TOTALTIMEOUTS	64
+#define PCF_INTTIMEOUTS	128
+#define PCF_SPECIALCHARS	256
+#define PCF_16BITMODE	512
+#define SP_PARITY	1
+#define SP_BAUD	2
+#define SP_DATABITS	4
+#define SP_STOPBITS	8
+#define SP_HANDSHAKING	16
+#define SP_PARITY_CHECK	32
+#define SP_RLSD	64
+#define DATABITS_5	1
+#define DATABITS_6	2
+#define DATABITS_7	4
+#define DATABITS_8	8
+#define DATABITS_16	16
+#define DATABITS_16X	32
+#define STOPBITS_10	1
+#define STOPBITS_15	2
+#define STOPBITS_20	4
+#define PARITY_NONE	256
+#define PARITY_ODD	512
+#define PARITY_EVEN	1024
+#define PARITY_MARK	2048
+#define PARITY_SPACE	4096
+#define EXCEPTION_DEBUG_EVENT	1
+#define CREATE_THREAD_DEBUG_EVENT	2
+#define CREATE_PROCESS_DEBUG_EVENT	3
+#define EXIT_THREAD_DEBUG_EVENT	4
+#define EXIT_PROCESS_DEBUG_EVENT	5
+#define LOAD_DLL_DEBUG_EVENT	6
+#define UNLOAD_DLL_DEBUG_EVENT	7
+#define OUTPUT_DEBUG_STRING_EVENT	8
+#define RIP_EVENT	9
+#define HFILE_ERROR ((HFILE)-1)
+#define FILE_BEGIN	0
+#define FILE_CURRENT	1
+#define FILE_END	2
+#define INVALID_SET_FILE_POINTER	((DWORD)-1)
+#define OF_READ 0
+#define OF_READWRITE	2
+#define OF_WRITE	1
+#define OF_SHARE_COMPAT	0
+#define OF_SHARE_DENY_NONE	64
+#define OF_SHARE_DENY_READ	48
+#define OF_SHARE_DENY_WRITE	32
+#define OF_SHARE_EXCLUSIVE	16
+#define OF_CANCEL	2048
+#define OF_CREATE	4096
+#define OF_DELETE	512
+#define OF_EXIST	16384
+#define OF_PARSE	256
+#define OF_PROMPT	8192
+#define OF_REOPEN	32768
+#define OF_VERIFY	1024
+#define NMPWAIT_NOWAIT	1
+#define NMPWAIT_WAIT_FOREVER	(-1)
+#define NMPWAIT_USE_DEFAULT_WAIT	0
+#define CE_BREAK	16
+#define CE_DNS	2048
+#define CE_FRAME	8
+#define CE_IOE	1024
+#define CE_MODE	32768
+#define CE_OOP	4096
+#define CE_OVERRUN	2
+#define CE_PTO	512
+#define CE_RXOVER	1
+#define CE_RXPARITY	4
+#define CE_TXFULL	256
+#define PROGRESS_CONTINUE	0
+#define PROGRESS_CANCEL	1
+#define PROGRESS_STOP	2
+#define PROGRESS_QUIET	3
+#define CALLBACK_CHUNK_FINISHED	0
+#define CALLBACK_STREAM_SWITCH	1
+#define COPY_FILE_FAIL_IF_EXISTS	1
+#define COPY_FILE_RESTARTABLE	2
+#define OFS_MAXPATHNAME 128
+#define DUPLICATE_CLOSE_SOURCE  1
+#define DUPLICATE_SAME_ACCESS   2
+#define FILE_MAP_ALL_ACCESS     0xf001f
+#define FILE_MAP_READ   4
+#define FILE_MAP_WRITE  2
+#define FILE_MAP_COPY   1
+#define MUTEX_ALL_ACCESS	0x1f0001
+#define MUTEX_MODIFY_STATE	1
+#define SEMAPHORE_ALL_ACCESS	0x1f0003
+#define SEMAPHORE_MODIFY_STATE	2
+#define EVENT_ALL_ACCESS	0x1f0003
+#define EVENT_MODIFY_STATE	2
+#define PIPE_ACCESS_DUPLEX      3
+#define PIPE_ACCESS_INBOUND     1
+#define PIPE_ACCESS_OUTBOUND    2
+#define PIPE_TYPE_BYTE	0
+#define PIPE_TYPE_MESSAGE	4
+#define PIPE_READMODE_BYTE	0
+#define PIPE_READMODE_MESSAGE	2
+#define PIPE_WAIT	0
+#define PIPE_NOWAIT	1
+#define PIPE_CLIENT_END 0
+#define PIPE_SERVER_END 1
+#define PIPE_UNLIMITED_INSTANCES 255
+#define CREATE_DEFAULT_ERROR_MODE	67108864
+#define DEBUG_PROCESS	1
+#define DEBUG_ONLY_THIS_PROCESS	2
+#define CREATE_SUSPENDED	4
+#define DETACHED_PROCESS	8
+#define CREATE_NEW_CONSOLE	16
+#define NORMAL_PRIORITY_CLASS	32
+#define IDLE_PRIORITY_CLASS	64
+#define HIGH_PRIORITY_CLASS	128
+#define REALTIME_PRIORITY_CLASS	256
+#define CREATE_NEW_PROCESS_GROUP	512
+#define CREATE_UNICODE_ENVIRONMENT	1024
+#define CREATE_SEPARATE_WOW_VDM	2048
+#define CREATE_SHARED_WOW_VDM 4096
+#define CREATE_FORCEDOS 8192
+#define CREATE_NO_WINDOW 0x8000000
+#define CONSOLE_TEXTMODE_BUFFER 1
+#define CREATE_NEW	1
+#define CREATE_ALWAYS	2
+#define OPEN_EXISTING	3
+#define OPEN_ALWAYS	4
+#define TRUNCATE_EXISTING	5
+#define FILE_FLAG_WRITE_THROUGH	0x80000000
+#define FILE_FLAG_OVERLAPPED	1073741824
+#define FILE_FLAG_NO_BUFFERING	536870912
+#define FILE_FLAG_RANDOM_ACCESS	268435456
+#define FILE_FLAG_SEQUENTIAL_SCAN	134217728
+#define FILE_FLAG_DELETE_ON_CLOSE	67108864
+#define FILE_FLAG_BACKUP_SEMANTICS	33554432
+#define FILE_FLAG_POSIX_SEMANTICS	16777216
+#define FILE_FLAG_OPEN_REPARSE_POINT	2097152
+#define FILE_FLAG_OPEN_NO_RECALL	1048576
+#define CLRDTR 6
+#define CLRRTS 4
+#define SETDTR 5
+#define SETRTS 3
+#define SETXOFF 1
+#define SETXON 2
+#define SETBREAK 8
+#define CLRBREAK 9
+#define STILL_ACTIVE 0x103
+#define FIND_FIRST_EX_CASE_SENSITIVE 1
+#define SCS_32BIT_BINARY 0
+#define SCS_DOS_BINARY 1
+#define SCS_OS216_BINARY 5
+#define SCS_PIF_BINARY 3
+#define SCS_POSIX_BINARY 4
+#define SCS_WOW_BINARY 2
+#define MAX_COMPUTERNAME_LENGTH 15
+#define HW_PROFILE_GUIDLEN	39
+#define MAX_PROFILE_LEN	80
+#define DOCKINFO_UNDOCKED	1
+#define DOCKINFO_DOCKED	2
+#define DOCKINFO_USER_SUPPLIED	4
+#define DOCKINFO_USER_UNDOCKED	(DOCKINFO_USER_SUPPLIED|DOCKINFO_UNDOCKED)
+#define DOCKINFO_USER_DOCKED	(DOCKINFO_USER_SUPPLIED|DOCKINFO_DOCKED)
+#define DRIVE_REMOVABLE 2
+#define DRIVE_FIXED 3
+#define DRIVE_REMOTE 4
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
+#define DRIVE_UNKNOWN 0
+#define DRIVE_NO_ROOT_DIR 1
+#define FILE_TYPE_UNKNOWN 0
+#define FILE_TYPE_DISK 1
+#define FILE_TYPE_CHAR 2
+#define FILE_TYPE_PIPE 3
+#define FILE_TYPE_REMOTE 0x8000
+#define HANDLE_FLAG_INHERIT 1
+#define HANDLE_FLAG_PROTECT_FROM_CLOSE 2
+#define STD_INPUT_HANDLE (DWORD)(0xfffffff6)
+#define STD_OUTPUT_HANDLE (DWORD)(0xfffffff5)
+#define STD_ERROR_HANDLE (DWORD)(0xfffffff4)
+#define INVALID_HANDLE_VALUE (HANDLE)(-1)
+#define GET_TAPE_MEDIA_INFORMATION 0
+#define GET_TAPE_DRIVE_INFORMATION 1
+#define SET_TAPE_MEDIA_INFORMATION 0
+#define SET_TAPE_DRIVE_INFORMATION 1
+#define THREAD_PRIORITY_ABOVE_NORMAL 1
+#define THREAD_PRIORITY_BELOW_NORMAL (-1)
+#define THREAD_PRIORITY_HIGHEST 2
+#define THREAD_PRIORITY_IDLE (-15)
+#define THREAD_PRIORITY_LOWEST (-2)
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_TIME_CRITICAL 15
+#define THREAD_PRIORITY_ERROR_RETURN 2147483647
+#define TIME_ZONE_ID_UNKNOWN 0
+#define TIME_ZONE_ID_STANDARD 1
+#define TIME_ZONE_ID_DAYLIGHT 2
+#define TIME_ZONE_ID_INVALID 0xFFFFFFFF
+#define FS_CASE_IS_PRESERVED 2
+#define FS_CASE_SENSITIVE 1
+#define FS_UNICODE_STORED_ON_DISK 4
+#define FS_PERSISTENT_ACLS 8
+#define FS_FILE_COMPRESSION 16
+#define FS_VOL_IS_COMPRESSED 32768
+#define GMEM_FIXED 0
+#define GMEM_MOVEABLE 2
+#define GMEM_MODIFY 128
+#define GPTR 64
+#define GHND 66
+#define GMEM_DDESHARE 8192
+#define GMEM_DISCARDABLE 256
+#define GMEM_LOWER 4096
+#define GMEM_NOCOMPACT 16
+#define GMEM_NODISCARD 32
+#define GMEM_NOT_BANKED 4096
+#define GMEM_NOTIFY 16384
+#define GMEM_SHARE 8192
+#define GMEM_ZEROINIT 64
+#define GMEM_DISCARDED 16384
+#define GMEM_INVALID_HANDLE 32768
+#define GMEM_LOCKCOUNT 255
+#define STATUS_WAIT_0 0
+#define STATUS_ABANDONED_WAIT_0 0x80
+#define STATUS_USER_APC 0xC0
+#define STATUS_TIMEOUT 0x102
+#define STATUS_PENDING 0x103
+#define STATUS_SEGMENT_NOTIFICATION 0x40000005
+#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
+#define STATUS_DATATYPE_MISALIGNMENT 0x80000002
+#define STATUS_BREAKPOINT 0x80000003
+#define STATUS_SINGLE_STEP 0x80000004
+#define STATUS_ACCESS_VIOLATION 0xC0000005
+#define STATUS_IN_PAGE_ERROR 0xC0000006
+#define STATUS_INVALID_HANDLE 0xC0000008L
+#define STATUS_NO_MEMORY 0xC0000017
+#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D
+#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
+#define STATUS_INVALID_DISPOSITION 0xC0000026
+#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C
+#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D
+#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E
+#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F
+#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090
+#define STATUS_FLOAT_OVERFLOW 0xC0000091
+#define STATUS_FLOAT_STACK_CHECK 0xC0000092
+#define STATUS_FLOAT_UNDERFLOW 0xC0000093
+#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
+#define STATUS_INTEGER_OVERFLOW 0xC0000095
+#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096
+#define STATUS_STACK_OVERFLOW 0xC00000FD
+#define STATUS_CONTROL_C_EXIT 0xC000013A
+#define EXCEPTION_ACCESS_VIOLATION	STATUS_ACCESS_VIOLATION
+#define EXCEPTION_DATATYPE_MISALIGNMENT	STATUS_DATATYPE_MISALIGNMENT
+#define EXCEPTION_BREAKPOINT	STATUS_BREAKPOINT
+#define EXCEPTION_SINGLE_STEP	STATUS_SINGLE_STEP
+#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED	STATUS_ARRAY_BOUNDS_EXCEEDED
+#define EXCEPTION_FLT_DENORMAL_OPERAND	STATUS_FLOAT_DENORMAL_OPERAND
+#define EXCEPTION_FLT_DIVIDE_BY_ZERO	STATUS_FLOAT_DIVIDE_BY_ZERO
+#define EXCEPTION_FLT_INEXACT_RESULT	STATUS_FLOAT_INEXACT_RESULT
+#define EXCEPTION_FLT_INVALID_OPERATION	STATUS_FLOAT_INVALID_OPERATION
+#define EXCEPTION_FLT_OVERFLOW	STATUS_FLOAT_OVERFLOW
+#define EXCEPTION_FLT_STACK_CHECK	STATUS_FLOAT_STACK_CHECK
+#define EXCEPTION_FLT_UNDERFLOW	STATUS_FLOAT_UNDERFLOW
+#define EXCEPTION_INT_DIVIDE_BY_ZERO	STATUS_INTEGER_DIVIDE_BY_ZERO
+#define EXCEPTION_INT_OVERFLOW	STATUS_INTEGER_OVERFLOW
+#define EXCEPTION_PRIV_INSTRUCTION	STATUS_PRIVILEGED_INSTRUCTION
+#define EXCEPTION_IN_PAGE_ERROR	STATUS_IN_PAGE_ERROR
+#define EXCEPTION_ILLEGAL_INSTRUCTION	STATUS_ILLEGAL_INSTRUCTION
+#define EXCEPTION_NONCONTINUABLE_EXCEPTION	STATUS_NONCONTINUABLE_EXCEPTION
+#define EXCEPTION_STACK_OVERFLOW	STATUS_STACK_OVERFLOW
+#define EXCEPTION_INVALID_DISPOSITION	STATUS_INVALID_DISPOSITION
+#define EXCEPTION_GUARD_PAGE	STATUS_GUARD_PAGE_VIOLATION
+#define EXCEPTION_INVALID_HANDLE	STATUS_INVALID_HANDLE
+#define CONTROL_C_EXIT	STATUS_CONTROL_C_EXIT
+#define PROCESS_HEAP_REGION 1
+#define PROCESS_HEAP_UNCOMMITTED_RANGE 2
+#define PROCESS_HEAP_ENTRY_BUSY 4
+#define PROCESS_HEAP_ENTRY_MOVEABLE 16
+#define PROCESS_HEAP_ENTRY_DDESHARE 32
+#define DONT_RESOLVE_DLL_REFERENCES 1
+#define LOAD_LIBRARY_AS_DATAFILE 2
+#define LOAD_WITH_ALTERED_SEARCH_PATH 8
+#define LMEM_FIXED 0
+#define LMEM_MOVEABLE 2
+#define LMEM_NONZEROLHND 2
+#define LMEM_NONZEROLPTR 0
+#define LMEM_DISCARDABLE 3840
+#define LMEM_NOCOMPACT 16
+#define LMEM_NODISCARD 32
+#define LMEM_ZEROINIT 64
+#define LMEM_DISCARDED 16384
+#define LMEM_MODIFY 128
+#define LMEM_INVALID_HANDLE 32768
+#define LMEM_LOCKCOUNT 255
+#define LPTR 64
+#define LHND 66
+#define NONZEROLHND 2
+#define NONZEROLPTR 0
+#define LOCKFILE_FAIL_IMMEDIATELY 1
+#define LOCKFILE_EXCLUSIVE_LOCK 2
+#define LOGON32_PROVIDER_DEFAULT	0
+#define LOGON32_PROVIDER_WINNT35	1
+#define LOGON32_LOGON_INTERACTIVE	2
+#define LOGON32_LOGON_BATCH	4
+#define LOGON32_LOGON_SERVICE	5
+#define MOVEFILE_REPLACE_EXISTING 1
+#define MOVEFILE_COPY_ALLOWED 2
+#define MOVEFILE_DELAY_UNTIL_REBOOT 4
+#define MOVEFILE_WRITE_THROUGH 8
+#define MAXIMUM_WAIT_OBJECTS 64
+#define MAXIMUM_SUSPEND_COUNT 0x7F
+#define WAIT_OBJECT_0 0
+#define WAIT_ABANDONED_0 128
+#define WAIT_TIMEOUT 0x102
+#define WAIT_IO_COMPLETION 0xC0
+#define WAIT_ABANDONED 128
+#define WAIT_FAILED 0xFFFFFFFF
+#define PURGE_TXABORT 1
+#define PURGE_RXABORT 2
+#define PURGE_TXCLEAR 4
+#define PURGE_RXCLEAR 8
+#define EVENTLOG_FORWARDS_READ 4
+#define EVENTLOG_BACKWARDS_READ 8
+#define EVENTLOG_SEEK_READ 2
+#define EVENTLOG_SEQUENTIAL_READ 1
+#define EVENTLOG_ERROR_TYPE 1
+#define EVENTLOG_WARNING_TYPE 2
+#define EVENTLOG_INFORMATION_TYPE 4
+#define EVENTLOG_AUDIT_SUCCESS 8
+#define EVENTLOG_AUDIT_FAILURE 16
+#define FORMAT_MESSAGE_ALLOCATE_BUFFER 256
+#define FORMAT_MESSAGE_IGNORE_INSERTS 512
+#define FORMAT_MESSAGE_FROM_STRING 1024
+#define FORMAT_MESSAGE_FROM_HMODULE 2048
+#define FORMAT_MESSAGE_FROM_SYSTEM 4096
+#define FORMAT_MESSAGE_ARGUMENT_ARRAY 8192
+#define FORMAT_MESSAGE_MAX_WIDTH_MASK 255
+#define EV_BREAK 64
+#define EV_CTS 8
+#define EV_DSR 16
+#define EV_ERR 128
+#define EV_EVENT1 2048
+#define EV_EVENT2 4096
+#define EV_PERR 512
+#define EV_RING 256
+#define EV_RLSD 32
+#define EV_RX80FULL 1024
+#define EV_RXCHAR 1
+#define EV_RXFLAG 2
+#define EV_TXEMPTY 4
+#define SEM_FAILCRITICALERRORS 1
+#define SEM_NOALIGNMENTFAULTEXCEPT 4
+#define SEM_NOGPFAULTERRORBOX 2
+#define SEM_NOOPENFILEERRORBOX 32768
+#define SLE_ERROR 1
+#define SLE_MINORERROR 2
+#define SLE_WARNING 3
+#define SHUTDOWN_NORETRY 1
+#define EXCEPTION_EXECUTE_HANDLER 1
+#define EXCEPTION_CONTINUE_EXECUTION (-1)
+#define EXCEPTION_CONTINUE_SEARCH 0
+#define MAXINTATOM 0xC000
+#define INVALID_ATOM ((ATOM)0)
+#define IGNORE	0
+#define INFINITE	0xFFFFFFFF
+#define NOPARITY	0
+#define ODDPARITY	1
+#define EVENPARITY	2
+#define MARKPARITY	3
+#define SPACEPARITY	4
+#define ONESTOPBIT	0
+#define ONE5STOPBITS	1
+#define TWOSTOPBITS	2
+#define CBR_110	110
+#define CBR_300	300
+#define CBR_600	600
+#define CBR_1200	1200
+#define CBR_2400	2400
+#define CBR_4800	4800
+#define CBR_9600	9600
+#define CBR_14400	14400
+#define CBR_19200	19200
+#define CBR_38400	38400
+#define CBR_56000	56000
+#define CBR_57600	57600
+#define CBR_115200	115200
+#define CBR_128000	128000
+#define CBR_256000	256000
+#define BACKUP_INVALID	0
+#define BACKUP_DATA 1
+#define BACKUP_EA_DATA 2
+#define BACKUP_SECURITY_DATA 3
+#define BACKUP_ALTERNATE_DATA 4
+#define BACKUP_LINK 5
+#define BACKUP_PROPERTY_DATA 6
+#define BACKUP_OBJECT_ID 7
+#define BACKUP_REPARSE_DATA 8
+#define BACKUP_SPARSE_BLOCK 9
+#define STREAM_NORMAL_ATTRIBUTE 0
+#define STREAM_MODIFIED_WHEN_READ 1
+#define STREAM_CONTAINS_SECURITY 2
+#define STREAM_CONTAINS_PROPERTIES 4
+#define STARTF_USESHOWWINDOW 1
+#define STARTF_USESIZE 2
+#define STARTF_USEPOSITION 4
+#define STARTF_USECOUNTCHARS 8
+#define STARTF_USEFILLATTRIBUTE 16
+#define STARTF_RUNFULLSCREEN 32
+#define STARTF_FORCEONFEEDBACK 64
+#define STARTF_FORCEOFFFEEDBACK 128
+#define STARTF_USESTDHANDLES 256
+#define STARTF_USEHOTKEY 512
+#define TC_NORMAL 0
+#define TC_HARDERR 1
+#define TC_GP_TRAP 2
+#define TC_SIGNAL 3
+#define AC_LINE_OFFLINE 0
+#define AC_LINE_ONLINE 1
+#define AC_LINE_BACKUP_POWER 2
+#define AC_LINE_UNKNOWN 255
+#define BATTERY_FLAG_HIGH 1
+#define BATTERY_FLAG_LOW 2
+#define BATTERY_FLAG_CRITICAL 4
+#define BATTERY_FLAG_CHARGING 8
+#define BATTERY_FLAG_NO_BATTERY 128
+#define BATTERY_FLAG_UNKNOWN 255
+#define BATTERY_PERCENTAGE_UNKNOWN 255
+#define BATTERY_LIFE_UNKNOWN 0xFFFFFFFF
+#define DDD_RAW_TARGET_PATH 1
+#define DDD_REMOVE_DEFINITION 2
+#define DDD_EXACT_MATCH_ON_REMOVE 4
+#define HINSTANCE_ERROR 32
+#define MS_CTS_ON 16
+#define MS_DSR_ON 32
+#define MS_RING_ON 64
+#define MS_RLSD_ON 128
+#define PROFILE_USER 0x10000000
+#define PROFILE_KERNEL 0x20000000
+#define PROFILE_SERVER 0x40000000
+#define DTR_CONTROL_DISABLE 0
+#define DTR_CONTROL_ENABLE 1
+#define DTR_CONTROL_HANDSHAKE 2
+#define RTS_CONTROL_DISABLE 0
+#define RTS_CONTROL_ENABLE 1
+#define RTS_CONTROL_HANDSHAKE 2
+#define RTS_CONTROL_TOGGLE 3
+#define SECURITY_ANONYMOUS (SecurityAnonymous<<16)
+#define SECURITY_IDENTIFICATION (SecurityIdentification<<16)
+#define SECURITY_IMPERSONATION (SecurityImpersonation<<16)
+#define SECURITY_DELEGATION (SecurityDelegation<<16)
+#define SECURITY_CONTEXT_TRACKING 0x40000
+#define SECURITY_EFFECTIVE_ONLY 0x80000
+#define SECURITY_SQOS_PRESENT 0x100000
+#define SECURITY_VALID_SQOS_FLAGS 0x1F0000
+#define INVALID_FILE_SIZE 0xFFFFFFFF
+#define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
+
+#ifndef RC_INVOKED
+typedef struct _FILETIME {
+	DWORD dwLowDateTime;
+	DWORD dwHighDateTime;
+} FILETIME,*PFILETIME,*LPFILETIME;
+typedef struct _BY_HANDLE_FILE_INFORMATION {
+	DWORD	dwFileAttributes;
+	FILETIME	ftCreationTime;
+	FILETIME	ftLastAccessTime;
+	FILETIME	ftLastWriteTime;
+	DWORD	dwVolumeSerialNumber;
+	DWORD	nFileSizeHigh;
+	DWORD	nFileSizeLow;
+	DWORD	nNumberOfLinks;
+	DWORD	nFileIndexHigh;
+	DWORD	nFileIndexLow;
+} BY_HANDLE_FILE_INFORMATION,*LPBY_HANDLE_FILE_INFORMATION;
+typedef struct _DCB {
+	DWORD DCBlength;
+	DWORD BaudRate;
+	DWORD fBinary:1;
+	DWORD fParity:1;
+	DWORD fOutxCtsFlow:1;
+	DWORD fOutxDsrFlow:1;
+	DWORD fDtrControl:2;
+	DWORD fDsrSensitivity:1;
+	DWORD fTXContinueOnXoff:1;
+	DWORD fOutX:1;
+	DWORD fInX:1;
+	DWORD fErrorChar:1;
+	DWORD fNull:1;
+	DWORD fRtsControl:2;
+	DWORD fAbortOnError:1;
+	DWORD fDummy2:17;
+	WORD wReserved;
+	WORD XonLim;
+	WORD XoffLim;
+	BYTE ByteSize;
+	BYTE Parity;
+	BYTE StopBits;
+	char XonChar;
+	char XoffChar;
+	char ErrorChar;
+	char EofChar;
+	char EvtChar;
+	WORD wReserved1;
+} DCB,*LPDCB;
+typedef struct _COMM_CONFIG {
+	DWORD dwSize;
+	WORD  wVersion;
+	WORD  wReserved;
+	DCB   dcb;
+	DWORD dwProviderSubType;
+	DWORD dwProviderOffset;
+	DWORD dwProviderSize;
+	WCHAR wcProviderData[1];
+} COMMCONFIG,*LPCOMMCONFIG;
+typedef struct _COMMPROP {
+	WORD	wPacketLength;
+	WORD	wPacketVersion;
+	DWORD	dwServiceMask;
+	DWORD	dwReserved1;
+	DWORD	dwMaxTxQueue;
+	DWORD	dwMaxRxQueue;
+	DWORD	dwMaxBaud;
+	DWORD	dwProvSubType;
+	DWORD	dwProvCapabilities;
+	DWORD	dwSettableParams;
+	DWORD	dwSettableBaud;
+	WORD	wSettableData;
+	WORD	wSettableStopParity;
+	DWORD	dwCurrentTxQueue;
+	DWORD	dwCurrentRxQueue;
+	DWORD	dwProvSpec1;
+	DWORD	dwProvSpec2;
+	WCHAR	wcProvChar[1];
+} COMMPROP,*LPCOMMPROP;
+typedef struct _COMMTIMEOUTS {
+	DWORD ReadIntervalTimeout;
+	DWORD ReadTotalTimeoutMultiplier;
+	DWORD ReadTotalTimeoutConstant;
+	DWORD WriteTotalTimeoutMultiplier;
+	DWORD WriteTotalTimeoutConstant;
+} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
+typedef struct _COMSTAT {
+	DWORD fCtsHold:1;
+	DWORD fDsrHold:1;
+	DWORD fRlsdHold:1;
+	DWORD fXoffHold:1;
+	DWORD fXoffSent:1;
+	DWORD fEof:1;
+	DWORD fTxim:1;
+	DWORD fReserved:25;
+	DWORD cbInQue;
+	DWORD cbOutQue;
+} COMSTAT,*LPCOMSTAT;
+typedef DWORD (WINAPI *LPTHREAD_START_ROUTINE)(LPVOID);
+typedef struct _CREATE_PROCESS_DEBUG_INFO {
+	HANDLE hFile;
+	HANDLE hProcess;
+	HANDLE hThread;
+	LPVOID lpBaseOfImage;
+	DWORD dwDebugInfoFileOffset;
+	DWORD nDebugInfoSize;
+	LPVOID lpThreadLocalBase;
+	LPTHREAD_START_ROUTINE lpStartAddress;
+	LPVOID lpImageName;
+	WORD fUnicode;
+} CREATE_PROCESS_DEBUG_INFO,*LPCREATE_PROCESS_DEBUG_INFO;
+typedef struct _CREATE_THREAD_DEBUG_INFO {
+	HANDLE hThread;
+	LPVOID lpThreadLocalBase;
+	LPTHREAD_START_ROUTINE lpStartAddress;
+} CREATE_THREAD_DEBUG_INFO,*LPCREATE_THREAD_DEBUG_INFO;
+typedef struct _EXCEPTION_DEBUG_INFO {
+	EXCEPTION_RECORD ExceptionRecord;
+	DWORD dwFirstChance;
+} EXCEPTION_DEBUG_INFO,*LPEXCEPTION_DEBUG_INFO;
+typedef struct _EXIT_THREAD_DEBUG_INFO {
+	DWORD dwExitCode;
+} EXIT_THREAD_DEBUG_INFO,*LPEXIT_THREAD_DEBUG_INFO;
+typedef struct _EXIT_PROCESS_DEBUG_INFO {
+	DWORD dwExitCode;
+} EXIT_PROCESS_DEBUG_INFO,*LPEXIT_PROCESS_DEBUG_INFO;
+typedef struct _LOAD_DLL_DEBUG_INFO {
+	HANDLE hFile;
+	LPVOID lpBaseOfDll;
+	DWORD dwDebugInfoFileOffset;
+	DWORD nDebugInfoSize;
+	LPVOID lpImageName;
+	WORD fUnicode;
+} LOAD_DLL_DEBUG_INFO,*LPLOAD_DLL_DEBUG_INFO;
+typedef struct _UNLOAD_DLL_DEBUG_INFO {
+	LPVOID lpBaseOfDll;
+} UNLOAD_DLL_DEBUG_INFO,*LPUNLOAD_DLL_DEBUG_INFO;
+typedef struct _OUTPUT_DEBUG_STRING_INFO {
+	LPSTR lpDebugStringData;
+	WORD fUnicode;
+	WORD nDebugStringLength;
+} OUTPUT_DEBUG_STRING_INFO,*LPOUTPUT_DEBUG_STRING_INFO;
+typedef struct _RIP_INFO {
+	DWORD dwError;
+	DWORD dwType;
+} RIP_INFO,*LPRIP_INFO;
+typedef struct _DEBUG_EVENT {
+	DWORD dwDebugEventCode;
+	DWORD dwProcessId;
+	DWORD dwThreadId;
+	union {
+		EXCEPTION_DEBUG_INFO Exception;
+		CREATE_THREAD_DEBUG_INFO CreateThread;
+		CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
+		EXIT_THREAD_DEBUG_INFO ExitThread;
+		EXIT_PROCESS_DEBUG_INFO ExitProcess;
+		LOAD_DLL_DEBUG_INFO LoadDll;
+		UNLOAD_DLL_DEBUG_INFO UnloadDll;
+		OUTPUT_DEBUG_STRING_INFO DebugString;
+		RIP_INFO RipInfo;
+	} u;
+} DEBUG_EVENT,*LPDEBUG_EVENT;
+typedef struct _OVERLAPPED {
+	DWORD Internal;
+	DWORD InternalHigh;
+	DWORD Offset;
+	DWORD OffsetHigh;
+	HANDLE hEvent;
+} OVERLAPPED,*POVERLAPPED,*LPOVERLAPPED;
+typedef struct _STARTUPINFOA {
+	DWORD	cb;
+	LPSTR	lpReserved;
+	LPSTR	lpDesktop;
+	LPSTR	lpTitle;
+	DWORD	dwX;
+	DWORD	dwY;
+	DWORD	dwXSize;
+	DWORD	dwYSize;
+	DWORD	dwXCountChars;
+	DWORD	dwYCountChars;
+	DWORD	dwFillAttribute;
+	DWORD	dwFlags;
+	WORD	wShowWindow;
+	WORD	cbReserved2;
+	PBYTE	lpReserved2;
+	HANDLE	hStdInput;
+	HANDLE	hStdOutput;
+	HANDLE	hStdError;
+} STARTUPINFOA,*LPSTARTUPINFOA;
+typedef struct _STARTUPINFOW {
+	DWORD	cb;
+	LPWSTR	lpReserved;
+	LPWSTR	lpDesktop;
+	LPWSTR	lpTitle;
+	DWORD	dwX;
+	DWORD	dwY;
+	DWORD	dwXSize;
+	DWORD	dwYSize;
+	DWORD	dwXCountChars;
+	DWORD	dwYCountChars;
+	DWORD	dwFillAttribute;
+	DWORD	dwFlags;
+	WORD	wShowWindow;
+	WORD	cbReserved2;
+	PBYTE	lpReserved2;
+	HANDLE	hStdInput;
+	HANDLE	hStdOutput;
+	HANDLE	hStdError;
+} STARTUPINFOW,*LPSTARTUPINFOW;
+typedef struct _PROCESS_INFORMATION {
+	HANDLE hProcess;
+	HANDLE hThread;
+	DWORD dwProcessId;
+	DWORD dwThreadId;
+} PROCESS_INFORMATION,*LPPROCESS_INFORMATION;
+typedef struct _CRITICAL_SECTION_DEBUG {
+	WORD Type;
+	WORD CreatorBackTraceIndex;
+	struct _CRITICAL_SECTION *CriticalSection;
+	LIST_ENTRY ProcessLocksList;
+	DWORD EntryCount;
+	DWORD ContentionCount;
+	DWORD Spare [2];
+} CRITICAL_SECTION_DEBUG,*PCRITICAL_SECTION_DEBUG;
+typedef struct _CRITICAL_SECTION {
+	PCRITICAL_SECTION_DEBUG DebugInfo;
+	LONG LockCount;
+	LONG RecursionCount;
+	HANDLE OwningThread;
+	HANDLE LockSemaphore;
+	DWORD SpinCount;
+} CRITICAL_SECTION,*PCRITICAL_SECTION,*LPCRITICAL_SECTION;
+typedef struct _SYSTEMTIME {
+	WORD wYear;
+	WORD wMonth;
+	WORD wDayOfWeek;
+	WORD wDay;
+	WORD wHour;
+	WORD wMinute;
+	WORD wSecond;
+	WORD wMilliseconds;
+} SYSTEMTIME,*LPSYSTEMTIME;
+typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
+	DWORD	dwFileAttributes;
+	FILETIME	ftCreationTime;
+	FILETIME	ftLastAccessTime;
+	FILETIME	ftLastWriteTime;
+	DWORD	nFileSizeHigh;
+	DWORD	nFileSizeLow;
+} WIN32_FILE_ATTRIBUTE_DATA,*LPWIN32_FILE_ATTRIBUTE_DATA;
+typedef struct _WIN32_FIND_DATAA {
+	DWORD dwFileAttributes;
+	FILETIME ftCreationTime;
+	FILETIME ftLastAccessTime;
+	FILETIME ftLastWriteTime;
+	DWORD nFileSizeHigh;
+	DWORD nFileSizeLow;
+	DWORD dwReserved0;
+	DWORD dwReserved1;
+	CHAR cFileName[MAX_PATH];
+	CHAR cAlternateFileName[14];
+} WIN32_FIND_DATAA,*LPWIN32_FIND_DATAA;
+typedef struct _WIN32_FIND_DATAW {
+	DWORD dwFileAttributes;
+	FILETIME ftCreationTime;
+	FILETIME ftLastAccessTime;
+	FILETIME ftLastWriteTime;
+	DWORD nFileSizeHigh;
+	DWORD nFileSizeLow;
+	DWORD dwReserved0;
+	DWORD dwReserved1;
+	WCHAR cFileName[MAX_PATH];
+	WCHAR cAlternateFileName[14];
+} WIN32_FIND_DATAW,*LPWIN32_FIND_DATAW;
+typedef struct _WIN32_STREAM_ID {
+	DWORD dwStreamId;
+	DWORD dwStreamAttributes;
+	LARGE_INTEGER Size;
+	DWORD dwStreamNameSize;
+	WCHAR cStreamName[ANYSIZE_ARRAY];
+} WIN32_STREAM_ID;
+typedef enum _FINDEX_INFO_LEVELS {
+	FindExInfoStandard,
+	FindExInfoMaxInfoLevel
+} FINDEX_INFO_LEVELS;
+typedef enum _FINDEX_SEARCH_OPS {
+	FindExSearchNameMatch,
+	FindExSearchLimitToDirectories,
+	FindExSearchLimitToDevices,
+	FindExSearchMaxSearchOp
+} FINDEX_SEARCH_OPS;
+typedef enum _ACL_INFORMATION_CLASS {
+	AclRevisionInformation=1,
+	AclSizeInformation
+} ACL_INFORMATION_CLASS;
+typedef struct tagHW_PROFILE_INFOA {
+	DWORD dwDockInfo;
+	CHAR szHwProfileGuid[HW_PROFILE_GUIDLEN];
+	CHAR szHwProfileName[MAX_PROFILE_LEN];
+} HW_PROFILE_INFOA,*LPHW_PROFILE_INFOA;
+typedef struct tagHW_PROFILE_INFOW {
+	DWORD dwDockInfo;
+	WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN];
+	WCHAR szHwProfileName[MAX_PROFILE_LEN];
+} HW_PROFILE_INFOW,*LPHW_PROFILE_INFOW;
+typedef enum _GET_FILEEX_INFO_LEVELS {
+	GetFileExInfoStandard,
+	GetFileExMaxInfoLevel
+} GET_FILEEX_INFO_LEVELS;
+typedef struct _SYSTEM_INFO {
+	_ANONYMOUS_UNION union {
+		DWORD dwOemId;
+		_ANONYMOUS_STRUCT struct {
+			WORD wProcessorArchitecture;
+			WORD wReserved;
+		} DUMMYSTRUCTNAME;
+	} DUMMYUNIONNAME;
+	DWORD dwPageSize;
+	PVOID lpMinimumApplicationAddress;
+	PVOID lpMaximumApplicationAddress;
+	DWORD dwActiveProcessorMask;
+	DWORD dwNumberOfProcessors;
+	DWORD dwProcessorType;
+	DWORD dwAllocationGranularity;
+	WORD wProcessorLevel;
+	WORD wProcessorRevision;
+} SYSTEM_INFO,*LPSYSTEM_INFO;
+typedef struct _SYSTEM_POWER_STATUS {
+	BYTE ACLineStatus;
+	BYTE BatteryFlag;
+	BYTE BatteryLifePercent;
+	BYTE Reserved1;
+	DWORD BatteryLifeTime;
+	DWORD BatteryFullLifeTime;
+} SYSTEM_POWER_STATUS,*LPSYSTEM_POWER_STATUS;
+typedef struct _TIME_ZONE_INFORMATION {
+	LONG Bias;
+	WCHAR StandardName[32];
+	SYSTEMTIME StandardDate;
+	LONG StandardBias;
+	WCHAR DaylightName[32];
+	SYSTEMTIME DaylightDate;
+	LONG DaylightBias;
+} TIME_ZONE_INFORMATION,*LPTIME_ZONE_INFORMATION;
+typedef struct _MEMORYSTATUS {
+	DWORD dwLength;
+	DWORD dwMemoryLoad;
+	DWORD dwTotalPhys;
+	DWORD dwAvailPhys;
+	DWORD dwTotalPageFile;
+	DWORD dwAvailPageFile;
+	DWORD dwTotalVirtual;
+	DWORD dwAvailVirtual;
+} MEMORYSTATUS,*LPMEMORYSTATUS;
+typedef struct _LDT_ENTRY {
+	WORD LimitLow;
+	WORD BaseLow;
+	union {
+		struct {
+			BYTE BaseMid;
+			BYTE Flags1;
+			BYTE Flags2;
+			BYTE BaseHi;
+		} Bytes;
+		struct {
+			DWORD BaseMid:8;
+			DWORD Type:5;
+			DWORD Dpl:2;
+			DWORD Pres:1;
+			DWORD LimitHi:4;
+			DWORD Sys:1;
+			DWORD Reserved_0:1;
+			DWORD Default_Big:1;
+			DWORD Granularity:1;
+			DWORD BaseHi:8;
+		} Bits;
+	} HighWord;
+} LDT_ENTRY,*PLDT_ENTRY,*LPLDT_ENTRY;
+typedef struct _PROCESS_HEAP_ENTRY {
+	PVOID lpData;
+	DWORD cbData;
+	BYTE cbOverhead;
+	BYTE iRegionIndex;
+	WORD wFlags;
+	_ANONYMOUS_UNION union {
+		struct {
+			HANDLE hMem;
+			DWORD dwReserved[3];
+		} Block;
+		struct {
+			DWORD dwCommittedSize;
+			DWORD dwUnCommittedSize;
+			LPVOID lpFirstBlock;
+			LPVOID lpLastBlock;
+		} Region;
+	} DUMMYUNIONNAME;
+} PROCESS_HEAP_ENTRY,*LPPROCESS_HEAP_ENTRY;
+typedef struct _OFSTRUCT {
+	BYTE cBytes;
+	BYTE fFixedDisk;
+	WORD nErrCode;
+	WORD Reserved1;
+	WORD Reserved2;
+	CHAR szPathName[OFS_MAXPATHNAME];
+} OFSTRUCT,*LPOFSTRUCT,*POFSTRUCT;
+typedef struct _WIN_CERTIFICATE {
+      DWORD dwLength;
+      WORD wRevision;
+      WORD wCertificateType;
+      BYTE bCertificate[1];
+} WIN_CERTIFICATE, *LPWIN_CERTIFICATE;
+
+typedef DWORD(WINAPI *LPPROGRESS_ROUTINE)(LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,LARGE_INTEGER,DWORD,DWORD,HANDLE,HANDLE,LPVOID);
+typedef void(WINAPI *LPFIBER_START_ROUTINE)(PVOID);
+typedef BOOL(CALLBACK *ENUMRESLANGPROC)(HMODULE,LPCTSTR,LPCTSTR,WORD,LONG);
+typedef BOOL(CALLBACK *ENUMRESNAMEPROC)(HMODULE,LPCTSTR,LPTSTR,LONG);
+typedef BOOL(CALLBACK *ENUMRESTYPEPROC)(HMODULE,LPTSTR,LONG);
+typedef void(CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPOVERLAPPED);
+typedef LONG(CALLBACK *PTOP_LEVEL_EXCEPTION_FILTER)(LPEXCEPTION_POINTERS);
+typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
+typedef void(APIENTRY *PAPCFUNC)(DWORD);
+typedef void(CALLBACK *PTIMERAPCROUTINE)(PVOID,DWORD,DWORD);
+#define MAKEINTATOM(i) (LPTSTR)((DWORD)((WORD)(i)))
+/* Functions */
+#ifndef UNDER_CE
+int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPSTR,int);
+#else
+int APIENTRY WinMain(HINSTANCE,HINSTANCE,LPWSTR,int);
+#endif
+int APIENTRY wWinMain(HINSTANCE,HINSTANCE,LPWSTR,int);
+long WINAPI _hread(HFILE,LPVOID,long);
+long WINAPI _hwrite(HFILE,LPCSTR,long);
+HFILE WINAPI _lclose(HFILE);
+HFILE WINAPI _lcreat(LPCSTR,int);
+LONG WINAPI _llseek(HFILE,LONG,int);
+HFILE WINAPI _lopen(LPCSTR,int);
+UINT WINAPI _lread(HFILE,LPVOID,UINT);
+UINT WINAPI _lwrite(HFILE,LPCSTR,UINT);
+#define AbnormalTermination() FALSE
+BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,PDWORD,PDWORD,PBOOL);
+BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR,LPVOID,LPSTR,LPSTR,PSECURITY_DESCRIPTOR,DWORD,PGENERIC_MAPPING,BOOL,PDWORD,PBOOL,PBOOL);
+BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR,LPVOID,LPWSTR,LPWSTR,PSECURITY_DESCRIPTOR,DWORD,PGENERIC_MAPPING,BOOL,PDWORD,PBOOL,PBOOL);
+BOOL WINAPI AddAccessAllowedAce(PACL,DWORD,DWORD,PSID);
+BOOL WINAPI AddAccessDeniedAce(PACL,DWORD,DWORD,PSID);
+BOOL WINAPI AddAce(PACL,DWORD,DWORD,PVOID,DWORD);
+ATOM WINAPI AddAtomA(LPCSTR);
+ATOM WINAPI AddAtomW(LPCWSTR);
+BOOL WINAPI AddAuditAccessAce(PACL,DWORD,DWORD,PSID,BOOL,BOOL);
+BOOL WINAPI AdjustTokenGroups(HANDLE,BOOL,PTOKEN_GROUPS,DWORD,PTOKEN_GROUPS,PDWORD);
+BOOL WINAPI AdjustTokenPrivileges(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
+BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID*);
+BOOL WINAPI AllocateLocallyUniqueId(PLUID);
+BOOL WINAPI AreAllAccessesGranted(DWORD,DWORD);
+BOOL WINAPI AreAnyAccessesGranted(DWORD,DWORD);
+BOOL WINAPI AreFileApisANSI(void);
+BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR);
+BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR);
+BOOL WINAPI BackupRead(HANDLE,PBYTE,DWORD,PDWORD,BOOL,BOOL,PVOID);
+BOOL WINAPI BackupSeek(HANDLE,DWORD,DWORD,PDWORD,PDWORD,PVOID);
+BOOL WINAPI BackupWrite(HANDLE,PBYTE,DWORD,PDWORD,BOOL,BOOL,PVOID);
+BOOL WINAPI Beep(DWORD,DWORD);
+HANDLE WINAPI BeginUpdateResourceA(LPCSTR,BOOL);
+HANDLE WINAPI BeginUpdateResourceW(LPCWSTR,BOOL);
+BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB);
+BOOL WINAPI BuildCommDCBW(LPCWSTR,LPDCB);
+BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR,LPDCB,LPCOMMTIMEOUTS);
+BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR,LPDCB,LPCOMMTIMEOUTS);
+BOOL WINAPI CallNamedPipeA(LPCSTR,PVOID,DWORD,PVOID,DWORD,PDWORD,DWORD);
+BOOL WINAPI CallNamedPipeW(LPCWSTR,PVOID,DWORD,PVOID,DWORD,PDWORD,DWORD);
+BOOL WINAPI CancelIo(HANDLE);
+BOOL WINAPI CancelWaitableTimer(HANDLE);
+BOOL WINAPI ClearCommBreak(HANDLE);
+BOOL WINAPI ClearCommError(HANDLE,PDWORD,LPCOMSTAT);
+BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR);
+BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR);
+BOOL WINAPI CloseEventLog(HANDLE);
+BOOL WINAPI CloseHandle(HANDLE);
+BOOL WINAPI CommConfigDialogA(LPCSTR,HWND,LPCOMMCONFIG);
+BOOL WINAPI CommConfigDialogW(LPCWSTR,HWND,LPCOMMCONFIG);
+LONG WINAPI CompareFileTime(CONST FILETIME*,CONST FILETIME*);
+BOOL WINAPI ConnectNamedPipe(HANDLE,LPOVERLAPPED);
+BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD);
+PVOID WINAPI ConvertThreadToFiber(PVOID);
+BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,BOOL);
+BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,BOOL);
+BOOL WINAPI CopyFileExA(LPCSTR,LPCSTR,LPPROGRESS_ROUTINE,LPVOID,LPBOOL,DWORD);
+BOOL WINAPI CopyFileExW(LPCWSTR,LPCWSTR,LPPROGRESS_ROUTINE,LPVOID,LPBOOL,DWORD);
+#define RtlMoveMemory memmove
+#define RtlCopyMemory memcpy
+#define RtlFillMemory(d,l,f) memset((d), (f), (l))
+#define RtlZeroMemory(d,l) RtlFillMemory((d),(l),0)
+#define MoveMemory RtlMoveMemory
+#define CopyMemory RtlCopyMemory
+#define FillMemory RtlFillMemory
+#define ZeroMemory RtlZeroMemory
+BOOL WINAPI CopySid(DWORD,PSID,PSID);
+BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES);
+BOOL WINAPI CreateDirectoryW(LPCWSTR,LPSECURITY_ATTRIBUTES);
+BOOL WINAPI CreateDirectoryExA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES);
+BOOL WINAPI CreateDirectoryExW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR);
+HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCWSTR);
+LPVOID WINAPI CreateFiber(DWORD,LPFIBER_START_ROUTINE,LPVOID);
+HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
+HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
+HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCSTR);
+HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,DWORD,DWORD,LPCWSTR);
+HANDLE WINAPI CreateHardLinkA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateHardLinkW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateIoCompletionPort(HANDLE,HANDLE,DWORD,DWORD);
+HANDLE WINAPI CreateMailslotA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateMailslotW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
+HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR);
+HANDLE WINAPI CreateNamedPipeA(LPCSTR,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+HANDLE WINAPI CreateNamedPipeW(LPCWSTR,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+BOOL WINAPI CreatePipe(PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD);
+BOOL WINAPI CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR*,BOOL,HANDLE,PGENERIC_MAPPING);
+BOOL WINAPI CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION);
+BOOL WINAPI CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION);
+BOOL WINAPI CreateProcessAsUserA(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION);
+BOOL WINAPI CreateProcessAsUserW(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,PVOID,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION);
+HANDLE WINAPI CreateRemoteThread(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
+HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR);
+HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
+DWORD WINAPI CreateTapePartition(HANDLE,DWORD,DWORD,DWORD);
+HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,PVOID,DWORD,PDWORD);
+HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
+HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR);
+BOOL WINAPI DebugActiveProcess(DWORD);
+void WINAPI DebugBreak(void);
+BOOL WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR);
+BOOL WINAPI DefineDosDeviceW(DWORD,LPCWSTR,LPCWSTR);
+#define DefineHandleTable(w) ((w),TRUE)
+BOOL WINAPI DeleteAce(PACL,DWORD);
+ATOM WINAPI DeleteAtom(ATOM);
+void WINAPI DeleteCriticalSection(PCRITICAL_SECTION);
+void WINAPI DeleteFiber(PVOID);
+BOOL WINAPI DeleteFileA(LPCSTR);
+BOOL WINAPI DeleteFileW(LPCWSTR);
+BOOL WINAPI DeregisterEventSource(HANDLE);
+BOOL WINAPI DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR*);
+BOOL WINAPI DeviceIoControl(HANDLE,DWORD,PVOID,DWORD,PVOID,DWORD,PDWORD,POVERLAPPED);
+BOOL WINAPI DisableThreadLibraryCalls(HMODULE);
+BOOL WINAPI DisconnectNamedPipe(HANDLE);
+BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME);
+BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,PHANDLE,DWORD,BOOL,DWORD);
+BOOL WINAPI DuplicateToken(HANDLE,SECURITY_IMPERSONATION_LEVEL,PHANDLE);
+BOOL WINAPI DuplicateTokenEx(HANDLE,DWORD,LPSECURITY_ATTRIBUTES,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
+BOOL WINAPI EndUpdateResourceA(HANDLE,BOOL);
+BOOL WINAPI EndUpdateResourceW(HANDLE,BOOL);
+void WINAPI EnterCriticalSection(LPCRITICAL_SECTION);
+BOOL WINAPI EnumResourceLanguagesA(HINSTANCE,LPCSTR,LPCSTR,ENUMRESLANGPROC,LONG);
+BOOL WINAPI EnumResourceLanguagesW(HINSTANCE,LPCWSTR,LPCWSTR,ENUMRESLANGPROC,LONG);
+BOOL WINAPI EnumResourceNamesA(HINSTANCE,LPCSTR,ENUMRESNAMEPROC,LONG);
+BOOL WINAPI EnumResourceNamesW(HINSTANCE,LPCWSTR,ENUMRESNAMEPROC,LONG);
+BOOL WINAPI EnumResourceTypesA(HINSTANCE,ENUMRESTYPEPROC,LONG);
+BOOL WINAPI EnumResourceTypesW(HINSTANCE,ENUMRESTYPEPROC,LONG);
+BOOL WINAPI EqualPrefixSid(PSID,PSID);
+BOOL WINAPI EqualSid(PSID,PSID);
+DWORD WINAPI EraseTape(HANDLE,DWORD,BOOL);
+BOOL WINAPI EscapeCommFunction(HANDLE,DWORD);
+DECLSPEC_NORETURN void WINAPI ExitProcess(UINT);
+DECLSPEC_NORETURN void WINAPI ExitThread(DWORD);
+DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD);
+void WINAPI FatalAppExitA(UINT,LPCSTR);
+void WINAPI FatalAppExitW(UINT,LPCWSTR);
+void WINAPI FatalExit(int);
+BOOL WINAPI FileTimeToDosDateTime(CONST FILETIME *,LPWORD,LPWORD);
+BOOL WINAPI FileTimeToLocalFileTime(FILETIME *,LPFILETIME);
+BOOL WINAPI FileTimeToSystemTime(CONST FILETIME *,LPSYSTEMTIME);
+ATOM WINAPI FindAtomA(LPCSTR);
+ATOM WINAPI FindAtomW(LPCWSTR);
+BOOL WINAPI FindClose(HANDLE);
+BOOL WINAPI FindCloseChangeNotification(HANDLE);
+HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR,BOOL,DWORD);
+HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR,BOOL,DWORD);
+HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);
+HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW);
+HANDLE WINAPI FindFirstFileExA(LPCSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD);
+HANDLE WINAPI FindFirstFileExW(LPCWSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD);
+BOOL WINAPI FindFirstFreeAce(PACL,PVOID*);
+BOOL WINAPI FindNextChangeNotification(HANDLE);
+BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA);
+BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW);
+HRSRC WINAPI FindResourceA(HMODULE,LPCSTR,LPCSTR);
+HRSRC WINAPI FindResourceW(HINSTANCE,LPCWSTR,LPCWSTR);
+HRSRC WINAPI FindResourceExA(HINSTANCE,LPCSTR,LPCSTR,WORD);
+HRSRC WINAPI FindResourceExW(HINSTANCE,LPCWSTR,LPCWSTR,WORD);
+BOOL WINAPI FlushFileBuffers(HANDLE);
+BOOL WINAPI FlushInstructionCache(HANDLE,PCVOID,DWORD);
+BOOL WINAPI FlushViewOfFile(PCVOID,DWORD);
+DWORD WINAPI FormatMessageA(DWORD,PCVOID,DWORD,DWORD,LPSTR,DWORD,va_list*);
+DWORD WINAPI FormatMessageW(DWORD,PCVOID,DWORD,DWORD,LPWSTR,DWORD,va_list*);
+BOOL WINAPI FreeEnvironmentStringsA(LPSTR);
+BOOL WINAPI FreeEnvironmentStringsW(LPWSTR);
+BOOL WINAPI FreeLibrary(HMODULE);
+DECLSPEC_NORETURN void WINAPI FreeLibraryAndExitThread(HMODULE,DWORD);
+#define FreeModule(m) FreeLibrary(m)
+#define FreeProcInstance(p) (void)(p)
+#ifndef XFree86Server
+BOOL WINAPI FreeResource(HGLOBAL);
+#endif /* ndef XFree86Server */
+PVOID WINAPI FreeSid(PSID);
+BOOL WINAPI GetAce(PACL,DWORD,PVOID);
+BOOL WINAPI GetAclInformation(PACL,PVOID,DWORD,ACL_INFORMATION_CLASS);
+UINT WINAPI GetAtomNameA(ATOM,LPSTR,int);
+UINT WINAPI GetAtomNameW(ATOM,LPWSTR,int);
+BOOL WINAPI GetBinaryTypeA(LPCSTR,PDWORD);
+BOOL WINAPI GetBinaryTypeW(LPCWSTR,PDWORD);
+LPSTR WINAPI GetCommandLineA(VOID);
+LPWSTR WINAPI GetCommandLineW(VOID);
+BOOL WINAPI GetCommConfig(HANDLE,LPCOMMCONFIG,PDWORD);
+BOOL WINAPI GetCommMask(HANDLE,PDWORD);
+BOOL WINAPI GetCommModemStatus(HANDLE,PDWORD);
+BOOL WINAPI GetCommProperties(HANDLE,LPCOMMPROP);
+BOOL WINAPI GetCommState(HANDLE,LPDCB);
+BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS);
+DWORD WINAPI GetCompressedFileSizeA(LPCSTR,PDWORD);
+DWORD WINAPI GetCompressedFileSizeW(LPCWSTR,PDWORD);
+BOOL WINAPI GetComputerNameA(LPSTR,PDWORD);
+BOOL WINAPI GetComputerNameW(LPWSTR,PDWORD);
+DWORD WINAPI GetCurrentDirectoryA(DWORD,LPSTR);
+DWORD WINAPI GetCurrentDirectoryW(DWORD,LPWSTR);
+BOOL WINAPI GetCurrentHwProfileA(LPHW_PROFILE_INFOA);
+BOOL WINAPI GetCurrentHwProfileW(LPHW_PROFILE_INFOW);
+HANDLE WINAPI GetCurrentProcess(void);
+DWORD WINAPI GetCurrentProcessId(void);
+HANDLE WINAPI GetCurrentThread(void);
+DWORD WINAPI GetCurrentThreadId(void);
+#define GetCurrentTime GetTickCount
+BOOL WINAPI GetDefaultCommConfigA(LPCSTR,LPCOMMCONFIG,PDWORD);
+BOOL WINAPI GetDefaultCommConfigW(LPCWSTR,LPCOMMCONFIG,PDWORD);
+BOOL WINAPI GetDiskFreeSpaceA(LPCSTR,PDWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,PDWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER);
+BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER);
+UINT WINAPI GetDriveTypeA(LPCSTR);
+UINT WINAPI GetDriveTypeW(LPCWSTR);
+LPSTR WINAPI GetEnvironmentStrings(void);
+LPSTR WINAPI GetEnvironmentStringsA(void);
+LPWSTR WINAPI GetEnvironmentStringsW(void);
+DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD);
+BOOL WINAPI GetExitCodeProcess(HANDLE,PDWORD);
+BOOL WINAPI GetExitCodeThread(HANDLE,PDWORD);
+DWORD WINAPI GetFileAttributesA(LPCSTR);
+DWORD WINAPI GetFileAttributesW(LPCWSTR);
+BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,PVOID);
+BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,PVOID);
+BOOL WINAPI GetFileInformationByHandle(HANDLE,LPBY_HANDLE_FILE_INFORMATION);
+BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
+BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
+DWORD WINAPI GetFileSize(HANDLE,PDWORD);
+BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME);
+DWORD WINAPI GetFileType(HANDLE);
+#define GetFreeSpace(w) (0x100000L)
+DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+BOOL WINAPI GetHandleInformation(HANDLE,PDWORD);
+BOOL WINAPI GetKernelObjectSecurity(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
+DWORD WINAPI GetLengthSid(PSID);
+void WINAPI GetLocalTime(LPSYSTEMTIME);
+DWORD WINAPI GetLogicalDrives(void);
+DWORD WINAPI GetLogicalDriveStringsA(DWORD,LPSTR);
+DWORD WINAPI GetLogicalDriveStringsW(DWORD,LPWSTR);
+DWORD WINAPI GetLongPathNameA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetLongPathNameW(LPCWSTR,LPWSTR,DWORD);
+BOOL WINAPI GetMailslotInfo(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD);
+DWORD WINAPI GetModuleFileNameA(HINSTANCE,LPSTR,DWORD);
+DWORD WINAPI GetModuleFileNameW(HINSTANCE,LPWSTR,DWORD);
+HMODULE WINAPI GetModuleHandleA(LPCSTR);
+HMODULE WINAPI GetModuleHandleW(LPCWSTR);
+BOOL WINAPI GetNamedPipeHandleStateA(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD,LPSTR,DWORD);
+BOOL WINAPI GetNamedPipeHandleStateW(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD,LPWSTR,DWORD);
+BOOL WINAPI GetNamedPipeInfo(HANDLE,PDWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD);
+BOOL WINAPI GetOldestEventLogRecord(HANDLE,PDWORD);
+BOOL WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,PDWORD,BOOL);
+DWORD WINAPI GetPriorityClass(HANDLE);
+BOOL WINAPI GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
+UINT WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR);
+UINT WINAPI GetPrivateProfileIntW(LPCWSTR,LPCWSTR,INT,LPCWSTR);
+DWORD WINAPI GetPrivateProfileSectionA(LPCSTR,LPSTR,DWORD,LPCSTR);
+DWORD WINAPI GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR);
+DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR,DWORD,LPCSTR);
+DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR,DWORD,LPCWSTR);
+DWORD WINAPI GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD,LPCSTR);
+DWORD WINAPI GetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,DWORD,LPCWSTR);
+BOOL WINAPI GetPrivateProfileStructA(LPCSTR,LPCSTR,PVOID,UINT,LPCSTR);
+BOOL WINAPI GetPrivateProfileStructW(LPCWSTR,LPCWSTR,PVOID,UINT,LPCWSTR);
+FARPROC WINAPI GetProcAddress(HINSTANCE,LPCSTR);
+BOOL WINAPI GetProcessAffinityMask(HANDLE,PDWORD,PDWORD);
+HANDLE WINAPI GetProcessHeap(VOID);
+DWORD WINAPI GetProcessHeaps(DWORD,PHANDLE);
+BOOL WINAPI GetProcessPriorityBoost(HANDLE,PBOOL);
+BOOL WINAPI GetProcessShutdownParameters(PDWORD,PDWORD);
+BOOL WINAPI GetProcessTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
+DWORD WINAPI GetProcessVersion(DWORD);
+HWINSTA WINAPI GetProcessWindowStation(void);
+BOOL WINAPI GetProcessWorkingSetSize(HANDLE,PDWORD,PDWORD);
+UINT WINAPI GetProfileIntA(LPCSTR,LPCSTR,INT);
+UINT WINAPI GetProfileIntW(LPCWSTR,LPCWSTR,INT);
+DWORD WINAPI GetProfileSectionA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetProfileSectionW(LPCWSTR,LPWSTR,DWORD);
+DWORD WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,DWORD);
+BOOL WINAPI GetQueuedCompletionStatus(HANDLE,PDWORD,PDWORD,LPOVERLAPPED*,DWORD);
+BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,PDWORD);
+BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL*,LPBOOL);
+BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID*,LPBOOL);
+DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR);
+BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID*,LPBOOL);
+BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,LPBOOL,PACL*,LPBOOL);
+DWORD WINAPI GetShortPathNameA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetShortPathNameW(LPCWSTR,LPWSTR,DWORD);
+PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID);
+DWORD WINAPI GetSidLengthRequired(UCHAR);
+PDWORD WINAPI GetSidSubAuthority(PSID,DWORD);
+PUCHAR WINAPI GetSidSubAuthorityCount(PSID);
+VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA);
+VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW);
+HANDLE WINAPI GetStdHandle(DWORD);
+UINT WINAPI GetSystemDirectoryA(LPSTR,UINT);
+UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT);
+VOID WINAPI GetSystemInfo(LPSYSTEM_INFO);
+BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
+VOID WINAPI GetSystemTime(LPSYSTEMTIME);
+BOOL WINAPI GetSystemTimeAdjustment(PDWORD,PDWORD,PBOOL);
+void WINAPI GetSystemTimeAsFileTime(LPFILETIME);
+DWORD WINAPI GetTapeParameters(HANDLE,DWORD,PDWORD,PVOID);
+DWORD WINAPI GetTapePosition(HANDLE,DWORD,PDWORD,PDWORD,PDWORD);
+DWORD WINAPI GetTapeStatus(HANDLE);
+UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR);
+UINT WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR);
+DWORD WINAPI GetTempPathA(DWORD,LPSTR);
+DWORD WINAPI GetTempPathW(DWORD,LPWSTR);
+BOOL WINAPI GetThreadContext(HANDLE,LPCONTEXT);
+int WINAPI GetThreadPriority(HANDLE);
+BOOL WINAPI GetThreadPriorityBoost(HANDLE,PBOOL);
+BOOL WINAPI GetThreadSelectorEntry(HANDLE,DWORD,LPLDT_ENTRY);
+BOOL WINAPI GetThreadTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
+DWORD WINAPI GetTickCount(void);
+DWORD WINAPI GetTimeZoneInformation(LPTIME_ZONE_INFORMATION);
+BOOL WINAPI GetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,PVOID,DWORD,PDWORD);
+BOOL WINAPI GetUserNameA (LPSTR,PDWORD);
+BOOL WINAPI GetUserNameW(LPWSTR,PDWORD);
+DWORD WINAPI GetVersion(void);
+BOOL WINAPI GetVersionExA(LPOSVERSIONINFOA);
+BOOL WINAPI GetVersionExW(LPOSVERSIONINFOW);
+BOOL WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,PDWORD,PDWORD,PDWORD,LPSTR,DWORD);
+BOOL WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,PDWORD,PDWORD,PDWORD,LPWSTR,DWORD);
+UINT WINAPI GetWindowsDirectoryA(LPSTR,UINT);
+UINT WINAPI GetWindowsDirectoryW(LPWSTR,UINT);
+DWORD WINAPI GetWindowThreadProcessId(HWND,PDWORD);
+ATOM WINAPI GlobalAddAtomA(LPCSTR);
+ATOM WINAPI GlobalAddAtomW( LPCWSTR);
+HGLOBAL WINAPI GlobalAlloc(UINT,DWORD);
+UINT WINAPI GlobalCompact(DWORD);
+ATOM WINAPI GlobalDeleteAtom(ATOM);
+HGLOBAL GlobalDiscard(HGLOBAL);
+ATOM WINAPI GlobalFindAtomA(LPCSTR);
+ATOM WINAPI GlobalFindAtomW(LPCWSTR);
+VOID WINAPI GlobalFix(HGLOBAL);
+UINT WINAPI GlobalFlags(HGLOBAL);
+HGLOBAL WINAPI GlobalFree(HGLOBAL);
+UINT WINAPI GlobalGetAtomNameA(ATOM,LPSTR,int);
+UINT WINAPI GlobalGetAtomNameW(ATOM,LPWSTR,int);
+HGLOBAL WINAPI GlobalHandle(PCVOID);
+LPVOID WINAPI GlobalLock(HGLOBAL);
+VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
+HGLOBAL WINAPI GlobalReAlloc(HGLOBAL,DWORD,UINT);
+DWORD WINAPI GlobalSize(HGLOBAL);
+VOID WINAPI GlobalUnfix(HGLOBAL);
+BOOL WINAPI GlobalUnlock(HGLOBAL);
+BOOL WINAPI GlobalUnWire(HGLOBAL);
+PVOID WINAPI GlobalWire(HGLOBAL);
+#define HasOverlappedIoCompleted(lpOverlapped)  ((lpOverlapped)->Internal != STATUS_PENDING)
+PVOID WINAPI HeapAlloc(HANDLE,DWORD,DWORD);
+UINT WINAPI HeapCompact(HANDLE,DWORD);
+HANDLE WINAPI HeapCreate(DWORD,DWORD,DWORD);
+BOOL WINAPI HeapDestroy(HANDLE);
+BOOL WINAPI HeapFree(HANDLE,DWORD,PVOID);
+BOOL WINAPI HeapLock(HANDLE);
+PVOID WINAPI HeapReAlloc(HANDLE,DWORD,PVOID,DWORD);
+DWORD WINAPI HeapSize(HANDLE,DWORD,PCVOID);
+BOOL WINAPI HeapUnlock(HANDLE);
+BOOL WINAPI HeapValidate(HANDLE,DWORD,PCVOID);
+BOOL WINAPI HeapWalk(HANDLE,LPPROCESS_HEAP_ENTRY);
+BOOL WINAPI ImpersonateLoggedOnUser(HANDLE);
+BOOL WINAPI ImpersonateNamedPipeClient(HANDLE);
+BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL);
+BOOL WINAPI InitAtomTable(DWORD);
+BOOL WINAPI InitializeAcl(PACL,DWORD,DWORD);
+VOID WINAPI InitializeCriticalSection(LPCRITICAL_SECTION);
+#if (_WIN32_WINNT >= 0x0403) /* Needs NT4, SP3 or later.  */
+BOOL WINAPI InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION,DWORD);
+DWORD WINAPI SetCriticalSectionSpinCount(LPCRITICAL_SECTION,DWORD);
+#endif
+BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
+BOOL WINAPI InitializeSid (PSID,PSID_IDENTIFIER_AUTHORITY,BYTE);
+LONG WINAPI InterlockedCompareExchange(LPLONG,LONG,LONG);
+/* PVOID WINAPI InterlockedCompareExchangePointer(PVOID*,PVOID,PVOID); */
+#define InterlockedCompareExchangePointer(d,e,c) \
+    (PVOID)InterlockedCompareExchange((LPLONG)(d),(LONG)(e),(LONG)(c))
+LONG WINAPI InterlockedDecrement(LPLONG);
+LONG WINAPI InterlockedExchange(LPLONG,LONG);
+/* PVOID WINAPI InterlockedExchangePointer(PVOID*,PVOID); */
+#define InterlockedExchangePointer(t,v) \
+    (PVOID)InterlockedExchange((LPLONG)(t),(LONG)(v))
+LONG WINAPI InterlockedExchangeAdd(PLONG,LONG);
+LONG WINAPI InterlockedIncrement(LPLONG);
+BOOL WINAPI IsBadCodePtr(FARPROC);
+BOOL WINAPI IsBadHugeReadPtr(PCVOID,UINT);
+BOOL WINAPI IsBadHugeWritePtr(PVOID,UINT);
+BOOL WINAPI IsBadReadPtr(PCVOID,UINT);
+BOOL WINAPI IsBadStringPtrA(LPCSTR,UINT);
+BOOL WINAPI IsBadStringPtrW(LPCWSTR,UINT);
+BOOL WINAPI IsBadWritePtr(PVOID,UINT);
+BOOL WINAPI IsDebuggerPresent(void);
+BOOL WINAPI IsProcessorFeaturePresent(DWORD);
+BOOL WINAPI IsTextUnicode(PCVOID,int,LPINT);
+BOOL WINAPI IsValidAcl(PACL);
+BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
+BOOL WINAPI IsValidSid(PSID);
+void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION);
+#define LimitEmsPages(n)
+HINSTANCE WINAPI LoadLibraryA(LPCSTR);
+HINSTANCE WINAPI LoadLibraryExA(LPCSTR,HANDLE,DWORD);
+HINSTANCE WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD);
+HINSTANCE WINAPI LoadLibraryW(LPCWSTR);
+DWORD WINAPI LoadModule(LPCSTR,PVOID);
+HGLOBAL WINAPI LoadResource(HINSTANCE,HRSRC);
+HLOCAL WINAPI LocalAlloc(UINT,UINT);
+UINT WINAPI LocalCompact(UINT);
+HLOCAL LocalDiscard(HLOCAL);
+BOOL WINAPI LocalFileTimeToFileTime(CONST FILETIME *,LPFILETIME);
+UINT WINAPI LocalFlags(HLOCAL);
+HLOCAL WINAPI LocalFree(HLOCAL);
+HLOCAL WINAPI LocalHandle(LPCVOID);
+PVOID WINAPI LocalLock(HLOCAL);
+HLOCAL WINAPI LocalReAlloc(HLOCAL,UINT,UINT);
+UINT WINAPI LocalShrink(HLOCAL,UINT);
+UINT WINAPI LocalSize(HLOCAL);
+BOOL WINAPI LocalUnlock(HLOCAL);
+BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+BOOL WINAPI LockFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPOVERLAPPED);
+PVOID WINAPI LockResource(HGLOBAL);
+#define LockSegment(w) GlobalFix((HANDLE)(w))
+BOOL WINAPI LogonUserA(LPSTR,LPSTR,LPSTR,DWORD,DWORD,PHANDLE);
+BOOL WINAPI LogonUserW(LPWSTR,LPWSTR,LPWSTR,DWORD,DWORD,PHANDLE);
+BOOL WINAPI LookupAccountNameA(LPCSTR,LPCSTR,PSID,PDWORD,LPSTR,PDWORD,PSID_NAME_USE);
+BOOL WINAPI LookupAccountNameW(LPCWSTR,LPCWSTR,PSID,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE);
+BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,PDWORD,LPSTR,PDWORD,PSID_NAME_USE);
+BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,PDWORD,LPWSTR,PDWORD,PSID_NAME_USE);
+BOOL WINAPI LookupPrivilegeDisplayNameA(LPCSTR,LPCSTR,LPSTR,PDWORD,PDWORD);
+BOOL WINAPI LookupPrivilegeDisplayNameW(LPCWSTR,LPCWSTR,LPWSTR,PDWORD,PDWORD);
+BOOL WINAPI LookupPrivilegeNameA(LPCSTR,PLUID,LPSTR,PDWORD);
+BOOL WINAPI LookupPrivilegeNameW(LPCWSTR,PLUID,LPWSTR,PDWORD);
+BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,PLUID);
+BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,PLUID);
+LPSTR WINAPI lstrcatA(LPSTR,LPCSTR);
+LPWSTR WINAPI lstrcatW(LPWSTR,LPCWSTR);
+int WINAPI lstrcmpA(LPCSTR,LPCSTR);
+int WINAPI lstrcmpiA(LPCSTR,LPCSTR);
+int WINAPI lstrcmpiW( LPCWSTR,LPCWSTR);
+int WINAPI lstrcmpW(LPCWSTR,LPCWSTR);
+LPSTR WINAPI lstrcpyA(LPSTR,LPCSTR);
+LPSTR WINAPI lstrcpynA(LPSTR,LPCSTR,int);
+LPWSTR WINAPI lstrcpynW(LPWSTR,LPCWSTR,int);
+LPWSTR WINAPI lstrcpyW(LPWSTR,LPCWSTR);
+int WINAPI lstrlenA(LPCSTR);
+int WINAPI lstrlenW(LPCWSTR);
+BOOL WINAPI MakeAbsoluteSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PDWORD,PACL,PDWORD,PACL,PDWORD,PSID,PDWORD,PSID,PDWORD);
+#define MakeProcInstance(p,i) (p)
+BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PDWORD);
+VOID WINAPI MapGenericMask(PDWORD,PGENERIC_MAPPING);
+PVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+PVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,PVOID);
+BOOL WINAPI MoveFileA(LPCSTR,LPCSTR);
+BOOL WINAPI MoveFileExA(LPCSTR,LPCSTR,DWORD);
+BOOL WINAPI MoveFileExW(LPCWSTR,LPCWSTR,DWORD);
+BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR);
+int WINAPI MulDiv(int,int,int);
+BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE);
+BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR,PVOID,BOOL);
+BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR,PVOID,BOOL);
+BOOL WINAPI ObjectDeleteAuditAlarmA(LPCSTR,PVOID,BOOL);
+BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR,PVOID,BOOL);
+BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR,PVOID,LPSTR,LPSTR,PSECURITY_DESCRIPTOR,HANDLE,DWORD,DWORD,PPRIVILEGE_SET,BOOL,BOOL,PBOOL);
+BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR,PVOID,LPWSTR,LPWSTR,PSECURITY_DESCRIPTOR,HANDLE,DWORD,DWORD,PPRIVILEGE_SET,BOOL,BOOL,PBOOL);
+BOOL WINAPI ObjectPrivilegeAuditAlarmA(LPCSTR,PVOID,HANDLE,DWORD,PPRIVILEGE_SET,BOOL);
+BOOL WINAPI ObjectPrivilegeAuditAlarmW(LPCWSTR,PVOID,HANDLE,DWORD,PPRIVILEGE_SET,BOOL);
+HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR);
+HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR);
+HANDLE WINAPI OpenEventA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenEventLogA (LPCSTR,LPCSTR);
+HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR);
+HANDLE WINAPI OpenEventW(DWORD,BOOL,LPCWSTR);
+HFILE WINAPI OpenFile(LPCSTR,LPOFSTRUCT,UINT);
+HANDLE WINAPI OpenFileMappingA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenFileMappingW(DWORD,BOOL,LPCWSTR);
+HANDLE WINAPI OpenMutexA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenMutexW(DWORD,BOOL,LPCWSTR);
+HANDLE WINAPI OpenProcess(DWORD,BOOL,DWORD);
+BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE);
+HANDLE WINAPI OpenSemaphoreA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenSemaphoreW(DWORD,BOOL,LPCWSTR);
+BOOL WINAPI OpenThreadToken(HANDLE,DWORD,BOOL,PHANDLE);
+HANDLE WINAPI OpenWaitableTimerA(DWORD,BOOL,LPCSTR);
+HANDLE WINAPI OpenWaitableTimerW(DWORD,BOOL,LPCWSTR);
+void WINAPI OutputDebugStringA(LPCSTR);
+void WINAPI OutputDebugStringW(LPCWSTR);
+BOOL WINAPI PeekNamedPipe(HANDLE,PVOID,DWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI PostQueuedCompletionStatus(HANDLE,DWORD,DWORD,LPOVERLAPPED);
+DWORD WINAPI PrepareTape(HANDLE,DWORD,BOOL);
+BOOL WINAPI PrivilegeCheck (HANDLE,PPRIVILEGE_SET,PBOOL);
+BOOL WINAPI PrivilegedServiceAuditAlarmA(LPCSTR,LPCSTR,HANDLE,PPRIVILEGE_SET,BOOL);
+BOOL WINAPI PrivilegedServiceAuditAlarmW(LPCWSTR,LPCWSTR,HANDLE,PPRIVILEGE_SET,BOOL);
+BOOL WINAPI PulseEvent(HANDLE);
+BOOL WINAPI PurgeComm(HANDLE,DWORD);
+DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD);
+BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER);
+BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER);
+DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,DWORD);
+void WINAPI RaiseException(DWORD,DWORD,DWORD,const DWORD*);
+BOOL WINAPI ReadDirectoryChangesW(HANDLE,PVOID,DWORD,BOOL,DWORD,PDWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
+BOOL WINAPI ReadEventLogA(HANDLE,DWORD,DWORD,PVOID,DWORD,DWORD *,DWORD *);
+BOOL WINAPI ReadEventLogW(HANDLE,DWORD,DWORD,PVOID,DWORD,DWORD *,DWORD *);
+BOOL WINAPI ReadFile(HANDLE,PVOID,DWORD,PDWORD,LPOVERLAPPED);
+BOOL WINAPI ReadFileEx(HANDLE,PVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
+BOOL WINAPI ReadProcessMemory(HANDLE,PCVOID,PVOID,DWORD,PDWORD);
+HANDLE WINAPI RegisterEventSourceA (LPCSTR,LPCSTR);
+HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR);
+BOOL WINAPI ReleaseMutex(HANDLE);
+BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG);
+BOOL WINAPI RemoveDirectoryA(LPCSTR);
+BOOL WINAPI RemoveDirectoryW(LPCWSTR);
+BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR*,PVOID);
+BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR*,PVOID);
+BOOL WINAPI ResetEvent(HANDLE);
+DWORD WINAPI ResumeThread(HANDLE);
+BOOL WINAPI RevertToSelf(void);
+DWORD WINAPI SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD WINAPI SearchPathW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+BOOL WINAPI SetAclInformation(PACL,PVOID,DWORD,ACL_INFORMATION_CLASS);
+BOOL WINAPI SetCommBreak(HANDLE);
+BOOL WINAPI SetCommConfig(HANDLE,LPCOMMCONFIG,DWORD);
+BOOL WINAPI SetCommMask(HANDLE,DWORD);
+BOOL WINAPI SetCommState(HANDLE,LPDCB);
+BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS);
+BOOL WINAPI SetComputerNameA(LPCSTR);
+BOOL WINAPI SetComputerNameW(LPCWSTR);
+BOOL WINAPI SetCurrentDirectoryA(LPCSTR);
+BOOL WINAPI SetCurrentDirectoryW(LPCWSTR);
+BOOL WINAPI SetDefaultCommConfigA(LPCSTR,LPCOMMCONFIG,DWORD);
+BOOL WINAPI SetDefaultCommConfigW(LPCWSTR,LPCOMMCONFIG,DWORD);
+BOOL WINAPI SetEndOfFile(HANDLE);
+BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR);
+BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR);
+UINT WINAPI SetErrorMode(UINT);
+BOOL WINAPI SetEvent(HANDLE);
+VOID WINAPI SetFileApisToANSI(void);
+VOID WINAPI SetFileApisToOEM(void);
+BOOL WINAPI SetFileAttributesA(LPCSTR,DWORD);
+BOOL WINAPI SetFileAttributesW(LPCWSTR,DWORD);
+DWORD WINAPI SetFilePointer(HANDLE,LONG,PLONG,DWORD);
+BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*);
+UINT WINAPI SetHandleCount(UINT);
+BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);
+BOOL WINAPI SetKernelObjectSecurity(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+void WINAPI SetLastError(DWORD);
+void WINAPI SetLastErrorEx(DWORD,DWORD);
+BOOL WINAPI SetLocalTime(const SYSTEMTIME*);
+BOOL WINAPI SetMailslotInfo(HANDLE,DWORD);
+BOOL WINAPI SetNamedPipeHandleState(HANDLE,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI SetPriorityClass(HANDLE,DWORD);
+BOOL WINAPI SetPrivateObjectSecurity(SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR *,PGENERIC_MAPPING,HANDLE);
+BOOL WINAPI SetProcessAffinityMask(HANDLE,DWORD);
+BOOL WINAPI SetProcessPriorityBoost(HANDLE,BOOL);
+BOOL WINAPI SetProcessShutdownParameters(DWORD,DWORD);
+BOOL WINAPI SetProcessWorkingSetSize(HANDLE,DWORD,DWORD);
+BOOL WINAPI SetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,SECURITY_DESCRIPTOR_CONTROL,SECURITY_DESCRIPTOR_CONTROL);
+BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,BOOL,PACL,BOOL);
+BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID,BOOL);
+BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID,BOOL);
+BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,BOOL,PACL,BOOL);
+BOOL WINAPI SetStdHandle(DWORD,HANDLE);
+#define SetSwapAreaSize(w) (w)
+BOOL WINAPI SetSystemPowerState(BOOL,BOOL);
+BOOL WINAPI SetSystemTime(const SYSTEMTIME*);
+BOOL WINAPI SetSystemTimeAdjustment(DWORD,BOOL);
+DWORD WINAPI SetTapeParameters(HANDLE,DWORD,PVOID);
+DWORD WINAPI SetTapePosition(HANDLE,DWORD,DWORD,DWORD,DWORD,BOOL);
+DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD);
+BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT*);
+DWORD WINAPI SetThreadIdealProcessor(HANDLE,DWORD);
+BOOL WINAPI SetThreadPriority(HANDLE,int);
+BOOL WINAPI SetThreadPriorityBoost(HANDLE,BOOL);
+BOOL WINAPI SetThreadToken (PHANDLE,HANDLE);
+BOOL WINAPI SetTimeZoneInformation(const TIME_ZONE_INFORMATION *);
+BOOL WINAPI SetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,PVOID,DWORD);
+LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER);
+BOOL WINAPI SetupComm(HANDLE,DWORD,DWORD);
+BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR);
+BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR);
+BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,PVOID,BOOL);
+BOOL WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL);
+DWORD WINAPI SizeofResource(HINSTANCE,HRSRC);
+void WINAPI Sleep(DWORD);
+DWORD WINAPI SleepEx(DWORD,BOOL);
+DWORD WINAPI SuspendThread(HANDLE);
+void WINAPI SwitchToFiber(PVOID);
+BOOL WINAPI SwitchToThread(void);
+BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
+BOOL WINAPI SystemTimeToTzSpecificLocalTime(LPTIME_ZONE_INFORMATION,LPSYSTEMTIME,LPSYSTEMTIME);
+BOOL WINAPI TerminateProcess(HANDLE,UINT);
+BOOL WINAPI TerminateThread(HANDLE,DWORD);
+DWORD WINAPI TlsAlloc(VOID);
+BOOL WINAPI TlsFree(DWORD);
+PVOID WINAPI TlsGetValue(DWORD);
+BOOL WINAPI TlsSetValue(DWORD,PVOID);
+BOOL WINAPI TransactNamedPipe(HANDLE,PVOID,DWORD,PVOID,DWORD,PDWORD,LPOVERLAPPED);
+BOOL WINAPI TransmitCommChar(HANDLE,char);
+BOOL WINAPI TryEnterCriticalSection(LPCRITICAL_SECTION);
+LONG WINAPI UnhandledExceptionFilter(LPEXCEPTION_POINTERS);
+BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+BOOL WINAPI UnlockFileEx(HANDLE,DWORD,DWORD,DWORD,LPOVERLAPPED);
+#define UnlockResource(h) (h)
+#define UnlockSegment(w) GlobalUnfix((HANDLE)(w))
+BOOL WINAPI UnmapViewOfFile(PVOID);
+BOOL WINAPI UpdateResourceA(HANDLE,LPCSTR,LPCSTR,WORD,PVOID,DWORD);
+BOOL WINAPI UpdateResourceW(HANDLE,LPCWSTR,LPCWSTR,WORD,PVOID,DWORD);
+BOOL WINAPI VerifyVersionInfoA(LPOSVERSIONINFOEXA,DWORD,DWORDLONG);
+BOOL WINAPI VerifyVersionInfoW(LPOSVERSIONINFOEXW,DWORD,DWORDLONG);
+PVOID WINAPI VirtualAlloc(PVOID,DWORD,DWORD,DWORD);
+PVOID WINAPI VirtualAllocEx(HANDLE,PVOID,DWORD,DWORD,DWORD);
+BOOL WINAPI VirtualFree(PVOID,DWORD,DWORD);
+BOOL WINAPI VirtualFreeEx(HANDLE,PVOID,DWORD,DWORD);
+BOOL WINAPI VirtualLock(PVOID,DWORD);
+BOOL WINAPI VirtualProtect(PVOID,DWORD,DWORD,PDWORD);
+BOOL WINAPI VirtualProtectEx(HANDLE,PVOID,DWORD,DWORD,PDWORD);
+DWORD WINAPI VirtualQuery(LPCVOID,PMEMORY_BASIC_INFORMATION,DWORD);
+DWORD WINAPI VirtualQueryEx(HANDLE,LPCVOID,PMEMORY_BASIC_INFORMATION,DWORD);
+BOOL WINAPI VirtualUnlock(PVOID,DWORD);
+BOOL WINAPI WaitCommEvent(HANDLE,PDWORD,LPOVERLAPPED);
+BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT,DWORD);
+DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DWORD);
+DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,BOOL,DWORD,BOOL);
+DWORD WINAPI WaitForSingleObject(HANDLE,DWORD);
+DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,BOOL);
+BOOL WINAPI WaitNamedPipeA(LPCSTR,DWORD);
+BOOL WINAPI WaitNamedPipeW(LPCWSTR,DWORD);
+BOOL WINAPI WinLoadTrustProvider(GUID*);
+BOOL WINAPI WriteFile(HANDLE,PCVOID,DWORD,PDWORD,LPOVERLAPPED);
+BOOL WINAPI WriteFileEx(HANDLE,PCVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
+BOOL WINAPI WritePrivateProfileSectionA(LPCSTR,LPCSTR,LPCSTR);
+BOOL WINAPI WritePrivateProfileSectionW(LPCWSTR,LPCWSTR,LPCWSTR);
+BOOL WINAPI WritePrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
+BOOL WINAPI WritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);
+BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,PVOID,UINT,LPCSTR);
+BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,PVOID,UINT,LPCWSTR);
+BOOL WINAPI WriteProcessMemory(HANDLE,PVOID,PVOID,DWORD,PDWORD);
+BOOL WINAPI WriteProfileSectionA(LPCSTR,LPCSTR);
+BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR);
+BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR);
+BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
+DWORD WINAPI WriteTapemark(HANDLE,DWORD,DWORD,BOOL);
+#define Yield()
+
+#ifdef UNICODE
+typedef STARTUPINFOW STARTUPINFO,*LPSTARTUPINFO;
+typedef WIN32_FIND_DATAW WIN32_FIND_DATA,*LPWIN32_FIND_DATA;
+typedef HW_PROFILE_INFOW HW_PROFILE_INFO,*LPHW_PROFILE_INFO;
+#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmW
+#define AddAtom AddAtomW
+#define BackupEventLog BackupEventLogW
+#define BeginUpdateResource BeginUpdateResourceW
+#define BuildCommDCB BuildCommDCBW
+#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsW
+#define CallNamedPipe CallNamedPipeW
+#define ClearEventLog ClearEventLogW
+#define CommConfigDialog CommConfigDialogW
+#define CopyFile CopyFileW
+#define CopyFileEx CopyFileExW
+#define CreateDirectory CreateDirectoryW
+#define CreateDirectoryEx CreateDirectoryExW
+#define CreateEvent CreateEventW
+#define CreateFile CreateFileW
+#define CreateFileMapping CreateFileMappingW
+#define CreateHardLink CreateHardLinkW
+#define CreateMailslot CreateMailslotW
+#define CreateMutex CreateMutexW
+#define CreateNamedPipe CreateNamedPipeW
+#define CreateProcess CreateProcessW
+#define CreateProcessAsUser CreateProcessAsUserW
+#define CreateSemaphore CreateSemaphoreW
+#define CreateWaitableTimer CreateWaitableTimerW
+#define DefineDosDevice DefineDosDeviceW
+#define DeleteFile DeleteFileW
+#define EndUpdateResource EndUpdateResourceW
+#define EnumResourceLanguages EnumResourceLanguagesW
+#define EnumResourceNames EnumResourceNamesW
+#define EnumResourceTypes EnumResourceTypesW
+#define ExpandEnvironmentStrings ExpandEnvironmentStringsW
+#define FatalAppExit FatalAppExitW
+#define FindAtom FindAtomW
+#define FindFirstChangeNotification FindFirstChangeNotificationW
+#define FindFirstFile FindFirstFileW
+#define FindFirstFileEx FindFirstFileExW
+#define FindNextFile FindNextFileW
+#define FindResource FindResourceW
+#define FindResourceEx FindResourceExW
+#define FormatMessage FormatMessageW
+#define FreeEnvironmentStrings FreeEnvironmentStringsW
+#define GetAtomName GetAtomNameW
+#define GetBinaryType GetBinaryTypeW
+#define GetCommandLine GetCommandLineW
+#define GetCompressedFileSize GetCompressedFileSizeW
+#define GetComputerName GetComputerNameW
+#define GetCurrentDirectory GetCurrentDirectoryW
+#define GetDefaultCommConfig GetDefaultCommConfigW
+#define GetDiskFreeSpace GetDiskFreeSpaceW
+#define GetDiskFreeSpaceEx GetDiskFreeSpaceExW
+#define GetDriveType GetDriveTypeW
+#define GetEnvironmentStrings GetEnvironmentStringsW
+#define GetEnvironmentVariable GetEnvironmentVariableW
+#define GetFileAttributes GetFileAttributesW
+#define GetFileSecurity GetFileSecurityW
+#define GetFileAttributesEx GetFileAttributesExW
+#define GetFullPathName GetFullPathNameW
+#define GetLogicalDriveStrings GetLogicalDriveStringsW
+#define GetLongPathName GetLongPathNameW
+#define GetModuleFileName GetModuleFileNameW
+#define GetModuleHandle GetModuleHandleW
+#define GetNamedPipeHandleState GetNamedPipeHandleStateW
+#define GetPrivateProfileInt GetPrivateProfileIntW
+#define GetPrivateProfileSection GetPrivateProfileSectionW
+#define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesW
+#define GetPrivateProfileString GetPrivateProfileStringW
+#define GetPrivateProfileStruct GetPrivateProfileStructW
+#define GetProfileInt GetProfileIntW
+#define GetProfileSection GetProfileSectionW
+#define GetProfileString GetProfileStringW
+#define GetShortPathName GetShortPathNameW
+#define GetStartupInfo GetStartupInfoW
+#define GetSystemDirectory GetSystemDirectoryW
+#define GetTempFileName GetTempFileNameW
+#define GetTempPath GetTempPathW
+#define GetUserName GetUserNameW
+#define GetVersionEx GetVersionExW
+#define GetVolumeInformation GetVolumeInformationW
+#define GetWindowsDirectory GetWindowsDirectoryW
+#define GlobalAddAtom GlobalAddAtomW
+#define GlobalFindAtom GlobalFindAtomW
+#define GlobalGetAtomName GlobalGetAtomNameW
+#define IsBadStringPtr IsBadStringPtrW
+#define LoadLibrary LoadLibraryW
+#define LoadLibraryEx LoadLibraryExW
+#define LogonUser LogonUserW
+#define LookupAccountName LookupAccountNameW
+#define LookupAccountSid LookupAccountSidW
+#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameW
+#define LookupPrivilegeName LookupPrivilegeNameW
+#define LookupPrivilegeValue LookupPrivilegeValueW
+#define lstrcat lstrcatW
+#define lstrcmp lstrcmpW
+#define lstrcmpi lstrcmpiW
+#define lstrcpy lstrcpyW
+#define lstrcpyn lstrcpynW
+#define lstrlen lstrlenW
+#define MoveFile MoveFileW
+#define MoveFileEx MoveFileExW
+#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmW
+#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmW
+#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmW
+#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmW
+#define OpenBackupEventLog OpenBackupEventLogW
+#define OpenEvent OpenEventW
+#define OpenEventLog OpenEventLogW
+#define OpenFileMapping OpenFileMappingW
+#define OpenMutex OpenMutexW
+#define OpenSemaphore OpenSemaphoreW
+#define OutputDebugString OutputDebugStringW
+#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmW
+#define QueryDosDevice QueryDosDeviceW
+#define ReadEventLog ReadEventLogW
+#define RegisterEventSource RegisterEventSourceW
+#define RemoveDirectory RemoveDirectoryW
+#define ReportEvent ReportEventW
+#define SearchPath SearchPathW
+#define SetComputerName SetComputerNameW
+#define SetCurrentDirectory SetCurrentDirectoryW
+#define SetDefaultCommConfig SetDefaultCommConfigW
+#define SetEnvironmentVariable SetEnvironmentVariableW
+#define SetFileAttributes SetFileAttributesW
+#define SetFileSecurity SetFileSecurityW
+#define SetVolumeLabel SetVolumeLabelW
+#define UpdateResource UpdateResourceW
+#define VerifyVersionInfo VerifyVersionInfoW
+#define WaitNamedPipe WaitNamedPipeW
+#define WritePrivateProfileSection WritePrivateProfileSectionW
+#define WritePrivateProfileString WritePrivateProfileStringW
+#define WritePrivateProfileStruct WritePrivateProfileStructW
+#define WriteProfileSection WriteProfileSectionW
+#define WriteProfileString WriteProfileStringW
+#else
+typedef STARTUPINFOA STARTUPINFO,*LPSTARTUPINFO;
+typedef WIN32_FIND_DATAA WIN32_FIND_DATA,*LPWIN32_FIND_DATA;
+typedef HW_PROFILE_INFOA HW_PROFILE_INFO,*LPHW_PROFILE_INFO;
+#define AccessCheckAndAuditAlarm AccessCheckAndAuditAlarmA
+#define AddAtom AddAtomA
+#define BackupEventLog BackupEventLogA
+#define BeginUpdateResource BeginUpdateResourceA
+#define BuildCommDCB BuildCommDCBA
+#define BuildCommDCBAndTimeouts BuildCommDCBAndTimeoutsA
+#define CallNamedPipe CallNamedPipeA
+#define ClearEventLog ClearEventLogA
+#define CommConfigDialog CommConfigDialogA
+#define CopyFile CopyFileA
+#define CopyFileEx CopyFileExA
+#define CreateDirectory CreateDirectoryA
+#define CreateDirectoryEx CreateDirectoryExA
+#define CreateEvent CreateEventA
+#define CreateFile CreateFileA
+#define CreateFileMapping CreateFileMappingA
+#define CreateHardLink CreateHardLinkA
+#define CreateMailslot CreateMailslotA
+#define CreateMutex CreateMutexA
+#define CreateNamedPipe CreateNamedPipeA
+#define CreateProcess CreateProcessA
+#define CreateProcessAsUser CreateProcessAsUserA
+#define CreateSemaphore CreateSemaphoreA
+#define CreateWaitableTimer CreateWaitableTimerA
+#define DefineDosDevice DefineDosDeviceA
+#define DeleteFile DeleteFileA
+#define EndUpdateResource EndUpdateResourceA
+#define EnumResourceLanguages EnumResourceLanguagesA
+#define EnumResourceNames EnumResourceNamesA
+#define EnumResourceTypes EnumResourceTypesA
+#define ExpandEnvironmentStrings ExpandEnvironmentStringsA
+#define FatalAppExit FatalAppExitA
+#define FindAtom FindAtomA
+#define FindFirstChangeNotification FindFirstChangeNotificationA
+#define FindFirstFile FindFirstFileA
+#define FindFirstFileEx FindFirstFileExW
+#define FindNextFile FindNextFileA
+#define FindResource FindResourceA
+#define FindResourceEx FindResourceExA
+#define FormatMessage FormatMessageA
+#define FreeEnvironmentStrings FreeEnvironmentStringsA
+#define GetAtomName GetAtomNameA
+#define GetBinaryType GetBinaryTypeA
+#define GetCommandLine GetCommandLineA
+#define GetComputerName GetComputerNameA
+#define GetCompressedFileSize GetCompressedFileSizeA
+#define GetCurrentDirectory GetCurrentDirectoryA
+#define GetDefaultCommConfig GetDefaultCommConfigA
+#define GetDiskFreeSpace GetDiskFreeSpaceA
+#define GetDiskFreeSpaceEx GetDiskFreeSpaceExA
+#define GetDriveType GetDriveTypeA
+#define GetEnvironmentStringsA GetEnvironmentStrings
+#define GetEnvironmentVariable GetEnvironmentVariableA
+#define GetFileAttributes GetFileAttributesA
+#define GetFileSecurity GetFileSecurityA
+#define GetFileAttributesEx GetFileAttributesExA
+#define GetFullPathName GetFullPathNameA
+#define GetLogicalDriveStrings GetLogicalDriveStringsA
+#define GetLongPathName GetLongPathNameA
+#define GetNamedPipeHandleState GetNamedPipeHandleStateA
+#define GetModuleHandle GetModuleHandleA
+#define GetModuleFileName GetModuleFileNameA
+#define GetPrivateProfileInt GetPrivateProfileIntA
+#define GetPrivateProfileSection GetPrivateProfileSectionA
+#define GetPrivateProfileSectionNames GetPrivateProfileSectionNamesA
+#define GetPrivateProfileString GetPrivateProfileStringA
+#define GetPrivateProfileStruct GetPrivateProfileStructA
+#define GetProfileInt GetProfileIntA
+#define GetProfileSection GetProfileSectionA
+#define GetProfileString GetProfileStringA
+#define GetShortPathName GetShortPathNameA
+#define GetStartupInfo GetStartupInfoA
+#define GetSystemDirectory GetSystemDirectoryA
+#define GetTempFileName GetTempFileNameA
+#define GetTempPath GetTempPathA
+#define GetUserName GetUserNameA
+#define GetVersionEx GetVersionExA
+#define GetVolumeInformation GetVolumeInformationA
+#define GetWindowsDirectory GetWindowsDirectoryA
+#define GlobalAddAtom GlobalAddAtomA
+#define GlobalFindAtom GlobalFindAtomA
+#define GlobalGetAtomName GlobalGetAtomNameA
+#define IsBadStringPtr IsBadStringPtrA
+#define LoadLibrary LoadLibraryA
+#define LoadLibraryEx LoadLibraryExA
+#define LogonUser LogonUserA
+#define LookupAccountName LookupAccountNameA
+#define LookupAccountSid LookupAccountSidA
+#define LookupPrivilegeDisplayName LookupPrivilegeDisplayNameA
+#define LookupPrivilegeName LookupPrivilegeNameA
+#define LookupPrivilegeValue LookupPrivilegeValueA
+#define lstrcat lstrcatA
+#define lstrcmp lstrcmpA
+#define lstrcmpi lstrcmpiA
+#define lstrcpy lstrcpyA
+#define lstrcpyn lstrcpynA
+#define lstrlen lstrlenA
+#define MoveFile MoveFileA
+#define MoveFileEx MoveFileExA
+#define ObjectCloseAuditAlarm ObjectCloseAuditAlarmA
+#define ObjectDeleteAuditAlarm ObjectDeleteAuditAlarmA
+#define ObjectOpenAuditAlarm ObjectOpenAuditAlarmA
+#define ObjectPrivilegeAuditAlarm ObjectPrivilegeAuditAlarmA
+#define OpenBackupEventLog OpenBackupEventLogA
+#define OpenEvent OpenEventA
+#define OpenEventLog OpenEventLogA
+#define OpenFileMapping OpenFileMappingA
+#define OpenMutex OpenMutexA
+#define OpenSemaphore OpenSemaphoreA
+#define OutputDebugString OutputDebugStringA
+#define PrivilegedServiceAuditAlarm PrivilegedServiceAuditAlarmA
+#define QueryDosDevice QueryDosDeviceA
+#define ReadEventLog ReadEventLogA
+#define RegisterEventSource RegisterEventSourceA
+#define RemoveDirectory RemoveDirectoryA
+#define ReportEvent ReportEventA
+#define SearchPath SearchPathA
+#define SetComputerName SetComputerNameA
+#define SetCurrentDirectory SetCurrentDirectoryA
+#define SetDefaultCommConfig SetDefaultCommConfigA
+#define SetEnvironmentVariable SetEnvironmentVariableA
+#define SetFileAttributes SetFileAttributesA
+#define SetFileSecurity SetFileSecurityA
+#define SetVolumeLabel SetVolumeLabelA
+#define UpdateResource UpdateResourceA
+#define VerifyVersionInfo VerifyVersionInfoA
+#define WaitNamedPipe WaitNamedPipeA
+#define WritePrivateProfileSection WritePrivateProfileSectionA
+#define WritePrivateProfileString WritePrivateProfileStringA
+#define WritePrivateProfileStruct WritePrivateProfileStructA
+#define WriteProfileSection WriteProfileSectionA
+#define WriteProfileString WriteProfileStringA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _WINBASE_H */
diff --git a/tinyc/win32/include/winapi/wincon.h b/tinyc/win32/include/winapi/wincon.h
new file mode 100755
index 000000000..8539fe5c6
--- /dev/null
+++ b/tinyc/win32/include/winapi/wincon.h
@@ -0,0 +1,207 @@
+#ifndef _WINCON_H
+#define _WINCON_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FOREGROUND_BLUE	1
+#define FOREGROUND_GREEN	2
+#define FOREGROUND_RED	4
+#define FOREGROUND_INTENSITY	8
+#define BACKGROUND_BLUE	16
+#define BACKGROUND_GREEN	32
+#define BACKGROUND_RED	64
+#define BACKGROUND_INTENSITY	128
+#define CTRL_C_EVENT 0
+#define CTRL_BREAK_EVENT 1
+#define CTRL_CLOSE_EVENT 2
+#define CTRL_LOGOFF_EVENT 5
+#define CTRL_SHUTDOWN_EVENT 6
+#define ENABLE_LINE_INPUT 2
+#define ENABLE_ECHO_INPUT 4
+#define ENABLE_PROCESSED_INPUT 1
+#define ENABLE_WINDOW_INPUT 8
+#define ENABLE_MOUSE_INPUT 16
+#define ENABLE_PROCESSED_OUTPUT 1
+#define ENABLE_WRAP_AT_EOL_OUTPUT 2
+#define KEY_EVENT 1
+#define MOUSE_EVENT 2
+#define WINDOW_BUFFER_SIZE_EVENT 4
+#define MENU_EVENT 8
+#define FOCUS_EVENT 16
+#define CAPSLOCK_ON 128
+#define ENHANCED_KEY 256
+#define RIGHT_ALT_PRESSED 1
+#define LEFT_ALT_PRESSED 2
+#define RIGHT_CTRL_PRESSED 4
+#define LEFT_CTRL_PRESSED 8
+#define SHIFT_PRESSED 16
+#define NUMLOCK_ON 32
+#define SCROLLLOCK_ON 64
+#define FROM_LEFT_1ST_BUTTON_PRESSED 1
+#define RIGHTMOST_BUTTON_PRESSED 2
+#define FROM_LEFT_2ND_BUTTON_PRESSED 4
+#define FROM_LEFT_3RD_BUTTON_PRESSED 8
+#define FROM_LEFT_4TH_BUTTON_PRESSED 16
+#define MOUSE_MOVED	1
+#define DOUBLE_CLICK	2
+#define MOUSE_WHEELED	4
+
+typedef struct _CHAR_INFO {
+	union {
+		WCHAR UnicodeChar;
+		CHAR AsciiChar;
+	} Char;
+	WORD Attributes;
+} CHAR_INFO,*PCHAR_INFO;
+typedef struct _SMALL_RECT {
+	SHORT Left;
+	SHORT Top;
+	SHORT Right;
+	SHORT Bottom;
+} SMALL_RECT,*PSMALL_RECT;
+typedef struct _CONSOLE_CURSOR_INFO {
+	DWORD	dwSize;
+	BOOL	bVisible;
+} CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO;
+typedef struct _COORD {
+	SHORT X;
+	SHORT Y;
+} COORD;
+typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
+	COORD	dwSize;
+	COORD	dwCursorPosition;
+	WORD	wAttributes;
+	SMALL_RECT srWindow;
+	COORD	dwMaximumWindowSize;
+} CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO;
+typedef BOOL(CALLBACK *PHANDLER_ROUTINE)(DWORD);
+typedef struct _KEY_EVENT_RECORD {
+	BOOL bKeyDown;
+	WORD wRepeatCount;
+	WORD wVirtualKeyCode;
+	WORD wVirtualScanCode;
+	union {
+		WCHAR UnicodeChar;
+		CHAR AsciiChar;
+	} uChar;
+	DWORD dwControlKeyState;
+} 
+#ifdef __GNUC__
+/* gcc's alignment is not what win32 expects */
+ PACKED
+#endif
+KEY_EVENT_RECORD;
+
+typedef struct _MOUSE_EVENT_RECORD {
+	COORD dwMousePosition;
+	DWORD dwButtonState;
+	DWORD dwControlKeyState;
+	DWORD dwEventFlags;
+} MOUSE_EVENT_RECORD;
+typedef struct _WINDOW_BUFFER_SIZE_RECORD {	COORD dwSize; } WINDOW_BUFFER_SIZE_RECORD;
+typedef struct _MENU_EVENT_RECORD {	UINT dwCommandId; } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD;
+typedef struct _FOCUS_EVENT_RECORD { BOOL bSetFocus; } FOCUS_EVENT_RECORD;
+typedef struct _INPUT_RECORD {
+	WORD EventType;
+	union {
+		KEY_EVENT_RECORD KeyEvent;
+		MOUSE_EVENT_RECORD MouseEvent;
+		WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
+		MENU_EVENT_RECORD MenuEvent;
+		FOCUS_EVENT_RECORD FocusEvent;
+	} Event;
+} INPUT_RECORD,*PINPUT_RECORD;
+
+BOOL WINAPI AllocConsole(void);
+HANDLE WINAPI CreateConsoleScreenBuffer(DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,PVOID);
+BOOL WINAPI FillConsoleOutputAttribute(HANDLE,WORD,DWORD,COORD,PDWORD);
+BOOL WINAPI FillConsoleOutputCharacterA(HANDLE,CHAR,DWORD,COORD,PDWORD);
+BOOL WINAPI FillConsoleOutputCharacterW(HANDLE,WCHAR,DWORD,COORD,PDWORD);
+BOOL WINAPI FlushConsoleInputBuffer(HANDLE);
+BOOL WINAPI FreeConsole(void);
+BOOL WINAPI GenerateConsoleCtrlEvent(DWORD,DWORD);
+UINT WINAPI GetConsoleCP(void);
+BOOL WINAPI GetConsoleCursorInfo(HANDLE,PCONSOLE_CURSOR_INFO);
+BOOL WINAPI GetConsoleMode(HANDLE,PDWORD);
+UINT WINAPI GetConsoleOutputCP(void);
+BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE,PCONSOLE_SCREEN_BUFFER_INFO);
+DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD);
+DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD);
+COORD WINAPI GetLargestConsoleWindowSize(HANDLE);
+BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,PDWORD);
+BOOL WINAPI GetNumberOfConsoleMouseButtons(PDWORD);
+BOOL WINAPI PeekConsoleInputA(HANDLE,PINPUT_RECORD,DWORD,PDWORD);
+BOOL WINAPI PeekConsoleInputW(HANDLE,PINPUT_RECORD,DWORD,PDWORD);
+BOOL WINAPI ReadConsoleA(HANDLE,PVOID,DWORD,PDWORD,PVOID);
+BOOL WINAPI ReadConsoleW(HANDLE,PVOID,DWORD,PDWORD,PVOID);
+BOOL WINAPI ReadConsoleInputA(HANDLE,PINPUT_RECORD,DWORD,PDWORD);
+BOOL WINAPI ReadConsoleInputW(HANDLE,PINPUT_RECORD,DWORD,PDWORD);
+BOOL WINAPI ReadConsoleOutputAttribute(HANDLE,LPWORD,DWORD,COORD,LPDWORD);
+BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE,LPSTR,DWORD,COORD,PDWORD);
+BOOL WINAPI ReadConsoleOutputCharacterW(HANDLE,LPWSTR,DWORD,COORD,PDWORD);
+BOOL WINAPI ReadConsoleOutputA(HANDLE,PCHAR_INFO,COORD,COORD,PSMALL_RECT);
+BOOL WINAPI ReadConsoleOutputW(HANDLE,PCHAR_INFO,COORD,COORD,PSMALL_RECT);
+BOOL WINAPI ScrollConsoleScreenBufferA(HANDLE,const SMALL_RECT*,const SMALL_RECT*,COORD,const CHAR_INFO*);
+BOOL WINAPI ScrollConsoleScreenBufferW(HANDLE,const SMALL_RECT*,const SMALL_RECT*,COORD,const CHAR_INFO*);
+BOOL WINAPI SetConsoleActiveScreenBuffer(HANDLE);
+BOOL WINAPI SetConsoleCP(UINT);
+BOOL WINAPI SetConsoleCtrlHandler(PHANDLER_ROUTINE,BOOL);
+BOOL WINAPI SetConsoleCursorInfo(HANDLE,const CONSOLE_CURSOR_INFO*);
+BOOL WINAPI SetConsoleCursorPosition(HANDLE,COORD);
+BOOL WINAPI SetConsoleMode(HANDLE,DWORD);
+BOOL WINAPI SetConsoleOutputCP(UINT);
+BOOL WINAPI SetConsoleScreenBufferSize(HANDLE,COORD);
+BOOL WINAPI SetConsoleTextAttribute(HANDLE,WORD);
+BOOL WINAPI SetConsoleTitleA(LPCSTR);
+BOOL WINAPI SetConsoleTitleW(LPCWSTR);
+BOOL WINAPI SetConsoleWindowInfo(HANDLE,BOOL,const SMALL_RECT*);
+BOOL WINAPI WriteConsoleA(HANDLE,PCVOID,DWORD,PDWORD,PVOID);
+BOOL WINAPI WriteConsoleW(HANDLE,PCVOID,DWORD,PDWORD,PVOID);
+BOOL WINAPI WriteConsoleInputA(HANDLE,const INPUT_RECORD*,DWORD,PDWORD);
+BOOL WINAPI WriteConsoleInputW(HANDLE,const INPUT_RECORD*,DWORD,PDWORD);
+BOOL WINAPI WriteConsoleOutputA(HANDLE,const CHAR_INFO*,COORD,COORD,PSMALL_RECT);
+BOOL WINAPI WriteConsoleOutputW(HANDLE,const CHAR_INFO*,COORD,COORD,PSMALL_RECT);
+BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,const WORD*,DWORD,COORD,PDWORD);
+BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,PDWORD);
+BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE,LPCWSTR,DWORD,COORD,PDWORD);
+
+#ifdef UNICODE
+#define FillConsoleOutputCharacter FillConsoleOutputCharacterW
+#define GetConsoleTitle GetConsoleTitleW
+#define PeekConsoleInput PeekConsoleInputW
+#define ReadConsole ReadConsoleW
+#define ReadConsoleInput ReadConsoleInputW
+#define ReadConsoleOutput ReadConsoleOutputW
+#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterW
+#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferW
+#define SetConsoleTitle SetConsoleTitleW
+#define WriteConsole WriteConsoleW
+#define WriteConsoleInput WriteConsoleInputW
+#define WriteConsoleOutput WriteConsoleOutputW
+#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterW
+#else
+#define FillConsoleOutputCharacter FillConsoleOutputCharacterA
+#define GetConsoleTitle GetConsoleTitleA
+#define PeekConsoleInput PeekConsoleInputA
+#define ReadConsole ReadConsoleA
+#define ReadConsoleInput ReadConsoleInputA
+#define ReadConsoleOutput ReadConsoleOutputA
+#define ReadConsoleOutputCharacter ReadConsoleOutputCharacterA
+#define ScrollConsoleScreenBuffer ScrollConsoleScreenBufferA
+#define SetConsoleTitle SetConsoleTitleA
+#define WriteConsole WriteConsoleA
+#define WriteConsoleInput WriteConsoleInputA
+#define WriteConsoleOutput WriteConsoleOutputA
+#define WriteConsoleOutputCharacter WriteConsoleOutputCharacterA
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/windef.h b/tinyc/win32/include/winapi/windef.h
new file mode 100755
index 000000000..1ee3f39f6
--- /dev/null
+++ b/tinyc/win32/include/winapi/windef.h
@@ -0,0 +1,240 @@
+#ifndef _WINDEF_H
+#define _WINDEF_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WINVER
+#define WINVER 0x0400
+#endif
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT WINVER
+#endif
+#ifndef WIN32
+#define WIN32
+#endif
+#ifndef _WIN32
+#define _WIN32
+#endif
+#define FAR
+#define far
+#define NEAR
+#define near
+#ifndef CONST
+#define CONST const
+#endif
+#undef MAX_PATH
+#define MAX_PATH 260
+
+#ifndef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void*)0)
+#endif
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#define IN
+#define OUT
+#ifndef OPTIONAL
+#define OPTIONAL
+#endif
+
+#ifdef __GNUC__
+#define PACKED __attribute__((packed))
+#ifndef _stdcall
+#define _stdcall __attribute__((stdcall))
+#endif
+#ifndef __stdcall
+#define __stdcall __attribute__((stdcall))
+#endif
+#ifndef _cdecl
+#define _cdecl __attribute__((cdecl))
+#endif
+#ifndef __cdecl
+#define __cdecl __attribute__((cdecl))
+#endif
+#ifndef __declspec
+#define __declspec(e) __attribute__((e))
+#endif
+#ifndef _declspec
+#define _declspec(e) __attribute__((e))
+#endif
+#else
+#define PACKED
+#define _cdecl
+#define __cdecl
+#endif
+
+#undef pascal
+#undef _pascal
+#undef __pascal
+#define pascal __stdcall
+#define _pascal __stdcall
+#define __pascal __stdcall
+#define PASCAL _pascal
+#define CDECL _cdecl
+#define STDCALL __stdcall
+#define WINAPI __stdcall
+#define WINAPIV __cdecl
+#define APIENTRY __stdcall
+#define CALLBACK __stdcall
+#define APIPRIVATE __stdcall
+
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#define DECLSPEC_EXPORT __declspec(dllexport)
+#ifdef __GNUC__
+#define DECLSPEC_NORETURN __declspec(noreturn)
+#define DECLARE_STDCALL_P( type ) __stdcall type
+#elif defined(__WATCOMC__)
+#define DECLSPEC_NORETURN
+#define DECLARE_STDCALL_P( type ) type __stdcall
+#endif /* __GNUC__/__WATCOMC__ */
+#define MAKEWORD(a,b)	((WORD)(((BYTE)(a))|(((WORD)((BYTE)(b)))<<8)))
+#define MAKELONG(a,b)	((LONG)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16)))
+#define LOWORD(l)	((WORD)((DWORD)(l)))
+#define HIWORD(l)	((WORD)(((DWORD)(l)>>16)&0xFFFF))
+#define LOBYTE(w)	((BYTE)(w))
+#define HIBYTE(w)	((BYTE)(((WORD)(w)>>8)&0xFF))
+
+#ifndef _export
+#define _export
+#endif
+#ifndef __export
+#define __export
+#endif
+
+#ifndef NOMINMAX
+#ifndef max
+#define max(a,b) ((a)>(b)?(a):(b))
+#endif
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+#endif
+
+#define UNREFERENCED_PARAMETER(P) {(P)=(P);}
+#define UNREFERENCED_LOCAL_VARIABLE(L) {(L)=(L);}
+#define DBG_UNREFERENCED_PARAMETER(P)
+#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
+
+typedef unsigned long DWORD;
+typedef int WINBOOL,*PWINBOOL,*LPWINBOOL;
+/* FIXME: Is there a good solution to this? */
+#ifndef XFree86Server
+#ifndef __OBJC__
+typedef WINBOOL BOOL;
+#else
+#define BOOL WINBOOL
+#endif
+typedef unsigned char BYTE;
+#endif /* ndef XFree86Server */
+typedef BOOL *PBOOL,*LPBOOL;
+typedef unsigned short WORD;
+typedef float FLOAT;
+typedef FLOAT *PFLOAT;
+typedef BYTE *PBYTE,*LPBYTE;
+typedef int *PINT,*LPINT;
+typedef WORD *PWORD,*LPWORD;
+typedef long *LPLONG;
+typedef DWORD *PDWORD,*LPDWORD;
+typedef void *PVOID,*LPVOID;
+typedef CONST void *PCVOID,*LPCVOID;
+typedef int INT;
+typedef unsigned int UINT,*PUINT,*LPUINT;
+
+#include <winnt.h>
+
+typedef UINT WPARAM;
+typedef LONG LPARAM;
+typedef LONG LRESULT;
+#ifndef _HRESULT_DEFINED
+typedef LONG HRESULT;
+#define _HRESULT_DEFINED
+#endif
+#ifndef XFree86Server
+typedef WORD ATOM;
+#endif /* XFree86Server */
+typedef HANDLE HGLOBAL;
+typedef HANDLE HLOCAL;
+typedef HANDLE GLOBALHANDLE;
+typedef HANDLE LOCALHANDLE;
+typedef void *HGDIOBJ;
+DECLARE_HANDLE(HACCEL);
+DECLARE_HANDLE(HBITMAP);
+DECLARE_HANDLE(HBRUSH);
+DECLARE_HANDLE(HCOLORSPACE);
+DECLARE_HANDLE(HDC);
+DECLARE_HANDLE(HGLRC);
+DECLARE_HANDLE(HDESK);
+DECLARE_HANDLE(HENHMETAFILE);
+DECLARE_HANDLE(HFONT);
+DECLARE_HANDLE(HICON);
+DECLARE_HANDLE(HKEY);
+/* FIXME: How to handle these. SM_CMONITORS etc in winuser.h also. */
+/* #if (WINVER >= 0x0500) */
+DECLARE_HANDLE(HMONITOR);
+#define HMONITOR_DECLARED 1
+DECLARE_HANDLE(HTERMINAL);
+DECLARE_HANDLE(HWINEVENTHOOK);
+/* #endif */
+typedef HKEY *PHKEY;
+DECLARE_HANDLE(HMENU);
+DECLARE_HANDLE(HMETAFILE);
+DECLARE_HANDLE(HINSTANCE);
+typedef HINSTANCE HMODULE;
+DECLARE_HANDLE(HPALETTE);
+DECLARE_HANDLE(HPEN);
+DECLARE_HANDLE(HRGN);
+DECLARE_HANDLE(HRSRC);
+DECLARE_HANDLE(HSTR);
+DECLARE_HANDLE(HTASK);
+DECLARE_HANDLE(HWND);
+DECLARE_HANDLE(HWINSTA);
+DECLARE_HANDLE(HKL);
+typedef int HFILE;
+typedef HICON HCURSOR;
+typedef DWORD COLORREF;
+typedef int (WINAPI *FARPROC)();
+typedef int (WINAPI *NEARPROC)();
+typedef int (WINAPI *PROC)();
+typedef struct tagRECT {
+	LONG left;
+	LONG top;
+	LONG right;
+	LONG bottom;
+} RECT,*PRECT,*LPRECT;
+typedef const RECT *LPCRECT;
+typedef struct tagRECTL {
+	LONG left;
+	LONG top;
+	LONG right;
+	LONG bottom;
+} RECTL,*PRECTL,*LPRECTL;
+typedef const RECTL *LPCRECTL;
+typedef struct tagPOINT {
+	LONG x;
+	LONG y;
+} POINT,POINTL,*PPOINT,*LPPOINT,*PPOINTL,*LPPOINTL;
+typedef struct tagSIZE {
+	LONG cx;
+	LONG cy;
+} SIZE,SIZEL,*PSIZE,*LPSIZE,*PSIZEL,*LPSIZEL;
+typedef struct tagPOINTS {
+	SHORT x;
+	SHORT y;
+} POINTS,*PPOINTS,*LPPOINTS;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/windows.h b/tinyc/win32/include/winapi/windows.h
new file mode 100755
index 000000000..de2cf9b85
--- /dev/null
+++ b/tinyc/win32/include/winapi/windows.h
@@ -0,0 +1,176 @@
+/*
+	windows.h - main header file for the Win32 API
+
+	Written by Anders Norlander <anorland@hem2.passagen.se>
+
+	This file is part of a free library for the Win32 API.
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+*/
+#ifndef _WINDOWS_H
+#define _WINDOWS_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+/* translate GCC target defines to MS equivalents. Keep this synchronized
+   with winnt.h. */
+#if defined(__i686__) && !defined(_M_IX86)
+#define _M_IX86 600
+#elif defined(__i586__) && !defined(_M_IX86)
+#define _M_IX86 500
+#elif defined(__i486__) && !defined(_M_IX86)
+#define _M_IX86 400
+#elif defined(__i386__) && !defined(_M_IX86)
+#define _M_IX86 300
+#endif
+#if defined(_M_IX86) && !defined(_X86_)
+#define _X86_
+#elif defined(_M_ALPHA) && !defined(_ALPHA_)
+#define _ALPHA_
+#elif defined(_M_PPC) && !defined(_PPC_)
+#define _PPC_
+#elif defined(_M_MRX000) && !defined(_MIPS_)
+#define _MIPS_
+#elif defined(_M_M68K) && !defined(_68K_)
+#define _68K_
+#endif
+
+#ifdef RC_INVOKED
+/* winresrc.h includes the necessary headers */
+#include <winresrc.h>
+#else
+
+#ifdef __GNUC__
+#ifndef NONAMELESSUNION
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) 
+#define _ANONYMOUS_UNION __extension__
+#define _ANONYMOUS_STRUCT __extension__
+#else
+#if defined(__cplusplus)
+#define _ANONYMOUS_UNION __extension__
+#endif /* __cplusplus */
+#endif /* __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) */
+#endif /* NONAMELESSUNION */
+#elif defined(__WATCOMC__)
+#define _ANONYMOUS_UNION
+#define _ANONYMOUS_STRUCT
+#endif /* __GNUC__/__WATCOMC__ */
+
+#ifndef _ANONYMOUS_UNION
+#define _ANONYMOUS_UNION
+#define _UNION_NAME(x) x
+#define DUMMYUNIONNAME	u
+#define DUMMYUNIONNAME2	u2
+#define DUMMYUNIONNAME3	u3
+#define DUMMYUNIONNAME4	u4
+#define DUMMYUNIONNAME5	u5
+#define DUMMYUNIONNAME6	u6
+#define DUMMYUNIONNAME7	u7
+#define DUMMYUNIONNAME8	u8
+#else
+#define _UNION_NAME(x)
+#define DUMMYUNIONNAME
+#define DUMMYUNIONNAME2
+#define DUMMYUNIONNAME3
+#define DUMMYUNIONNAME4
+#define DUMMYUNIONNAME5
+#define DUMMYUNIONNAME6
+#define DUMMYUNIONNAME7
+#define DUMMYUNIONNAME8
+#endif
+#ifndef _ANONYMOUS_STRUCT
+#define _ANONYMOUS_STRUCT
+#define _STRUCT_NAME(x) x
+#define DUMMYSTRUCTNAME	s
+#define DUMMYSTRUCTNAME2 s2
+#define DUMMYSTRUCTNAME3 s3
+#else
+#define _STRUCT_NAME(x)
+#define DUMMYSTRUCTNAME
+#define DUMMYSTRUCTNAME2
+#define DUMMYSTRUCTNAME3
+#endif
+
+#ifndef NO_STRICT
+#ifndef STRICT
+#define STRICT 1
+#endif
+#endif
+
+#include <stdarg.h>
+#include <windef.h>
+#include <wincon.h>
+#include <basetyps.h>
+#include <excpt.h>
+#include <winbase.h>
+#ifndef _WINGDI_H
+#include <wingdi.h>
+#endif
+#ifndef _WINUSER_H
+#include <winuser.h>
+#endif
+#ifndef _WINNLS_H
+#include <winnls.h>
+#endif
+#ifndef _WINVER_H
+#include <winver.h>
+#endif
+#ifndef _WINNETWK_H
+#include <winnetwk.h>
+#endif
+#ifndef _WINREG_H
+#include <winreg.h>
+#endif
+#ifndef _WINSVC_H
+#include <winsvc.h>
+#endif
+
+#ifndef WIN32_LEAN_AND_MEAN
+#include <commdlg.h>
+#include <cderr.h>
+#include <dde.h>
+#include <ddeml.h>
+#include <dlgs.h>
+#include <lzexpand.h>
+#include <mmsystem.h>
+#include <nb30.h>
+#include <rpc.h>
+#include <shellapi.h>
+#include <winperf.h>
+#include <winspool.h>
+#if defined(Win32_Winsock)
+#warning "The  Win32_Winsock macro name is deprecated.\
+    Please use __USE_W32_SOCKETS instead"
+#ifndef __USE_W32_SOCKETS
+#define __USE_W32_SOCKETS
+#endif
+#endif
+#if defined(__USE_W32_SOCKETS) || !(defined(__CYGWIN__) || defined(__MSYS__) || defined(_UWIN))
+#if (_WIN32_WINNT >= 0x0400)
+#include <winsock2.h>
+/*
+ * MS likes to include mswsock.h here as well,
+ * but that can cause undefined symbols if
+ * winsock2.h is included before windows.h
+ */
+#else
+#include <winsock.h>
+#endif /*  (_WIN32_WINNT >= 0x0400) */
+#endif
+#endif /* WIN32_LEAN_AND_MEAN */
+
+#endif /* RC_INVOKED */
+
+#ifdef __OBJC__
+/* FIXME: Not undefining BOOL here causes all BOOLs to be WINBOOL (int),
+   but undefining it causes trouble as well if a file is included after
+   windows.h
+*/
+#undef BOOL
+#endif
+
+#endif
diff --git a/tinyc/win32/include/winapi/winerror.h b/tinyc/win32/include/winapi/winerror.h
new file mode 100755
index 000000000..8865d9782
--- /dev/null
+++ b/tinyc/win32/include/winapi/winerror.h
@@ -0,0 +1,1054 @@
+#ifndef _WINERROR_H
+#define _WINERROR_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#define ERROR_SUCCESS 0L
+#define NO_ERROR 0L
+#define ERROR_INVALID_FUNCTION 1L
+#define ERROR_FILE_NOT_FOUND 2L
+#define ERROR_PATH_NOT_FOUND 3L
+#define ERROR_TOO_MANY_OPEN_FILES 4L
+#define ERROR_ACCESS_DENIED 5L
+#define ERROR_INVALID_HANDLE 6L
+#define ERROR_ARENA_TRASHED 7L
+#define ERROR_NOT_ENOUGH_MEMORY 8L
+#define ERROR_INVALID_BLOCK 9L
+#define ERROR_BAD_ENVIRONMENT 10L
+#define ERROR_BAD_FORMAT 11L
+#define ERROR_INVALID_ACCESS 12L
+#define ERROR_INVALID_DATA 13L
+#define ERROR_OUTOFMEMORY 14L
+#define ERROR_INVALID_DRIVE 15L
+#define ERROR_CURRENT_DIRECTORY 16L
+#define ERROR_NOT_SAME_DEVICE 17L
+#define ERROR_NO_MORE_FILES 18L
+#define ERROR_WRITE_PROTECT 19L
+#define ERROR_BAD_UNIT 20L
+#define ERROR_NOT_READY 21L
+#define ERROR_BAD_COMMAND 22L
+#define ERROR_CRC 23L
+#define ERROR_BAD_LENGTH 24L
+#define ERROR_SEEK 25L
+#define ERROR_NOT_DOS_DISK 26L
+#define ERROR_SECTOR_NOT_FOUND 27L
+#define ERROR_OUT_OF_PAPER 28L
+#define ERROR_WRITE_FAULT 29L
+#define ERROR_READ_FAULT 30L
+#define ERROR_GEN_FAILURE 31L
+#define ERROR_SHARING_VIOLATION 32L
+#define ERROR_LOCK_VIOLATION 33L
+#define ERROR_WRONG_DISK 34L
+#define ERROR_SHARING_BUFFER_EXCEEDED 36L
+#define ERROR_HANDLE_EOF 38L
+#define ERROR_HANDLE_DISK_FULL 39L
+#define ERROR_NOT_SUPPORTED 50L
+#define ERROR_REM_NOT_LIST 51L
+#define ERROR_DUP_NAME 52L
+#define ERROR_BAD_NETPATH 53L
+#define ERROR_NETWORK_BUSY 54L
+#define ERROR_DEV_NOT_EXIST 55L
+#define ERROR_TOO_MANY_CMDS 56L
+#define ERROR_ADAP_HDW_ERR 57L
+#define ERROR_BAD_NET_RESP 58L
+#define ERROR_UNEXP_NET_ERR 59L
+#define ERROR_BAD_REM_ADAP 60L
+#define ERROR_PRINTQ_FULL 61L
+#define ERROR_NO_SPOOL_SPACE 62L
+#define ERROR_PRINT_CANCELLED 63L
+#define ERROR_NETNAME_DELETED 64L
+#define ERROR_NETWORK_ACCESS_DENIED 65L
+#define ERROR_BAD_DEV_TYPE 66L
+#define ERROR_BAD_NET_NAME 67L
+#define ERROR_TOO_MANY_NAMES 68L
+#define ERROR_TOO_MANY_SESS 69L
+#define ERROR_SHARING_PAUSED 70L
+#define ERROR_REQ_NOT_ACCEP 71L
+#define ERROR_REDIR_PAUSED 72L
+#define ERROR_FILE_EXISTS 80L
+#define ERROR_CANNOT_MAKE 82L
+#define ERROR_FAIL_I24 83L
+#define ERROR_OUT_OF_STRUCTURES 84L
+#define ERROR_ALREADY_ASSIGNED 85L
+#define ERROR_INVALID_PASSWORD 86L
+#define ERROR_INVALID_PARAMETER 87L
+#define ERROR_NET_WRITE_FAULT 88L
+#define ERROR_NO_PROC_SLOTS 89L
+#define ERROR_TOO_MANY_SEMAPHORES 100L
+#define ERROR_EXCL_SEM_ALREADY_OWNED 101L
+#define ERROR_SEM_IS_SET 102L
+#define ERROR_TOO_MANY_SEM_REQUESTS 103L
+#define ERROR_INVALID_AT_INTERRUPT_TIME 104L
+#define ERROR_SEM_OWNER_DIED 105L
+#define ERROR_SEM_USER_LIMIT 106L
+#define ERROR_DISK_CHANGE 107L
+#define ERROR_DRIVE_LOCKED 108L
+#define ERROR_BROKEN_PIPE 109L
+#define ERROR_OPEN_FAILED 110L
+#define ERROR_BUFFER_OVERFLOW 111L
+#define ERROR_DISK_FULL 112L
+#define ERROR_NO_MORE_SEARCH_HANDLES 113L
+#define ERROR_INVALID_TARGET_HANDLE 114L
+#define ERROR_INVALID_CATEGORY 117L
+#define ERROR_INVALID_VERIFY_SWITCH 118L
+#define ERROR_BAD_DRIVER_LEVEL 119L
+#define ERROR_CALL_NOT_IMPLEMENTED 120L
+#define ERROR_SEM_TIMEOUT 121L
+#define ERROR_INSUFFICIENT_BUFFER 122L
+#define ERROR_INVALID_NAME 123L
+#define ERROR_INVALID_LEVEL 124L
+#define ERROR_NO_VOLUME_LABEL 125L
+#define ERROR_MOD_NOT_FOUND 126L
+#define ERROR_PROC_NOT_FOUND 127L
+#define ERROR_WAIT_NO_CHILDREN 128L
+#define ERROR_CHILD_NOT_COMPLETE 129L
+#define ERROR_DIRECT_ACCESS_HANDLE 130L
+#define ERROR_NEGATIVE_SEEK 131L
+#define ERROR_SEEK_ON_DEVICE 132L
+#define ERROR_IS_JOIN_TARGET 133L
+#define ERROR_IS_JOINED 134L
+#define ERROR_IS_SUBSTED 135L
+#define ERROR_NOT_JOINED 136L
+#define ERROR_NOT_SUBSTED 137L
+#define ERROR_JOIN_TO_JOIN 138L
+#define ERROR_SUBST_TO_SUBST 139L
+#define ERROR_JOIN_TO_SUBST 140L
+#define ERROR_SUBST_TO_JOIN 141L
+#define ERROR_BUSY_DRIVE 142L
+#define ERROR_SAME_DRIVE 143L
+#define ERROR_DIR_NOT_ROOT 144L
+#define ERROR_DIR_NOT_EMPTY 145L
+#define ERROR_IS_SUBST_PATH 146L
+#define ERROR_IS_JOIN_PATH 147L
+#define ERROR_PATH_BUSY 148L
+#define ERROR_IS_SUBST_TARGET 149L
+#define ERROR_SYSTEM_TRACE 150L
+#define ERROR_INVALID_EVENT_COUNT 151L
+#define ERROR_TOO_MANY_MUXWAITERS 152L
+#define ERROR_INVALID_LIST_FORMAT 153L
+#define ERROR_LABEL_TOO_LONG 154L
+#define ERROR_TOO_MANY_TCBS 155L
+#define ERROR_SIGNAL_REFUSED 156L
+#define ERROR_DISCARDED 157L
+#define ERROR_NOT_LOCKED 158L
+#define ERROR_BAD_THREADID_ADDR 159L
+#define ERROR_BAD_ARGUMENTS 160L
+#define ERROR_BAD_PATHNAME 161L
+#define ERROR_SIGNAL_PENDING 162L
+#define ERROR_MAX_THRDS_REACHED 164L
+#define ERROR_LOCK_FAILED 167L
+#define ERROR_BUSY 170L
+#define ERROR_CANCEL_VIOLATION 173L
+#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174L
+#define ERROR_INVALID_SEGMENT_NUMBER 180L
+#define ERROR_INVALID_ORDINAL 182L
+#define ERROR_ALREADY_EXISTS 183L
+#define ERROR_INVALID_FLAG_NUMBER 186L
+#define ERROR_SEM_NOT_FOUND 187L
+#define ERROR_INVALID_STARTING_CODESEG 188L
+#define ERROR_INVALID_STACKSEG 189L
+#define ERROR_INVALID_MODULETYPE 190L
+#define ERROR_INVALID_EXE_SIGNATURE 191L
+#define ERROR_EXE_MARKED_INVALID 192L
+#define ERROR_BAD_EXE_FORMAT 193L
+#define ERROR_ITERATED_DATA_EXCEEDS_64k 194L
+#define ERROR_INVALID_MINALLOCSIZE 195L
+#define ERROR_DYNLINK_FROM_INVALID_RING 196L
+#define ERROR_IOPL_NOT_ENABLED 197L
+#define ERROR_INVALID_SEGDPL 198L
+#define ERROR_AUTODATASEG_EXCEEDS_64k 199L
+#define ERROR_RING2SEG_MUST_BE_MOVABLE 200L
+#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201L
+#define ERROR_INFLOOP_IN_RELOC_CHAIN 202L
+#define ERROR_ENVVAR_NOT_FOUND 203L
+#define ERROR_NO_SIGNAL_SENT 205L
+#define ERROR_FILENAME_EXCED_RANGE 206L
+#define ERROR_RING2_STACK_IN_USE 207L
+#define ERROR_META_EXPANSION_TOO_LONG 208L
+#define ERROR_INVALID_SIGNAL_NUMBER 209L
+#define ERROR_THREAD_1_INACTIVE 210L
+#define ERROR_LOCKED 212L
+#define ERROR_TOO_MANY_MODULES 214L
+#define ERROR_NESTING_NOT_ALLOWED 215L
+#define ERROR_BAD_PIPE 230L
+#define ERROR_PIPE_BUSY 231L
+#define ERROR_NO_DATA 232L
+#define ERROR_PIPE_NOT_CONNECTED 233L
+#define ERROR_MORE_DATA 234L
+#define ERROR_VC_DISCONNECTED 240L
+#define ERROR_INVALID_EA_NAME 254L
+#define ERROR_EA_LIST_INCONSISTENT 255L
+#define ERROR_NO_MORE_ITEMS 259L
+#define ERROR_CANNOT_COPY 266L
+#define ERROR_DIRECTORY 267L
+#define ERROR_EAS_DIDNT_FIT 275L
+#define ERROR_EA_FILE_CORRUPT 276L
+#define ERROR_EA_TABLE_FULL 277L
+#define ERROR_INVALID_EA_HANDLE 278L
+#define ERROR_EAS_NOT_SUPPORTED 282L
+#define ERROR_NOT_OWNER 288L
+#define ERROR_TOO_MANY_POSTS 298L
+#define ERROR_PARTIAL_COPY 299L
+#define ERROR_MR_MID_NOT_FOUND 317L
+#define ERROR_INVALID_ADDRESS 487L
+#define ERROR_ARITHMETIC_OVERFLOW 534L
+#define ERROR_PIPE_CONNECTED 535L
+#define ERROR_PIPE_LISTENING 536L
+#define ERROR_EA_ACCESS_DENIED 994L
+#define ERROR_OPERATION_ABORTED 995L
+#define ERROR_IO_INCOMPLETE 996L
+#define ERROR_IO_PENDING 997L
+#define ERROR_NOACCESS 998L
+#define ERROR_SWAPERROR 999L
+#define ERROR_STACK_OVERFLOW 1001L
+#define ERROR_INVALID_MESSAGE 1002L
+#define ERROR_CAN_NOT_COMPLETE 1003L
+#define ERROR_INVALID_FLAGS 1004L
+#define ERROR_UNRECOGNIZED_VOLUME 1005L
+#define ERROR_FILE_INVALID 1006L
+#define ERROR_FULLSCREEN_MODE 1007L
+#define ERROR_NO_TOKEN 1008L
+#define ERROR_BADDB 1009L
+#define ERROR_BADKEY 1010L
+#define ERROR_CANTOPEN 1011L
+#define ERROR_CANTREAD 1012L
+#define ERROR_CANTWRITE 1013L
+#define ERROR_REGISTRY_RECOVERED 1014L
+#define ERROR_REGISTRY_CORRUPT 1015L
+#define ERROR_REGISTRY_IO_FAILED 1016L
+#define ERROR_NOT_REGISTRY_FILE 1017L
+#define ERROR_KEY_DELETED 1018L
+#define ERROR_NO_LOG_SPACE 1019L
+#define ERROR_KEY_HAS_CHILDREN 1020L
+#define ERROR_CHILD_MUST_BE_VOLATILE 1021L
+#define ERROR_NOTIFY_ENUM_DIR 1022L
+#define ERROR_DEPENDENT_SERVICES_RUNNING 1051L
+#define ERROR_INVALID_SERVICE_CONTROL 1052L
+#define ERROR_SERVICE_REQUEST_TIMEOUT 1053L
+#define ERROR_SERVICE_NO_THREAD 1054L
+#define ERROR_SERVICE_DATABASE_LOCKED 1055L
+#define ERROR_SERVICE_ALREADY_RUNNING 1056L
+#define ERROR_INVALID_SERVICE_ACCOUNT 1057L
+#define ERROR_SERVICE_DISABLED 1058L
+#define ERROR_CIRCULAR_DEPENDENCY 1059L
+#define ERROR_SERVICE_DOES_NOT_EXIST 1060L
+#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061L
+#define ERROR_SERVICE_NOT_ACTIVE 1062L
+#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063L
+#define ERROR_EXCEPTION_IN_SERVICE 1064L
+#define ERROR_DATABASE_DOES_NOT_EXIST 1065L
+#define ERROR_SERVICE_SPECIFIC_ERROR 1066L
+#define ERROR_PROCESS_ABORTED 1067L
+#define ERROR_SERVICE_DEPENDENCY_FAIL 1068L
+#define ERROR_SERVICE_LOGON_FAILED 1069L
+#define ERROR_SERVICE_START_HANG 1070L
+#define ERROR_INVALID_SERVICE_LOCK 1071L
+#define ERROR_SERVICE_MARKED_FOR_DELETE 1072L
+#define ERROR_SERVICE_EXISTS 1073L
+#define ERROR_ALREADY_RUNNING_LKG 1074L
+#define ERROR_SERVICE_DEPENDENCY_DELETED 1075L
+#define ERROR_BOOT_ALREADY_ACCEPTED 1076L
+#define ERROR_SERVICE_NEVER_STARTED 1077L
+#define ERROR_DUPLICATE_SERVICE_NAME 1078L
+#define ERROR_END_OF_MEDIA 1100L
+#define ERROR_FILEMARK_DETECTED 1101L
+#define ERROR_BEGINNING_OF_MEDIA 1102L
+#define ERROR_SETMARK_DETECTED 1103L
+#define ERROR_NO_DATA_DETECTED 1104L
+#define ERROR_PARTITION_FAILURE 1105L
+#define ERROR_INVALID_BLOCK_LENGTH 1106L
+#define ERROR_DEVICE_NOT_PARTITIONED 1107L
+#define ERROR_UNABLE_TO_LOCK_MEDIA 1108L
+#define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109L
+#define ERROR_MEDIA_CHANGED 1110L
+#define ERROR_BUS_RESET 1111L
+#define ERROR_NO_MEDIA_IN_DRIVE 1112L
+#define ERROR_NO_UNICODE_TRANSLATION 1113L
+#define ERROR_DLL_INIT_FAILED 1114L
+#define ERROR_SHUTDOWN_IN_PROGRESS 1115L
+#define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116L
+#define ERROR_IO_DEVICE 1117L
+#define ERROR_SERIAL_NO_DEVICE 1118L
+#define ERROR_IRQ_BUSY 1119L
+#define ERROR_MORE_WRITES 1120L
+#define ERROR_COUNTER_TIMEOUT 1121L
+#define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122L
+#define ERROR_FLOPPY_WRONG_CYLINDER 1123L
+#define ERROR_FLOPPY_UNKNOWN_ERROR 1124L
+#define ERROR_FLOPPY_BAD_REGISTERS 1125L
+#define ERROR_DISK_RECALIBRATE_FAILED 1126L
+#define ERROR_DISK_OPERATION_FAILED 1127L
+#define ERROR_DISK_RESET_FAILED 1128L
+#define ERROR_EOM_OVERFLOW 1129L
+#define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130L
+#define ERROR_POSSIBLE_DEADLOCK 1131L
+#define ERROR_MAPPED_ALIGNMENT 1132L
+#define ERROR_SET_POWER_STATE_VETOED 1140L
+#define ERROR_SET_POWER_STATE_FAILED 1141L
+#define ERROR_TOO_MANY_LINKS 1142L
+#define ERROR_OLD_WIN_VERSION 1150L
+#define ERROR_APP_WRONG_OS 1151L
+#define ERROR_SINGLE_INSTANCE_APP 1152L
+#define ERROR_RMODE_APP 1153L
+#define ERROR_INVALID_DLL 1154L
+#define ERROR_NO_ASSOCIATION 1155L
+#define ERROR_DDE_FAIL 1156L
+#define ERROR_DLL_NOT_FOUND 1157L
+#define ERROR_BAD_USERNAME 2202L
+#define ERROR_NOT_CONNECTED 2250L
+#define ERROR_OPEN_FILES 2401L
+#define ERROR_ACTIVE_CONNECTIONS 2402L
+#define ERROR_DEVICE_IN_USE 2404L
+#define ERROR_BAD_DEVICE 1200L
+#define ERROR_CONNECTION_UNAVAIL 1201L
+#define ERROR_DEVICE_ALREADY_REMEMBERED 1202L
+#define ERROR_NO_NET_OR_BAD_PATH 1203L
+#define ERROR_BAD_PROVIDER 1204L
+#define ERROR_CANNOT_OPEN_PROFILE 1205L
+#define ERROR_BAD_PROFILE 1206L
+#define ERROR_NOT_CONTAINER 1207L
+#define ERROR_EXTENDED_ERROR 1208L
+#define ERROR_INVALID_GROUPNAME 1209L
+#define ERROR_INVALID_COMPUTERNAME 1210L
+#define ERROR_INVALID_EVENTNAME 1211L
+#define ERROR_INVALID_DOMAINNAME 1212L
+#define ERROR_INVALID_SERVICENAME 1213L
+#define ERROR_INVALID_NETNAME 1214L
+#define ERROR_INVALID_SHARENAME 1215L
+#define ERROR_INVALID_PASSWORDNAME 1216L
+#define ERROR_INVALID_MESSAGENAME 1217L
+#define ERROR_INVALID_MESSAGEDEST 1218L
+#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219L
+#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220L
+#define ERROR_DUP_DOMAINNAME 1221L
+#define ERROR_NO_NETWORK 1222L
+#define ERROR_CANCELLED 1223L
+#define ERROR_USER_MAPPED_FILE 1224L
+#define ERROR_CONNECTION_REFUSED 1225L
+#define ERROR_GRACEFUL_DISCONNECT 1226L
+#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227L
+#define ERROR_ADDRESS_NOT_ASSOCIATED 1228L
+#define ERROR_CONNECTION_INVALID 1229L
+#define ERROR_CONNECTION_ACTIVE 1230L
+#define ERROR_NETWORK_UNREACHABLE 1231L
+#define ERROR_HOST_UNREACHABLE 1232L
+#define ERROR_PROTOCOL_UNREACHABLE 1233L
+#define ERROR_PORT_UNREACHABLE 1234L
+#define ERROR_REQUEST_ABORTED 1235L
+#define ERROR_CONNECTION_ABORTED 1236L
+#define ERROR_RETRY 1237L
+#define ERROR_CONNECTION_COUNT_LIMIT 1238L
+#define ERROR_LOGIN_TIME_RESTRICTION 1239L
+#define ERROR_LOGIN_WKSTA_RESTRICTION 1240L
+#define ERROR_INCORRECT_ADDRESS 1241L
+#define ERROR_ALREADY_REGISTERED 1242L
+#define ERROR_SERVICE_NOT_FOUND 1243L
+#define ERROR_NOT_AUTHENTICATED 1244L
+#define ERROR_NOT_LOGGED_ON 1245L
+#define ERROR_CONTINUE 1246L
+#define ERROR_ALREADY_INITIALIZED 1247L
+#define ERROR_NO_MORE_DEVICES 1248L
+#define ERROR_NOT_ALL_ASSIGNED 1300L
+#define ERROR_SOME_NOT_MAPPED 1301L
+#define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302L
+#define ERROR_LOCAL_USER_SESSION_KEY 1303L
+#define ERROR_NULL_LM_PASSWORD 1304L
+#define ERROR_UNKNOWN_REVISION 1305L
+#define ERROR_REVISION_MISMATCH 1306L
+#define ERROR_INVALID_OWNER 1307L
+#define ERROR_INVALID_PRIMARY_GROUP 1308L
+#define ERROR_NO_IMPERSONATION_TOKEN 1309L
+#define ERROR_CANT_DISABLE_MANDATORY 1310L
+#define ERROR_NO_LOGON_SERVERS 1311L
+#define ERROR_NO_SUCH_LOGON_SESSION 1312L
+#define ERROR_NO_SUCH_PRIVILEGE 1313L
+#define ERROR_PRIVILEGE_NOT_HELD 1314L
+#define ERROR_INVALID_ACCOUNT_NAME 1315L
+#define ERROR_USER_EXISTS 1316L
+#define ERROR_NO_SUCH_USER 1317L
+#define ERROR_GROUP_EXISTS 1318L
+#define ERROR_NO_SUCH_GROUP 1319L
+#define ERROR_MEMBER_IN_GROUP 1320L
+#define ERROR_MEMBER_NOT_IN_GROUP 1321L
+#define ERROR_LAST_ADMIN 1322L
+#define ERROR_WRONG_PASSWORD 1323L
+#define ERROR_ILL_FORMED_PASSWORD 1324L
+#define ERROR_PASSWORD_RESTRICTION 1325L
+#define ERROR_LOGON_FAILURE 1326L
+#define ERROR_ACCOUNT_RESTRICTION 1327L
+#define ERROR_INVALID_LOGON_HOURS 1328L
+#define ERROR_INVALID_WORKSTATION 1329L
+#define ERROR_PASSWORD_EXPIRED 1330L
+#define ERROR_ACCOUNT_DISABLED 1331L
+#define ERROR_NONE_MAPPED 1332L
+#define ERROR_TOO_MANY_LUIDS_REQUESTED 1333L
+#define ERROR_LUIDS_EXHAUSTED 1334L
+#define ERROR_INVALID_SUB_AUTHORITY 1335L
+#define ERROR_INVALID_ACL 1336L
+#define ERROR_INVALID_SID 1337L
+#define ERROR_INVALID_SECURITY_DESCR 1338L
+#define ERROR_BAD_INHERITANCE_ACL 1340L
+#define ERROR_SERVER_DISABLED 1341L
+#define ERROR_SERVER_NOT_DISABLED 1342L
+#define ERROR_INVALID_ID_AUTHORITY 1343L
+#define ERROR_ALLOTTED_SPACE_EXCEEDED 1344L
+#define ERROR_INVALID_GROUP_ATTRIBUTES 1345L
+#define ERROR_BAD_IMPERSONATION_LEVEL 1346L
+#define ERROR_CANT_OPEN_ANONYMOUS 1347L
+#define ERROR_BAD_VALIDATION_CLASS 1348L
+#define ERROR_BAD_TOKEN_TYPE 1349L
+#define ERROR_NO_SECURITY_ON_OBJECT 1350L
+#define ERROR_CANT_ACCESS_DOMAIN_INFO 1351L
+#define ERROR_INVALID_SERVER_STATE 1352L
+#define ERROR_INVALID_DOMAIN_STATE 1353L
+#define ERROR_INVALID_DOMAIN_ROLE 1354L
+#define ERROR_NO_SUCH_DOMAIN 1355L
+#define ERROR_DOMAIN_EXISTS 1356L
+#define ERROR_DOMAIN_LIMIT_EXCEEDED 1357L
+#define ERROR_INTERNAL_DB_CORRUPTION 1358L
+#define ERROR_INTERNAL_ERROR 1359L
+#define ERROR_GENERIC_NOT_MAPPED 1360L
+#define ERROR_BAD_DESCRIPTOR_FORMAT 1361L
+#define ERROR_NOT_LOGON_PROCESS 1362L
+#define ERROR_LOGON_SESSION_EXISTS 1363L
+#define ERROR_NO_SUCH_PACKAGE 1364L
+#define ERROR_BAD_LOGON_SESSION_STATE 1365L
+#define ERROR_LOGON_SESSION_COLLISION 1366L
+#define ERROR_INVALID_LOGON_TYPE 1367L
+#define ERROR_CANNOT_IMPERSONATE 1368L
+#define ERROR_RXACT_INVALID_STATE 1369L
+#define ERROR_RXACT_COMMIT_FAILURE 1370L
+#define ERROR_SPECIAL_ACCOUNT 1371L
+#define ERROR_SPECIAL_GROUP 1372L
+#define ERROR_SPECIAL_USER 1373L
+#define ERROR_MEMBERS_PRIMARY_GROUP 1374L
+#define ERROR_TOKEN_ALREADY_IN_USE 1375L
+#define ERROR_NO_SUCH_ALIAS 1376L
+#define ERROR_MEMBER_NOT_IN_ALIAS 1377L
+#define ERROR_MEMBER_IN_ALIAS 1378L
+#define ERROR_ALIAS_EXISTS 1379L
+#define ERROR_LOGON_NOT_GRANTED 1380L
+#define ERROR_TOO_MANY_SECRETS 1381L
+#define ERROR_SECRET_TOO_LONG 1382L
+#define ERROR_INTERNAL_DB_ERROR 1383L
+#define ERROR_TOO_MANY_CONTEXT_IDS 1384L
+#define ERROR_LOGON_TYPE_NOT_GRANTED 1385L
+#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386L
+#define ERROR_NO_SUCH_MEMBER 1387L
+#define ERROR_INVALID_MEMBER 1388L
+#define ERROR_TOO_MANY_SIDS 1389L
+#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390L
+#define ERROR_NO_INHERITANCE 1391L
+#define ERROR_FILE_CORRUPT 1392L
+#define ERROR_DISK_CORRUPT 1393L
+#define ERROR_NO_USER_SESSION_KEY 1394L
+#define ERROR_LICENSE_QUOTA_EXCEEDED 1395L
+#define ERROR_INVALID_WINDOW_HANDLE 1400L
+#define ERROR_INVALID_MENU_HANDLE 1401L
+#define ERROR_INVALID_CURSOR_HANDLE 1402L
+#define ERROR_INVALID_ACCEL_HANDLE 1403L
+#define ERROR_INVALID_HOOK_HANDLE 1404L
+#define ERROR_INVALID_DWP_HANDLE 1405L
+#define ERROR_TLW_WITH_WSCHILD 1406L
+#define ERROR_CANNOT_FIND_WND_CLASS 1407L
+#define ERROR_WINDOW_OF_OTHER_THREAD 1408L
+#define ERROR_HOTKEY_ALREADY_REGISTERED 1409L
+#define ERROR_CLASS_ALREADY_EXISTS 1410L
+#define ERROR_CLASS_DOES_NOT_EXIST 1411L
+#define ERROR_CLASS_HAS_WINDOWS 1412L
+#define ERROR_INVALID_INDEX 1413L
+#define ERROR_INVALID_ICON_HANDLE 1414L
+#define ERROR_PRIVATE_DIALOG_INDEX 1415L
+#define ERROR_LISTBOX_ID_NOT_FOUND 1416L
+#define ERROR_NO_WILDCARD_CHARACTERS 1417L
+#define ERROR_CLIPBOARD_NOT_OPEN 1418L
+#define ERROR_HOTKEY_NOT_REGISTERED 1419L
+#define ERROR_WINDOW_NOT_DIALOG 1420L
+#define ERROR_CONTROL_ID_NOT_FOUND 1421L
+#define ERROR_INVALID_COMBOBOX_MESSAGE 1422L
+#define ERROR_WINDOW_NOT_COMBOBOX 1423L
+#define ERROR_INVALID_EDIT_HEIGHT 1424L
+#define ERROR_DC_NOT_FOUND 1425L
+#define ERROR_INVALID_HOOK_FILTER 1426L
+#define ERROR_INVALID_FILTER_PROC 1427L
+#define ERROR_HOOK_NEEDS_HMOD 1428L
+#define ERROR_GLOBAL_ONLY_HOOK 1429L
+#define ERROR_JOURNAL_HOOK_SET 1430L
+#define ERROR_HOOK_NOT_INSTALLED 1431L
+#define ERROR_INVALID_LB_MESSAGE 1432L
+#define ERROR_SETCOUNT_ON_BAD_LB 1433L
+#define ERROR_LB_WITHOUT_TABSTOPS 1434L
+#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435L
+#define ERROR_CHILD_WINDOW_MENU 1436L
+#define ERROR_NO_SYSTEM_MENU 1437L
+#define ERROR_INVALID_MSGBOX_STYLE 1438L
+#define ERROR_INVALID_SPI_VALUE 1439L
+#define ERROR_SCREEN_ALREADY_LOCKED 1440L
+#define ERROR_HWNDS_HAVE_DIFF_PARENT 1441L
+#define ERROR_NOT_CHILD_WINDOW 1442L
+#define ERROR_INVALID_GW_COMMAND 1443L
+#define ERROR_INVALID_THREAD_ID 1444L
+#define ERROR_NON_MDICHILD_WINDOW 1445L
+#define ERROR_POPUP_ALREADY_ACTIVE 1446L
+#define ERROR_NO_SCROLLBARS 1447L
+#define ERROR_INVALID_SCROLLBAR_RANGE 1448L
+#define ERROR_INVALID_SHOWWIN_COMMAND 1449L
+#define ERROR_NO_SYSTEM_RESOURCES 1450L
+#define ERROR_NONPAGED_SYSTEM_RESOURCES 1451L
+#define ERROR_PAGED_SYSTEM_RESOURCES 1452L
+#define ERROR_WORKING_SET_QUOTA 1453L
+#define ERROR_PAGEFILE_QUOTA 1454L
+#define ERROR_COMMITMENT_LIMIT 1455L
+#define ERROR_MENU_ITEM_NOT_FOUND 1456L
+#define ERROR_EVENTLOG_FILE_CORRUPT 1500L
+#define ERROR_EVENTLOG_CANT_START 1501L
+#define ERROR_LOG_FILE_FULL 1502L
+#define ERROR_EVENTLOG_FILE_CHANGED 1503L
+#define RPC_S_INVALID_STRING_BINDING 1700L
+#define RPC_S_WRONG_KIND_OF_BINDING 1701L
+#define RPC_S_INVALID_BINDING 1702L
+#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703L
+#define RPC_S_INVALID_RPC_PROTSEQ 1704L
+#define RPC_S_INVALID_STRING_UUID 1705L
+#define RPC_S_INVALID_ENDPOINT_FORMAT 1706L
+#define RPC_S_INVALID_NET_ADDR 1707L
+#define RPC_S_NO_ENDPOINT_FOUND 1708L
+#define RPC_S_INVALID_TIMEOUT 1709L
+#define RPC_S_OBJECT_NOT_FOUND 1710L
+#define RPC_S_ALREADY_REGISTERED 1711L
+#define RPC_S_TYPE_ALREADY_REGISTERED 1712L
+#define RPC_S_ALREADY_LISTENING 1713L
+#define RPC_S_NO_PROTSEQS_REGISTERED 1714L
+#define RPC_S_NOT_LISTENING 1715L
+#define RPC_S_UNKNOWN_MGR_TYPE 1716L
+#define RPC_S_UNKNOWN_IF 1717L
+#define RPC_S_NO_BINDINGS 1718L
+#define RPC_S_NO_PROTSEQS 1719L
+#define RPC_S_CANT_CREATE_ENDPOINT 1720L
+#define RPC_S_OUT_OF_RESOURCES 1721L
+#define RPC_S_SERVER_UNAVAILABLE 1722L
+#define RPC_S_SERVER_TOO_BUSY 1723L
+#define RPC_S_INVALID_NETWORK_OPTIONS 1724L
+#define RPC_S_NO_CALL_ACTIVE 1725L
+#define RPC_S_CALL_FAILED 1726L
+#define RPC_S_CALL_FAILED_DNE 1727L
+#define RPC_S_PROTOCOL_ERROR 1728L
+#define RPC_S_UNSUPPORTED_TRANS_SYN 1730L
+#define RPC_S_UNSUPPORTED_TYPE 1732L
+#define RPC_S_INVALID_TAG 1733L
+#define RPC_S_INVALID_BOUND 1734L
+#define RPC_S_NO_ENTRY_NAME 1735L
+#define RPC_S_INVALID_NAME_SYNTAX 1736L
+#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737L
+#define RPC_S_UUID_NO_ADDRESS 1739L
+#define RPC_S_DUPLICATE_ENDPOINT 1740L
+#define RPC_S_UNKNOWN_AUTHN_TYPE 1741L
+#define RPC_S_MAX_CALLS_TOO_SMALL 1742L
+#define RPC_S_STRING_TOO_LONG 1743L
+#define RPC_S_PROTSEQ_NOT_FOUND 1744L
+#define RPC_S_PROCNUM_OUT_OF_RANGE 1745L
+#define RPC_S_BINDING_HAS_NO_AUTH 1746L
+#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747L
+#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748L
+#define RPC_S_INVALID_AUTH_IDENTITY 1749L
+#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750L
+#define EPT_S_INVALID_ENTRY 1751L
+#define EPT_S_CANT_PERFORM_OP 1752L
+#define EPT_S_NOT_REGISTERED 1753L
+#define RPC_S_NOTHING_TO_EXPORT 1754L
+#define RPC_S_INCOMPLETE_NAME 1755L
+#define RPC_S_INVALID_VERS_OPTION 1756L
+#define RPC_S_NO_MORE_MEMBERS 1757L
+#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758L
+#define RPC_S_INTERFACE_NOT_FOUND 1759L
+#define RPC_S_ENTRY_ALREADY_EXISTS 1760L
+#define RPC_S_ENTRY_NOT_FOUND 1761L
+#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762L
+#define RPC_S_INVALID_NAF_ID 1763L
+#define RPC_S_CANNOT_SUPPORT 1764L
+#define RPC_S_NO_CONTEXT_AVAILABLE 1765L
+#define RPC_S_INTERNAL_ERROR 1766L
+#define RPC_S_ZERO_DIVIDE 1767L
+#define RPC_S_ADDRESS_ERROR 1768L
+#define RPC_S_FP_DIV_ZERO 1769L
+#define RPC_S_FP_UNDERFLOW 1770L
+#define RPC_S_FP_OVERFLOW 1771L
+#define RPC_X_NO_MORE_ENTRIES 1772L
+#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773L
+#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774L
+#define RPC_X_SS_IN_NULL_CONTEXT 1775L
+#define RPC_X_SS_CONTEXT_DAMAGED 1777L
+#define RPC_X_SS_HANDLES_MISMATCH 1778L
+#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779L
+#define RPC_X_NULL_REF_POINTER 1780L
+#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781L
+#define RPC_X_BYTE_COUNT_TOO_SMALL 1782L
+#define RPC_X_BAD_STUB_DATA 1783L
+#define ERROR_INVALID_USER_BUFFER 1784L
+#define ERROR_UNRECOGNIZED_MEDIA 1785L
+#define ERROR_NO_TRUST_LSA_SECRET 1786L
+#define ERROR_NO_TRUST_SAM_ACCOUNT 1787L
+#define ERROR_TRUSTED_DOMAIN_FAILURE 1788L
+#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789L
+#define ERROR_TRUST_FAILURE 1790L
+#define RPC_S_CALL_IN_PROGRESS 1791L
+#define ERROR_NETLOGON_NOT_STARTED 1792L
+#define ERROR_ACCOUNT_EXPIRED 1793L
+#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794L
+#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795L
+#define ERROR_UNKNOWN_PORT 1796L
+#define ERROR_UNKNOWN_PRINTER_DRIVER 1797L
+#define ERROR_UNKNOWN_PRINTPROCESSOR 1798L
+#define ERROR_INVALID_SEPARATOR_FILE 1799L
+#define ERROR_INVALID_PRIORITY 1800L
+#define ERROR_INVALID_PRINTER_NAME 1801L
+#define ERROR_PRINTER_ALREADY_EXISTS 1802L
+#define ERROR_INVALID_PRINTER_COMMAND 1803L
+#define ERROR_INVALID_DATATYPE 1804L
+#define ERROR_INVALID_ENVIRONMENT 1805L
+#define RPC_S_NO_MORE_BINDINGS 1806L
+#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807L
+#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808L
+#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809L
+#define ERROR_DOMAIN_TRUST_INCONSISTENT 1810L
+#define ERROR_SERVER_HAS_OPEN_HANDLES 1811L
+#define ERROR_RESOURCE_DATA_NOT_FOUND 1812L
+#define ERROR_RESOURCE_TYPE_NOT_FOUND 1813L
+#define ERROR_RESOURCE_NAME_NOT_FOUND 1814L
+#define ERROR_RESOURCE_LANG_NOT_FOUND 1815L
+#define ERROR_NOT_ENOUGH_QUOTA 1816L
+#define RPC_S_NO_INTERFACES 1817L
+#define RPC_S_CALL_CANCELLED 1818L
+#define RPC_S_BINDING_INCOMPLETE 1819L
+#define RPC_S_COMM_FAILURE 1820L
+#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821L
+#define RPC_S_NO_PRINC_NAME 1822L
+#define RPC_S_NOT_RPC_ERROR 1823L
+#define RPC_S_UUID_LOCAL_ONLY 1824L
+#define RPC_S_SEC_PKG_ERROR 1825L
+#define RPC_S_NOT_CANCELLED 1826L
+#define RPC_X_INVALID_ES_ACTION 1827L
+#define RPC_X_WRONG_ES_VERSION 1828L
+#define RPC_X_WRONG_STUB_VERSION 1829L
+#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898L
+#define EPT_S_CANT_CREATE 1899L
+#define RPC_S_INVALID_OBJECT 1900L
+#define ERROR_INVALID_TIME 1901L
+#define ERROR_INVALID_FORM_NAME 1902L
+#define ERROR_INVALID_FORM_SIZE 1903L
+#define ERROR_ALREADY_WAITING 1904L
+#define ERROR_PRINTER_DELETED 1905L
+#define ERROR_INVALID_PRINTER_STATE 1906L
+#define ERROR_PASSWORD_MUST_CHANGE 1907L
+#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908L
+#define ERROR_ACCOUNT_LOCKED_OUT 1909L
+#define ERROR_NO_BROWSER_SERVERS_FOUND 6118L
+#define ERROR_INVALID_PIXEL_FORMAT 2000L
+#define ERROR_BAD_DRIVER 2001L
+#define ERROR_INVALID_WINDOW_STYLE 2002L
+#define ERROR_METAFILE_NOT_SUPPORTED 2003L
+#define ERROR_TRANSFORM_NOT_SUPPORTED 2004L
+#define ERROR_CLIPPING_NOT_SUPPORTED 2005L
+#define ERROR_UNKNOWN_PRINT_MONITOR 3000L
+#define ERROR_PRINTER_DRIVER_IN_USE 3001L
+#define ERROR_SPOOL_FILE_NOT_FOUND 3002L
+#define ERROR_SPL_NO_STARTDOC 3003L
+#define ERROR_SPL_NO_ADDJOB 3004L
+#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005L
+#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006L
+#define ERROR_WINS_INTERNAL 4000L
+#define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001L
+#define ERROR_STATIC_INIT 4002L
+#define ERROR_INC_BACKUP 4003L
+#define ERROR_FULL_BACKUP 4004L
+#define ERROR_REC_NON_EXISTENT 4005L
+#define ERROR_RPL_NOT_ALLOWED 4006L
+#define SEVERITY_SUCCESS 0
+#define SEVERITY_ERROR 1
+#define FACILITY_WINDOWS 8
+#define FACILITY_STORAGE 3
+#define FACILITY_RPC 1
+#define FACILITY_WIN32 7
+#define FACILITY_CONTROL 10
+#define FACILITY_NULL 0
+#define FACILITY_ITF 4
+#define FACILITY_DISPATCH 2
+#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
+#define FAILED(Status) ((HRESULT)(Status)<0)
+#define IS_ERROR(Status) ((unsigned long)(Status) >> 31 == SEVERITY_ERROR)
+#define HRESULT_CODE(r) ((r)&0xFFFF)
+#define SCODE_CODE(c) ((c)&0xFFFF)
+#define HRESULT_FACILITY(r) (((r)>>16)&0x1fff)
+#define SCODE_FACILITY(c) (((c)>>16)&0x1fff)
+#define HRESULT_SEVERITY(r) (((r)>>31)&0x1)
+#define SCODE_SEVERITY(c) (((c)>>31)&0x1)
+#define MAKE_HRESULT(s,f,c) ((HRESULT)(((unsigned long)(s)<<31)|((unsigned long)(f)<<16)|((unsigned long)(c))))
+#define MAKE_SCODE(s,f,c) ((SCODE)(((unsigned long)(s)<<31)|((unsigned long)(f)<<16)|((unsigned long)(c))) )
+#define FACILITY_NT_BIT 0x10000000
+#define HRESULT_FROM_WIN32(x) (x?((HRESULT)(((x)&0x0000FFFF)|(FACILITY_WIN32<<16)|0x80000000)):0)
+#define HRESULT_FROM_NT(x) ((HRESULT)((x)|FACILITY_NT_BIT))
+#define GetScode(hr) ((SCODE) (hr))
+#define ResultFromScode(sc) ((HRESULT) (sc))
+#define PropagateResult(hrPrevious, scBase) ((HRESULT) scBase)
+
+#define NOERROR S_OK
+#define E_UNEXPECTED 0x8000FFFFL
+#define E_NOTIMPL 0x80004001L
+#define E_OUTOFMEMORY 0x8007000EL
+#define E_INVALIDARG 0x80070057L
+#define E_NOINTERFACE 0x80004002L
+#define E_POINTER 0x80004003L
+#define E_HANDLE 0x80070006L
+#define E_ABORT 0x80004004L
+#define E_FAIL 0x80004005L
+#define E_ACCESSDENIED 0x80070005L
+#define E_PENDING 0x8000000AL
+#define CO_E_INIT_TLS 0x80004006L
+#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007L
+#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008L
+#define CO_E_INIT_CLASS_CACHE 0x80004009L
+#define CO_E_INIT_RPC_CHANNEL 0x8000400AL
+#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400BL
+#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400CL
+#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400DL
+#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400EL
+#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400FL
+#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010L
+#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011L
+#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012L
+#define S_OK (0x00000000L)
+#define S_FALSE (0x00000001L)
+#define OLE_E_FIRST 0x80040000L
+#define OLE_E_LAST 0x800400FFL
+#define OLE_S_FIRST 0x00040000L
+#define OLE_S_LAST 0x000400FFL
+#define OLE_E_OLEVERB 0x80040000L
+#define OLE_E_ADVF 0x80040001L
+#define OLE_E_ENUM_NOMORE 0x80040002L
+#define OLE_E_ADVISENOTSUPPORTED 0x80040003L
+#define OLE_E_NOCONNECTION 0x80040004L
+#define OLE_E_NOTRUNNING 0x80040005L
+#define OLE_E_NOCACHE 0x80040006L
+#define OLE_E_BLANK 0x80040007L
+#define OLE_E_CLASSDIFF 0x80040008L
+#define OLE_E_CANT_GETMONIKER 0x80040009L
+#define OLE_E_CANT_BINDTOSOURCE 0x8004000AL
+#define OLE_E_STATIC 0x8004000BL
+#define OLE_E_PROMPTSAVECANCELLED 0x8004000CL
+#define OLE_E_INVALIDRECT 0x8004000DL
+#define OLE_E_WRONGCOMPOBJ 0x8004000EL
+#define OLE_E_INVALIDHWND 0x8004000FL
+#define OLE_E_NOT_INPLACEACTIVE 0x80040010L
+#define OLE_E_CANTCONVERT 0x80040011L
+#define OLE_E_NOSTORAGE 0x80040012L
+#define DV_E_FORMATETC 0x80040064L
+#define DV_E_DVTARGETDEVICE 0x80040065L
+#define DV_E_STGMEDIUM 0x80040066L
+#define DV_E_STATDATA 0x80040067L
+#define DV_E_LINDEX 0x80040068L
+#define DV_E_TYMED 0x80040069L
+#define DV_E_CLIPFORMAT 0x8004006AL
+#define DV_E_DVASPECT 0x8004006BL
+#define DV_E_DVTARGETDEVICE_SIZE 0x8004006CL
+#define DV_E_NOIVIEWOBJECT 0x8004006DL
+#define DRAGDROP_E_FIRST 0x80040100L
+#define DRAGDROP_E_LAST 0x8004010FL
+#define DRAGDROP_S_FIRST 0x00040100L
+#define DRAGDROP_S_LAST 0x0004010FL
+#define DRAGDROP_E_NOTREGISTERED 0x80040100L
+#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L
+#define DRAGDROP_E_INVALIDHWND 0x80040102L
+#define CLASSFACTORY_E_FIRST 0x80040110L
+#define CLASSFACTORY_E_LAST 0x8004011FL
+#define CLASSFACTORY_S_FIRST 0x00040110L
+#define CLASSFACTORY_S_LAST 0x0004011FL
+#define CLASS_E_NOAGGREGATION 0x80040110L
+#define CLASS_E_CLASSNOTAVAILABLE 0x80040111L
+#define MARSHAL_E_FIRST 0x80040120L
+#define MARSHAL_E_LAST 0x8004012FL
+#define MARSHAL_S_FIRST 0x00040120L
+#define MARSHAL_S_LAST 0x0004012FL
+#define DATA_E_FIRST 0x80040130L
+#define DATA_E_LAST 0x8004013FL
+#define DATA_S_FIRST 0x00040130L
+#define DATA_S_LAST 0x0004013FL
+#define VIEW_E_FIRST 0x80040140L
+#define VIEW_E_LAST 0x8004014FL
+#define VIEW_S_FIRST 0x00040140L
+#define VIEW_S_LAST 0x0004014FL
+#define VIEW_E_DRAW 0x80040140L
+#define REGDB_E_FIRST 0x80040150L
+#define REGDB_E_LAST 0x8004015FL
+#define REGDB_S_FIRST 0x00040150L
+#define REGDB_S_LAST 0x0004015FL
+#define REGDB_E_READREGDB 0x80040150L
+#define REGDB_E_WRITEREGDB 0x80040151L
+#define REGDB_E_KEYMISSING 0x80040152L
+#define REGDB_E_INVALIDVALUE 0x80040153L
+#define REGDB_E_CLASSNOTREG 0x80040154L
+#define REGDB_E_IIDNOTREG 0x80040155L
+#define CACHE_E_FIRST 0x80040170L
+#define CACHE_E_LAST 0x8004017FL
+#define CACHE_S_FIRST 0x00040170L
+#define CACHE_S_LAST 0x0004017FL
+#define CACHE_E_NOCACHE_UPDATED 0x80040170L
+#define OLEOBJ_E_FIRST 0x80040180L
+#define OLEOBJ_E_LAST 0x8004018FL
+#define OLEOBJ_S_FIRST 0x00040180L
+#define OLEOBJ_S_LAST 0x0004018FL
+#define OLEOBJ_E_NOVERBS 0x80040180L
+#define OLEOBJ_E_INVALIDVERB 0x80040181L
+#define CLIENTSITE_E_FIRST 0x80040190L
+#define CLIENTSITE_E_LAST 0x8004019FL
+#define CLIENTSITE_S_FIRST 0x00040190L
+#define CLIENTSITE_S_LAST 0x0004019FL
+#define INPLACE_E_NOTUNDOABLE 0x800401A0L
+#define INPLACE_E_NOTOOLSPACE 0x800401A1L
+#define INPLACE_E_FIRST 0x800401A0L
+#define INPLACE_E_LAST 0x800401AFL
+#define INPLACE_S_FIRST 0x000401A0L
+#define INPLACE_S_LAST 0x000401AFL
+#define ENUM_E_FIRST 0x800401B0L
+#define ENUM_E_LAST 0x800401BFL
+#define ENUM_S_FIRST 0x000401B0L
+#define ENUM_S_LAST 0x000401BFL
+#define CONVERT10_E_FIRST 0x800401C0L
+#define CONVERT10_E_LAST 0x800401CFL
+#define CONVERT10_S_FIRST 0x000401C0L
+#define CONVERT10_S_LAST 0x000401CFL
+#define CONVERT10_E_OLESTREAM_GET 0x800401C0L
+#define CONVERT10_E_OLESTREAM_PUT 0x800401C1L
+#define CONVERT10_E_OLESTREAM_FMT 0x800401C2L
+#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3L
+#define CONVERT10_E_STG_FMT 0x800401C4L
+#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5L
+#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6L
+#define CLIPBRD_E_FIRST 0x800401D0L
+#define CLIPBRD_E_LAST 0x800401DFL
+#define CLIPBRD_S_FIRST 0x000401D0L
+#define CLIPBRD_S_LAST 0x000401DFL
+#define CLIPBRD_E_CANT_OPEN 0x800401D0L
+#define CLIPBRD_E_CANT_EMPTY 0x800401D1L
+#define CLIPBRD_E_CANT_SET 0x800401D2L
+#define CLIPBRD_E_BAD_DATA 0x800401D3L
+#define CLIPBRD_E_CANT_CLOSE 0x800401D4L
+#define MK_E_FIRST 0x800401E0L
+#define MK_E_LAST 0x800401EFL
+#define MK_S_FIRST 0x000401E0L
+#define MK_S_LAST 0x000401EFL
+#define MK_E_CONNECTMANUALLY 0x800401E0L
+#define MK_E_EXCEEDEDDEADLINE 0x800401E1L
+#define MK_E_NEEDGENERIC 0x800401E2L
+#define MK_E_UNAVAILABLE 0x800401E3L
+#define MK_E_SYNTAX 0x800401E4L
+#define MK_E_NOOBJECT 0x800401E5L
+#define MK_E_INVALIDEXTENSION 0x800401E6L
+#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7L
+#define MK_E_NOTBINDABLE 0x800401E8L
+#define MK_E_NOTBOUND 0x800401E9L
+#define MK_E_CANTOPENFILE 0x800401EAL
+#define MK_E_MUSTBOTHERUSER 0x800401EBL
+#define MK_E_NOINVERSE 0x800401ECL
+#define MK_E_NOSTORAGE 0x800401EDL
+#define MK_E_NOPREFIX 0x800401EEL
+#define MK_E_ENUMERATION_FAILED 0x800401EFL
+#define CO_E_FIRST 0x800401F0L
+#define CO_E_LAST 0x800401FFL
+#define CO_S_FIRST 0x000401F0L
+#define CO_S_LAST 0x000401FFL
+#define CO_E_NOTINITIALIZED 0x800401F0L
+#define CO_E_ALREADYINITIALIZED 0x800401F1L
+#define CO_E_CANTDETERMINECLASS 0x800401F2L
+#define CO_E_CLASSSTRING 0x800401F3L
+#define CO_E_IIDSTRING 0x800401F4L
+#define CO_E_APPNOTFOUND 0x800401F5L
+#define CO_E_APPSINGLEUSE 0x800401F6L
+#define CO_E_ERRORINAPP 0x800401F7L
+#define CO_E_DLLNOTFOUND 0x800401F8L
+#define CO_E_ERRORINDLL 0x800401F9L
+#define CO_E_WRONGOSFORAPP 0x800401FAL
+#define CO_E_OBJNOTREG 0x800401FBL
+#define CO_E_OBJISREG 0x800401FCL
+#define CO_E_OBJNOTCONNECTED 0x800401FDL
+#define CO_E_APPDIDNTREG 0x800401FEL
+#define CO_E_RELEASED 0x800401FFL
+#define OLE_S_USEREG 0x00040000L
+#define OLE_S_STATIC 0x00040001L
+#define OLE_S_MAC_CLIPFORMAT 0x00040002L
+#define DRAGDROP_S_DROP 0x00040100L
+#define DRAGDROP_S_CANCEL 0x00040101L
+#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L
+#define DATA_S_SAMEFORMATETC 0x00040130L
+#define VIEW_S_ALREADY_FROZEN 0x00040140L
+#define CACHE_S_FORMATETC_NOTSUPPORTED 0x00040170L
+#define CACHE_S_SAMECACHE 0x00040171L
+#define CACHE_S_SOMECACHES_NOTUPDATED 0x00040172L
+#define OLEOBJ_S_INVALIDVERB 0x00040180L
+#define OLEOBJ_S_CANNOT_DOVERB_NOW 0x00040181L
+#define OLEOBJ_S_INVALIDHWND 0x00040182L
+#define INPLACE_S_TRUNCATED 0x000401A0L
+#define CONVERT10_S_NO_PRESENTATION 0x000401C0L
+#define MK_S_REDUCED_TO_SELF 0x000401E2L
+#define MK_S_ME 0x000401E4L
+#define MK_S_HIM 0x000401E5L
+#define MK_S_US 0x000401E6L
+#define MK_S_MONIKERALREADYREGISTERED 0x000401E7L
+#define CO_E_CLASS_CREATE_FAILED 0x80080001L
+#define CO_E_SCM_ERROR 0x80080002L
+#define CO_E_SCM_RPC_FAILURE 0x80080003L
+#define CO_E_BAD_PATH 0x80080004L
+#define CO_E_SERVER_EXEC_FAILURE 0x80080005L
+#define CO_E_OBJSRV_RPC_FAILURE 0x80080006L
+#define MK_E_NO_NORMALIZED 0x80080007L
+#define CO_E_SERVER_STOPPING 0x80080008L
+#define MEM_E_INVALID_ROOT 0x80080009L
+#define MEM_E_INVALID_LINK 0x80080010L
+#define MEM_E_INVALID_SIZE 0x80080011L
+#define DISP_E_UNKNOWNINTERFACE 0x80020001L
+#define DISP_E_MEMBERNOTFOUND 0x80020003L
+#define DISP_E_PARAMNOTFOUND 0x80020004L
+#define DISP_E_TYPEMISMATCH 0x80020005L
+#define DISP_E_UNKNOWNNAME 0x80020006L
+#define DISP_E_NONAMEDARGS 0x80020007L
+#define DISP_E_BADVARTYPE 0x80020008L
+#define DISP_E_EXCEPTION 0x80020009L
+#define DISP_E_OVERFLOW 0x8002000AL
+#define DISP_E_BADINDEX 0x8002000BL
+#define DISP_E_UNKNOWNLCID 0x8002000CL
+#define DISP_E_ARRAYISLOCKED 0x8002000DL
+#define DISP_E_BADPARAMCOUNT 0x8002000EL
+#define DISP_E_PARAMNOTOPTIONAL 0x8002000FL
+#define DISP_E_BADCALLEE 0x80020010L
+#define DISP_E_NOTACOLLECTION 0x80020011L
+#define TYPE_E_BUFFERTOOSMALL 0x80028016L
+#define TYPE_E_INVDATAREAD 0x80028018L
+#define TYPE_E_UNSUPFORMAT 0x80028019L
+#define TYPE_E_REGISTRYACCESS 0x8002801CL
+#define TYPE_E_LIBNOTREGISTERED 0x8002801DL
+#define TYPE_E_UNDEFINEDTYPE 0x80028027L
+#define TYPE_E_QUALIFIEDNAMEDISALLOWED 0x80028028L
+#define TYPE_E_INVALIDSTATE 0x80028029L
+#define TYPE_E_WRONGTYPEKIND 0x8002802AL
+#define TYPE_E_ELEMENTNOTFOUND 0x8002802BL
+#define TYPE_E_AMBIGUOUSNAME 0x8002802CL
+#define TYPE_E_NAMECONFLICT 0x8002802DL
+#define TYPE_E_UNKNOWNLCID 0x8002802EL
+#define TYPE_E_DLLFUNCTIONNOTFOUND 0x8002802FL
+#define TYPE_E_BADMODULEKIND 0x800288BDL
+#define TYPE_E_SIZETOOBIG 0x800288C5L
+#define TYPE_E_DUPLICATEID 0x800288C6L
+#define TYPE_E_INVALIDID 0x800288CFL
+#define TYPE_E_TYPEMISMATCH 0x80028CA0L
+#define TYPE_E_OUTOFBOUNDS 0x80028CA1L
+#define TYPE_E_IOERROR 0x80028CA2L
+#define TYPE_E_CANTCREATETMPFILE 0x80028CA3L
+#define TYPE_E_CANTLOADLIBRARY 0x80029C4AL
+#define TYPE_E_INCONSISTENTPROPFUNCS 0x80029C83L
+#define TYPE_E_CIRCULARTYPE 0x80029C84L
+#define STG_E_INVALIDFUNCTION 0x80030001L
+#define STG_E_FILENOTFOUND 0x80030002L
+#define STG_E_PATHNOTFOUND 0x80030003L
+#define STG_E_TOOMANYOPENFILES 0x80030004L
+#define STG_E_ACCESSDENIED 0x80030005L
+#define STG_E_INVALIDHANDLE 0x80030006L
+#define STG_E_INSUFFICIENTMEMORY 0x80030008L
+#define STG_E_INVALIDPOINTER 0x80030009L
+#define STG_E_NOMOREFILES 0x80030012L
+#define STG_E_DISKISWRITEPROTECTED 0x80030013L
+#define STG_E_SEEKERROR 0x80030019L
+#define STG_E_WRITEFAULT 0x8003001DL
+#define STG_E_READFAULT 0x8003001EL
+#define STG_E_SHAREVIOLATION 0x80030020L
+#define STG_E_LOCKVIOLATION 0x80030021L
+#define STG_E_FILEALREADYEXISTS 0x80030050L
+#define STG_E_INVALIDPARAMETER 0x80030057L
+#define STG_E_MEDIUMFULL 0x80030070L
+#define STG_E_ABNORMALAPIEXIT 0x800300FAL
+#define STG_E_INVALIDHEADER 0x800300FBL
+#define STG_E_INVALIDNAME 0x800300FCL
+#define STG_E_UNKNOWN 0x800300FDL
+#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FEL
+#define STG_E_INVALIDFLAG 0x800300FFL
+#define STG_E_INUSE 0x80030100L
+#define STG_E_NOTCURRENT 0x80030101L
+#define STG_E_REVERTED 0x80030102L
+#define STG_E_CANTSAVE 0x80030103L
+#define STG_E_OLDFORMAT 0x80030104L
+#define STG_E_OLDDLL 0x80030105L
+#define STG_E_SHAREREQUIRED 0x80030106L
+#define STG_E_NOTFILEBASEDSTORAGE 0x80030107L
+#define STG_E_EXTANTMARSHALLINGS 0x80030108L
+#define STG_S_CONVERTED 0x00030200L
+#define RPC_E_CALL_REJECTED 0x80010001L
+#define RPC_E_CALL_CANCELED 0x80010002L
+#define RPC_E_CANTPOST_INSENDCALL 0x80010003L
+#define RPC_E_CANTCALLOUT_INASYNCCALL 0x80010004L
+#define RPC_E_CANTCALLOUT_INEXTERNALCALL 0x80010005L
+#define RPC_E_CONNECTION_TERMINATED 0x80010006L
+#define RPC_E_SERVER_DIED 0x80010007L
+#define RPC_E_CLIENT_DIED 0x80010008L
+#define RPC_E_INVALID_DATAPACKET 0x80010009L
+#define RPC_E_CANTTRANSMIT_CALL 0x8001000AL
+#define RPC_E_CLIENT_CANTMARSHAL_DATA 0x8001000BL
+#define RPC_E_CLIENT_CANTUNMARSHAL_DATA 0x8001000CL
+#define RPC_E_SERVER_CANTMARSHAL_DATA 0x8001000DL
+#define RPC_E_SERVER_CANTUNMARSHAL_DATA 0x8001000EL
+#define RPC_E_INVALID_DATA 0x8001000FL
+#define RPC_E_INVALID_PARAMETER 0x80010010L
+#define RPC_E_CANTCALLOUT_AGAIN 0x80010011L
+#define RPC_E_SERVER_DIED_DNE 0x80010012L
+#define RPC_E_SYS_CALL_FAILED 0x80010100L
+#define RPC_E_OUT_OF_RESOURCES 0x80010101L
+#define RPC_E_ATTEMPTED_MULTITHREAD 0x80010102L
+#define RPC_E_NOT_REGISTERED 0x80010103L
+#define RPC_E_FAULT 0x80010104L
+#define RPC_E_SERVERFAULT 0x80010105L
+#define RPC_E_CHANGED_MODE 0x80010106L
+#define RPC_E_INVALIDMETHOD 0x80010107L
+#define RPC_E_DISCONNECTED 0x80010108L
+#define RPC_E_RETRY 0x80010109L
+#define RPC_E_SERVERCALL_RETRYLATER 0x8001010AL
+#define RPC_E_SERVERCALL_REJECTED 0x8001010BL
+#define RPC_E_INVALID_CALLDATA 0x8001010CL
+#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL 0x8001010DL
+#define RPC_E_WRONG_THREAD 0x8001010EL
+#define RPC_E_THREAD_NOT_INIT 0x8001010FL
+#define RPC_E_UNEXPECTED 0x8001FFFFL
+
+#define NTE_BAD_UID 0x80090001L
+#define NTE_BAD_HASH 0x80090002L
+#define NTE_BAD_KEY 0x80090003L
+#define NTE_BAD_LEN 0x80090004L
+#define NTE_BAD_DATA 0x80090005L
+#define NTE_BAD_SIGNATURE 0x80090006L
+#define NTE_BAD_VER 0x80090007L
+#define NTE_BAD_ALGID 0x80090008L
+#define NTE_BAD_FLAGS 0x80090009L
+#define NTE_BAD_TYPE 0x8009000AL
+#define NTE_BAD_KEY_STATE 0x8009000BL
+#define NTE_BAD_HASH_STATE 0x8009000CL
+#define NTE_NO_KEY 0x8009000DL
+#define NTE_NO_MEMORY 0x8009000EL
+#define NTE_EXISTS 0x8009000FL
+#define NTE_PERM 0x80090010L
+#define NTE_NOT_FOUND 0x80090011L
+#define NTE_DOUBLE_ENCRYPT 0x80090012L
+#define NTE_BAD_PROVIDER 0x80090013L
+#define NTE_BAD_PROV_TYPE 0x80090014L
+#define NTE_BAD_PUBLIC_KEY 0x80090015L
+#define NTE_BAD_KEYSET 0x80090016L
+#define NTE_PROV_TYPE_NOT_DEF 0x80090017L
+#define NTE_PROV_TYPE_ENTRY_BAD 0x80090018L
+#define NTE_KEYSET_NOT_DEF 0x80090019L
+#define NTE_KEYSET_ENTRY_BAD 0x8009001AL
+#define NTE_PROV_TYPE_NO_MATCH 0x8009001BL
+#define NTE_SIGNATURE_FILE_BAD 0x8009001CL
+#define NTE_PROVIDER_DLL_FAIL 0x8009001DL
+#define NTE_PROV_DLL_NOT_FOUND 0x8009001EL
+#define NTE_BAD_KEYSET_PARAM 0x8009001FL
+#define NTE_FAIL 0x80090020L
+#define NTE_SYS_ERR 0x80090021L
+/* #define NTE_TOKEN_KEYSET_STORAGE ??? */
+
+#endif
diff --git a/tinyc/win32/include/winapi/wingdi.h b/tinyc/win32/include/winapi/wingdi.h
new file mode 100755
index 000000000..b0af5adeb
--- /dev/null
+++ b/tinyc/win32/include/winapi/wingdi.h
@@ -0,0 +1,2843 @@
+#ifndef _WINGDI_H
+#define _WINGDI_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WINGDIAPI
+#define BI_RGB 0
+#define BI_RLE8 1
+#define BI_RLE4 2
+#define BI_BITFIELDS 3
+#define BI_JPEG 4
+#define BI_PNG 5
+#define LF_FACESIZE	32
+#define LF_FULLFACESIZE	64
+#define CA_NEGATIVE	1
+#define CA_LOG_FILTER	2
+#define ILLUMINANT_DEVICE_DEFAULT	0
+#define ILLUMINANT_A	1
+#define ILLUMINANT_B	2
+#define ILLUMINANT_C	3
+#define ILLUMINANT_D50	4
+#define ILLUMINANT_D55	5
+#define ILLUMINANT_D65	6
+#define ILLUMINANT_D75	7
+#define ILLUMINANT_F2	8
+#define ILLUMINANT_MAX_INDEX	ILLUMINANT_F2
+#define ILLUMINANT_TUNGSTEN	ILLUMINANT_A
+#define ILLUMINANT_DAYLIGHT	ILLUMINANT_C
+#define ILLUMINANT_FLUORESCENT	ILLUMINANT_F2
+#define ILLUMINANT_NTSC	ILLUMINANT_C
+#define RGB_GAMMA_MIN	2500
+#define RGB_GAMMA_MAX	65000
+#define REFERENCE_WHITE_MIN	6000
+#define REFERENCE_WHITE_MAX	10000
+#define REFERENCE_BLACK_MIN	0
+#define REFERENCE_BLACK_MAX	4000
+#define COLOR_ADJ_MIN	(-100)
+#define COLOR_ADJ_MAX	100
+#define CCHDEVICENAME 32
+#define CCHFORMNAME 32
+#define DI_COMPAT	4
+#define DI_DEFAULTSIZE	8
+#define DI_IMAGE	2
+#define DI_MASK	1
+#define DI_NORMAL	3
+#define DI_APPBANDING 1
+#define EMR_HEADER	1
+#define EMR_POLYBEZIER 2
+#define EMR_POLYGON	3
+#define EMR_POLYLINE	4
+#define EMR_POLYBEZIERTO	5
+#define EMR_POLYLINETO 6
+#define EMR_POLYPOLYLINE	7
+#define EMR_POLYPOLYGON 8
+#define EMR_SETWINDOWEXTEX	9
+#define EMR_SETWINDOWORGEX	10
+#define EMR_SETVIEWPORTEXTEX 11
+#define EMR_SETVIEWPORTORGEX 12
+#define EMR_SETBRUSHORGEX 13
+#define EMR_EOF 14
+#define EMR_SETPIXELV 15
+#define EMR_SETMAPPERFLAGS 16
+#define EMR_SETMAPMODE 17
+#define EMR_SETBKMODE 18
+#define EMR_SETPOLYFILLMODE 19
+#define EMR_SETROP2 20
+#define EMR_SETSTRETCHBLTMODE 21
+#define EMR_SETTEXTALIGN 22
+#define EMR_SETCOLORADJUSTMENT 23
+#define EMR_SETTEXTCOLOR 24
+#define EMR_SETBKCOLOR 25
+#define EMR_OFFSETCLIPRGN 26
+#define EMR_MOVETOEX 27
+#define EMR_SETMETARGN 28
+#define EMR_EXCLUDECLIPRECT 29
+#define EMR_INTERSECTCLIPRECT 30
+#define EMR_SCALEVIEWPORTEXTEX 31
+#define EMR_SCALEWINDOWEXTEX 32
+#define EMR_SAVEDC 33
+#define EMR_RESTOREDC 34
+#define EMR_SETWORLDTRANSFORM 35
+#define EMR_MODIFYWORLDTRANSFORM 36
+#define EMR_SELECTOBJECT 37
+#define EMR_CREATEPEN 38
+#define EMR_CREATEBRUSHINDIRECT 39
+#define EMR_DELETEOBJECT 40
+#define EMR_ANGLEARC 41
+#define EMR_ELLIPSE  42
+#define EMR_RECTANGLE 43
+#define EMR_ROUNDRECT 44
+#define EMR_ARC 45
+#define EMR_CHORD 46
+#define EMR_PIE 47
+#define EMR_SELECTPALETTE 48
+#define EMR_CREATEPALETTE 49
+#define EMR_SETPALETTEENTRIES 50
+#define EMR_RESIZEPALETTE 51
+#define EMR_REALIZEPALETTE 52
+#define EMR_EXTFLOODFILL 53
+#define EMR_LINETO 54
+#define EMR_ARCTO 55
+#define EMR_POLYDRAW 56
+#define EMR_SETARCDIRECTION 57
+#define EMR_SETMITERLIMIT 58
+#define EMR_BEGINPATH 59
+#define EMR_ENDPATH 60
+#define EMR_CLOSEFIGURE 61
+#define EMR_FILLPATH 62
+#define EMR_STROKEANDFILLPATH 63
+#define EMR_STROKEPATH 64
+#define EMR_FLATTENPATH 65
+#define EMR_WIDENPATH 66
+#define EMR_SELECTCLIPPATH 67
+#define EMR_ABORTPATH 68
+#define EMR_GDICOMMENT 70
+#define EMR_FILLRGN 71
+#define EMR_FRAMERGN 72
+#define EMR_INVERTRGN 73
+#define EMR_PAINTRGN 74
+#define EMR_EXTSELECTCLIPRGN 75
+#define EMR_BITBLT 76
+#define EMR_STRETCHBLT 77
+#define EMR_MASKBLT 78
+#define EMR_PLGBLT 79
+#define EMR_SETDIBITSTODEVICE 80
+#define EMR_STRETCHDIBITS 81
+#define EMR_EXTCREATEFONTINDIRECTW 82
+#define EMR_EXTTEXTOUTA 83
+#define EMR_EXTTEXTOUTW 84
+#define EMR_POLYBEZIER16 85
+#define EMR_POLYGON16 86
+#define EMR_POLYLINE16 87
+#define EMR_POLYBEZIERTO16 88
+#define EMR_POLYLINETO16 89
+#define EMR_POLYPOLYLINE16 90
+#define EMR_POLYPOLYGON16 91
+#define EMR_POLYDRAW16 92
+#define EMR_CREATEMONOBRUSH 93
+#define EMR_CREATEDIBPATTERNBRUSHPT 94
+#define EMR_EXTCREATEPEN 95
+#define EMR_POLYTEXTOUTA 96
+#define EMR_POLYTEXTOUTW 97
+#define EMR_SETICMMODE 98
+#define EMR_CREATECOLORSPACE 99
+#define EMR_SETCOLORSPACE 100
+#define EMR_DELETECOLORSPACE 101
+#define EMR_GLSRECORD 102
+#define EMR_GLSBOUNDEDRECORD 103
+#define EMR_PIXELFORMAT 104
+#define ENHMETA_SIGNATURE 1179469088
+#define EPS_SIGNATURE 0x46535045
+#define META_SETBKCOLOR	0x201
+#define META_SETBKMODE	0x102
+#define META_SETMAPMODE	0x103
+#define META_SETROP2	0x104
+#define META_SETRELABS	0x105
+#define META_SETPOLYFILLMODE	0x106
+#define META_SETSTRETCHBLTMODE	0x107
+#define META_SETTEXTCHAREXTRA	0x108
+#define META_SETTEXTCOLOR	0x209
+#define META_SETTEXTJUSTIFICATION	0x20A
+#define META_SETWINDOWORG	0x20B
+#define META_SETWINDOWEXT	0x20C
+#define META_SETVIEWPORTORG	0x20D
+#define META_SETVIEWPORTEXT	0x20E
+#define META_OFFSETWINDOWORG	0x20F
+#define META_SCALEWINDOWEXT	0x410
+#define META_OFFSETVIEWPORTORG	0x211
+#define META_SCALEVIEWPORTEXT	0x412
+#define META_LINETO	0x213
+#define META_MOVETO	0x214
+#define META_EXCLUDECLIPRECT	0x415
+#define META_INTERSECTCLIPRECT	0x416
+#define META_ARC	0x817
+#define META_ELLIPSE	0x418
+#define META_FLOODFILL	0x419
+#define META_PIE	0x81A
+#define META_RECTANGLE	0x41B
+#define META_ROUNDRECT	0x61C
+#define META_PATBLT	0x61D
+#define META_SAVEDC	0x1E
+#define META_SETPIXEL	0x41F
+#define META_OFFSETCLIPRGN	0x220
+#define META_TEXTOUT	0x521
+#define META_BITBLT	0x922
+#define META_STRETCHBLT	0xB23
+#define META_POLYGON	0x324
+#define META_POLYLINE	0x325
+#define META_ESCAPE	0x626
+#define META_RESTOREDC	0x127
+#define META_FILLREGION	0x228
+#define META_FRAMEREGION	0x429
+#define META_INVERTREGION	0x12A
+#define META_PAINTREGION	0x12B
+#define META_SELECTCLIPREGION	0x12C
+#define META_SELECTOBJECT	0x12D
+#define META_SETTEXTALIGN	0x12E
+#define META_CHORD	0x830
+#define META_SETMAPPERFLAGS	0x231
+#define META_EXTTEXTOUT	0xa32
+#define META_SETDIBTODEV	0xd33
+#define META_SELECTPALETTE	0x234
+#define META_REALIZEPALETTE	0x35
+#define META_ANIMATEPALETTE	0x436
+#define META_SETPALENTRIES	0x37
+#define META_POLYPOLYGON	0x538
+#define META_RESIZEPALETTE	0x139
+#define META_DIBBITBLT	0x940
+#define META_DIBSTRETCHBLT	0xb41
+#define META_DIBCREATEPATTERNBRUSH	0x142
+#define META_STRETCHDIB	0xf43
+#define META_EXTFLOODFILL	0x548
+#define META_DELETEOBJECT	0x1f0
+#define META_CREATEPALETTE	0xf7
+#define META_CREATEPATTERNBRUSH	0x1F9
+#define META_CREATEPENINDIRECT	0x2FA
+#define META_CREATEFONTINDIRECT	0x2FB
+#define META_CREATEBRUSHINDIRECT	0x2FC
+#define META_CREATEREGION	0x6FF
+#define PT_MOVETO	6
+#define PT_LINETO	2
+#define PT_BEZIERTO	4
+#define PT_CLOSEFIGURE 1
+#define ELF_VENDOR_SIZE	4
+#define ELF_VERSION	0
+#define ELF_CULTURE_LATIN	0
+#define PFD_TYPE_RGBA	0
+#define PFD_TYPE_COLORINDEX	1
+#define PFD_MAIN_PLANE	0
+#define PFD_OVERLAY_PLANE	1
+#define PFD_UNDERLAY_PLANE	(-1)
+#define PFD_DOUBLEBUFFER	1
+#define PFD_STEREO	2
+#define PFD_DRAW_TO_WINDOW	4
+#define PFD_DRAW_TO_BITMAP	8
+#define PFD_SUPPORT_GDI	16
+#define PFD_SUPPORT_OPENGL	32
+#define PFD_GENERIC_FORMAT	64
+#define PFD_NEED_PALETTE	128
+#define PFD_NEED_SYSTEM_PALETTE	0x00000100
+#define PFD_SWAP_EXCHANGE	0x00000200
+#define PFD_SWAP_COPY	0x00000400
+#define PFD_GENERIC_ACCELERATED	0x00001000
+#define PFD_DEPTH_DONTCARE	0x20000000
+#define PFD_DOUBLEBUFFER_DONTCARE	0x40000000
+#define PFD_STEREO_DONTCARE	0x80000000
+#define SP_ERROR	(-1)
+#define SP_OUTOFDISK	(-4)
+#define SP_OUTOFMEMORY	(-5)
+#define SP_USERABORT	(-3)
+#define SP_APPABORT	(-2)
+#define BLACKNESS	0x42
+#define NOTSRCERASE	0x1100A6
+#define NOTSRCCOPY	0x330008
+#define SRCERASE	0x440328
+#define DSTINVERT	0x550009
+#define PATINVERT	0x5A0049
+#define SRCINVERT	0x660046
+#define SRCAND	0x8800C6
+#define MERGEPAINT	0xBB0226
+#define MERGECOPY	0xC000CA
+#define SRCCOPY 0xCC0020
+#define SRCPAINT	0xEE0086
+#define PATCOPY	0xF00021
+#define PATPAINT	0xFB0A09
+#define WHITENESS	0xFF0062
+#define R2_BLACK	1
+#define R2_COPYPEN	13
+#define R2_MASKNOTPEN	3
+#define R2_MASKPEN	9
+#define R2_MASKPENNOT	5
+#define R2_MERGENOTPEN	12
+#define R2_MERGEPEN	15
+#define R2_MERGEPENNOT	14
+#define R2_NOP	11
+#define R2_NOT	6
+#define R2_NOTCOPYPEN	4
+#define R2_NOTMASKPEN	8
+#define R2_NOTMERGEPEN	2
+#define R2_NOTXORPEN	10
+#define R2_WHITE	16
+#define R2_XORPEN	7
+#define CM_OUT_OF_GAMUT	255
+#define CM_IN_GAMUT	0
+#define RGN_AND 1
+#define RGN_COPY	5
+#define RGN_DIFF	4
+#define RGN_OR	2
+#define RGN_XOR	3
+#define NULLREGION	1
+#define SIMPLEREGION	2
+#define COMPLEXREGION	3
+#define ERROR 0
+#define CBM_INIT	4
+#define DIB_PAL_COLORS	1
+#define DIB_RGB_COLORS	0
+#define FW_DONTCARE	0
+#define FW_THIN	100
+#define FW_EXTRALIGHT	200
+#define FW_ULTRALIGHT	FW_EXTRALIGHT
+#define FW_LIGHT	300
+#define FW_NORMAL	400
+#define FW_REGULAR	400
+#define FW_MEDIUM	500
+#define FW_SEMIBOLD	600
+#define FW_DEMIBOLD	FW_SEMIBOLD
+#define FW_BOLD	700
+#define FW_EXTRABOLD	800
+#define FW_ULTRABOLD	FW_EXTRABOLD
+#define FW_HEAVY	900
+#define FW_BLACK	FW_HEAVY
+#define ANSI_CHARSET	0
+#define DEFAULT_CHARSET	1
+#define SYMBOL_CHARSET	2
+#define SHIFTJIS_CHARSET	128
+#define HANGEUL_CHARSET	129
+#define HANGUL_CHARSET  129
+#define GB2312_CHARSET	134
+#define CHINESEBIG5_CHARSET	136
+#define GREEK_CHARSET	161
+#define TURKISH_CHARSET	162
+#define HEBREW_CHARSET	177
+#define ARABIC_CHARSET	178
+#define BALTIC_CHARSET	186
+#define RUSSIAN_CHARSET	204
+#define THAI_CHARSET	222
+#define EASTEUROPE_CHARSET	238
+#define OEM_CHARSET	255
+#define JOHAB_CHARSET	130
+#define VIETNAMESE_CHARSET	163
+#define MAC_CHARSET 77
+#define BALTIC_CHARSET 186
+#define JOHAB_CHARSET 130
+#define VIETNAMESE_CHARSET 163
+#define OUT_DEFAULT_PRECIS	0
+#define OUT_STRING_PRECIS	1
+#define OUT_CHARACTER_PRECIS	2
+#define OUT_STROKE_PRECIS	3
+#define OUT_TT_PRECIS	4
+#define OUT_DEVICE_PRECIS	5
+#define OUT_RASTER_PRECIS	6
+#define OUT_TT_ONLY_PRECIS	7
+#define OUT_OUTLINE_PRECIS	8
+#define CLIP_DEFAULT_PRECIS	0
+#define CLIP_CHARACTER_PRECIS	1
+#define CLIP_STROKE_PRECIS	2
+#define CLIP_MASK	15
+#define CLIP_LH_ANGLES	16
+#define CLIP_TT_ALWAYS	32
+#define CLIP_EMBEDDED	128
+#define DEFAULT_QUALITY	0
+#define DRAFT_QUALITY	1
+#define PROOF_QUALITY	2
+#define NONANTIALIASED_QUALITY 3
+#define ANTIALIASED_QUALITY 4
+#define DEFAULT_PITCH	0
+#define FIXED_PITCH	1
+#define VARIABLE_PITCH	2
+#define MONO_FONT 8
+#define FF_DECORATIVE	80
+#define FF_DONTCARE	0
+#define FF_MODERN	48
+#define FF_ROMAN	16
+#define FF_SCRIPT	64
+#define FF_SWISS	32
+#define PANOSE_COUNT 10
+#define PAN_FAMILYTYPE_INDEX 0
+#define PAN_SERIFSTYLE_INDEX 1
+#define PAN_WEIGHT_INDEX 2
+#define PAN_PROPORTION_INDEX 3
+#define PAN_CONTRAST_INDEX 4
+#define PAN_STROKEVARIATION_INDEX 5
+#define PAN_ARMSTYLE_INDEX 6
+#define PAN_LETTERFORM_INDEX 7
+#define PAN_MIDLINE_INDEX 8
+#define PAN_XHEIGHT_INDEX 9
+#define PAN_CULTURE_LATIN 0
+#define PAN_ANY 0
+#define PAN_NO_FIT 1
+#define PAN_FAMILY_TEXT_DISPLAY 2
+#define PAN_FAMILY_SCRIPT 3
+#define PAN_FAMILY_DECORATIVE 4
+#define PAN_FAMILY_PICTORIAL 5
+#define PAN_SERIF_COVE 2
+#define PAN_SERIF_OBTUSE_COVE 3
+#define PAN_SERIF_SQUARE_COVE 4
+#define PAN_SERIF_OBTUSE_SQUARE_COVE 5
+#define PAN_SERIF_SQUARE 6
+#define PAN_SERIF_THIN 7
+#define PAN_SERIF_BONE 8
+#define PAN_SERIF_EXAGGERATED 9
+#define PAN_SERIF_TRIANGLE 10
+#define PAN_SERIF_NORMAL_SANS 11
+#define PAN_SERIF_OBTUSE_SANS 12
+#define PAN_SERIF_PERP_SANS 13
+#define PAN_SERIF_FLARED 14
+#define PAN_SERIF_ROUNDED 15
+#define PAN_WEIGHT_VERY_LIGHT 2
+#define PAN_WEIGHT_LIGHT 3
+#define PAN_WEIGHT_THIN 4
+#define PAN_WEIGHT_BOOK 5
+#define PAN_WEIGHT_MEDIUM 6
+#define PAN_WEIGHT_DEMI 7
+#define PAN_WEIGHT_BOLD 8
+#define PAN_WEIGHT_HEAVY 9
+#define PAN_WEIGHT_BLACK 10
+#define PAN_WEIGHT_NORD 11
+#define PAN_PROP_OLD_STYLE 2
+#define PAN_PROP_MODERN 3
+#define PAN_PROP_EVEN_WIDTH 4
+#define PAN_PROP_EXPANDED 5
+#define PAN_PROP_CONDENSED 6
+#define PAN_PROP_VERY_EXPANDED 7
+#define PAN_PROP_VERY_CONDENSED 8
+#define PAN_PROP_MONOSPACED 9
+#define PAN_CONTRAST_NONE 2
+#define PAN_CONTRAST_VERY_LOW 3
+#define PAN_CONTRAST_LOW 4
+#define PAN_CONTRAST_MEDIUM_LOW 5
+#define PAN_CONTRAST_MEDIUM 6
+#define PAN_CONTRAST_MEDIUM_HIGH 7
+#define PAN_CONTRAST_HIGH 8
+#define PAN_CONTRAST_VERY_HIGH 9
+#define PAN_STROKE_GRADUAL_DIAG 2
+#define PAN_STROKE_GRADUAL_TRAN 3
+#define PAN_STROKE_GRADUAL_VERT 4
+#define PAN_STROKE_GRADUAL_HORZ 5
+#define PAN_STROKE_RAPID_VERT 6
+#define PAN_STROKE_RAPID_HORZ 7
+#define PAN_STROKE_INSTANT_VERT 8
+#define PAN_STRAIGHT_ARMS_HORZ 2
+#define PAN_STRAIGHT_ARMS_WEDGE 3
+#define PAN_STRAIGHT_ARMS_VERT 4
+#define PAN_STRAIGHT_ARMS_SINGLE_SERIF 5
+#define PAN_STRAIGHT_ARMS_DOUBLE_SERIF 6
+#define PAN_BENT_ARMS_HORZ 7
+#define PAN_BENT_ARMS_WEDGE 8
+#define PAN_BENT_ARMS_VERT 9
+#define PAN_BENT_ARMS_SINGLE_SERIF 10
+#define PAN_BENT_ARMS_DOUBLE_SERIF 11
+#define PAN_LETT_NORMAL_CONTACT 2
+#define PAN_LETT_NORMAL_WEIGHTED 3
+#define PAN_LETT_NORMAL_BOXED 4
+#define PAN_LETT_NORMAL_FLATTENED 5
+#define PAN_LETT_NORMAL_ROUNDED 6
+#define PAN_LETT_NORMAL_OFF_CENTER 7
+#define PAN_LETT_NORMAL_SQUARE 8
+#define PAN_LETT_OBLIQUE_CONTACT 9
+#define PAN_LETT_OBLIQUE_WEIGHTED 10
+#define PAN_LETT_OBLIQUE_BOXED 11
+#define PAN_LETT_OBLIQUE_FLATTENED 12
+#define PAN_LETT_OBLIQUE_ROUNDED 13
+#define PAN_LETT_OBLIQUE_OFF_CENTER 14
+#define PAN_LETT_OBLIQUE_SQUARE 15
+#define PAN_MIDLINE_STANDARD_TRIMMED 2
+#define PAN_MIDLINE_STANDARD_POINTED 3
+#define PAN_MIDLINE_STANDARD_SERIFED 4
+#define PAN_MIDLINE_HIGH_TRIMMED 5
+#define PAN_MIDLINE_HIGH_POINTED 6
+#define PAN_MIDLINE_HIGH_SERIFED 7
+#define PAN_MIDLINE_CONSTANT_TRIMMED 8
+#define PAN_MIDLINE_CONSTANT_POINTED 9
+#define PAN_MIDLINE_CONSTANT_SERIFED 10
+#define PAN_MIDLINE_LOW_TRIMMED 11
+#define PAN_MIDLINE_LOW_POINTED 12
+#define PAN_MIDLINE_LOW_SERIFED 13
+#define PAN_XHEIGHT_CONSTANT_SMALL 2
+#define PAN_XHEIGHT_CONSTANT_STD 3
+#define PAN_XHEIGHT_CONSTANT_LARGE 4
+#define PAN_XHEIGHT_DUCKING_SMALL 5
+#define PAN_XHEIGHT_DUCKING_STD 6
+#define PAN_XHEIGHT_DUCKING_LARGE 7
+#define FS_LATIN1 1
+#define FS_LATIN2 2
+#define FS_CYRILLIC 4
+#define FS_GREEK 8
+#define FS_TURKISH 16
+#define FS_HEBREW 32
+#define FS_ARABIC 64
+#define FS_BALTIC 128
+#define FS_THAI 0x10000
+#define FS_JISJAPAN 0x20000
+#define FS_CHINESESIMP 0x40000
+#define FS_WANSUNG 0x80000
+#define FS_CHINESETRAD 0x100000
+#define FS_JOHAB 0x200000
+#define FS_SYMBOL 0x80000000
+#define HS_BDIAGONAL	3
+#define HS_CROSS	4
+#define HS_DIAGCROSS	5
+#define HS_FDIAGONAL	2
+#define HS_HORIZONTAL	0
+#define HS_VERTICAL	1
+#define PS_GEOMETRIC	65536
+#define PS_COSMETIC	0
+#define PS_ALTERNATE	8
+#define PS_SOLID	0
+#define PS_DASH	1
+#define PS_DOT	2
+#define PS_DASHDOT	3
+#define PS_DASHDOTDOT	4
+#define PS_NULL	5
+#define PS_USERSTYLE	7
+#define PS_INSIDEFRAME	6
+#define PS_ENDCAP_ROUND	0
+#define PS_ENDCAP_SQUARE	256
+#define PS_ENDCAP_FLAT	512
+#define PS_JOIN_BEVEL	4096
+#define PS_JOIN_MITER	8192
+#define PS_JOIN_ROUND	0
+#define PS_STYLE_MASK	15
+#define PS_ENDCAP_MASK	3840
+#define PS_TYPE_MASK	983040
+#define ALTERNATE	1
+#define WINDING	2
+#define DC_BINNAMES	12
+#define DC_BINS	6
+#define DC_COPIES	18
+#define DC_DRIVER	11
+#define DC_DATATYPE_PRODUCED	21
+#define DC_DUPLEX	7
+#define DC_EMF_COMPLIANT	20
+#define DC_ENUMRESOLUTIONS	13
+#define DC_EXTRA	9
+#define DC_FIELDS	1
+#define DC_FILEDEPENDENCIES	14
+#define DC_MAXEXTENT	5
+#define DC_MINEXTENT	4
+#define DC_ORIENTATION	17
+#define DC_PAPERNAMES	16
+#define DC_PAPERS	2
+#define DC_PAPERSIZE	3
+#define DC_SIZE	8
+#define DC_TRUETYPE	15
+#define DCTT_BITMAP	1
+#define DCTT_DOWNLOAD	2
+#define DCTT_SUBDEV	4
+#define DCTT_DOWNLOAD_OUTLINE 8
+#define DC_VERSION	10
+#define DC_BINADJUST	19
+#define DC_EMF_COMPLIANT	20
+#define DC_DATATYPE_PRODUCED	21
+#define DC_MANUFACTURER	23
+#define DC_MODEL	24
+#define DCBA_FACEUPNONE	0
+#define DCBA_FACEUPCENTER	1
+#define DCBA_FACEUPLEFT	2
+#define DCBA_FACEUPRIGHT	3
+#define DCBA_FACEDOWNNONE	256
+#define DCBA_FACEDOWNCENTER	257
+#define DCBA_FACEDOWNLEFT	258
+#define DCBA_FACEDOWNRIGHT	259
+#define FLOODFILLBORDER 0
+#define FLOODFILLSURFACE 1
+#define ETO_CLIPPED 4
+#define ETO_GLYPH_INDEX 16
+#define ETO_OPAQUE 2
+#define ETO_RTLREADING 128
+#define GDICOMMENT_WINDOWS_METAFILE (-2147483647)
+#define GDICOMMENT_BEGINGROUP 2
+#define GDICOMMENT_ENDGROUP 3
+#define GDICOMMENT_MULTIFORMATS 1073741828
+#define GDICOMMENT_IDENTIFIER 1128875079
+#define AD_COUNTERCLOCKWISE 1
+#define AD_CLOCKWISE 2
+#define RDH_RECTANGLES	1
+#define GCPCLASS_LATIN	1
+#define GCPCLASS_HEBREW	2
+#define GCPCLASS_ARABIC	2
+#define GCPCLASS_NEUTRAL	3
+#define GCPCLASS_LOCALNUMBER	4
+#define GCPCLASS_LATINNUMBER	5
+#define GCPCLASS_LATINNUMERICTERMINATOR	6
+#define GCPCLASS_LATINNUMERICSEPARATOR	7
+#define GCPCLASS_NUMERICSEPARATOR	8
+#define GCPCLASS_PREBOUNDLTR	128
+#define GCPCLASS_PREBOUNDRTL	64
+#define GCPCLASS_POSTBOUNDLTR	32
+#define GCPCLASS_POSTBOUNDRTL	16
+#define GCPGLYPH_LINKBEFORE	0x8000
+#define GCPGLYPH_LINKAFTER	0x4000
+#define DCB_DISABLE 8
+#define DCB_ENABLE 4
+#define DCB_RESET 1
+#define DCB_SET 3
+#define DCB_ACCUMULATE 2
+#define DCB_DIRTY	2
+#define OBJ_BRUSH 2
+#define OBJ_PEN 1
+#define OBJ_PAL 5
+#define OBJ_FONT 6
+#define OBJ_BITMAP 7
+#define OBJ_EXTPEN 11
+#define OBJ_REGION 8
+#define OBJ_DC 3
+#define OBJ_MEMDC 10
+#define OBJ_METAFILE 9
+#define OBJ_METADC 4
+#define OBJ_ENHMETAFILE 13
+#define OBJ_ENHMETADC 12
+#define DRIVERVERSION 0
+#define TECHNOLOGY 2
+#define DT_PLOTTER 0
+#define DT_RASDISPLAY 1
+#define DT_RASPRINTER 2
+#define DT_RASCAMERA 3
+#define DT_CHARSTREAM 4
+#define DT_METAFILE 5
+#define DT_DISPFILE 6
+#define HORZSIZE 4
+#define VERTSIZE 6
+#define HORZRES 8
+#define VERTRES 10
+#define LOGPIXELSX 88
+#define LOGPIXELSY 90
+#define BITSPIXEL 12
+#define PLANES 14
+#define NUMBRUSHES 16
+#define NUMPENS 18
+#define NUMFONTS 22
+#define NUMCOLORS 24
+#define NUMMARKERS 20
+#define ASPECTX 40
+#define ASPECTY 42
+#define ASPECTXY 44
+#define PDEVICESIZE 26
+#define CLIPCAPS 36
+#define SIZEPALETTE 104
+#define NUMRESERVED 106
+#define COLORRES 108
+#define PHYSICALWIDTH 110
+#define PHYSICALHEIGHT 111
+#define PHYSICALOFFSETX 112
+#define PHYSICALOFFSETY 113
+#define SCALINGFACTORX 114
+#define SCALINGFACTORY 115
+#define VREFRESH 116
+#define DESKTOPHORZRES 118
+#define DESKTOPVERTRES 117
+#define BLTALIGNMENT 119
+#define RASTERCAPS 38
+#define RC_BANDING 2
+#define RC_BITBLT 1
+#define RC_BITMAP64 8
+#define RC_DI_BITMAP 128
+#define RC_DIBTODEV 512
+#define RC_FLOODFILL 4096
+#define RC_GDI20_OUTPUT 16
+#define RC_PALETTE 256
+#define RC_SCALING 4
+#define RC_STRETCHBLT 2048
+#define RC_STRETCHDIB 8192
+#define RC_DEVBITS 0x8000
+#define RC_OP_DX_OUTPUT 0x4000
+#define CURVECAPS 28
+#define CC_NONE 0
+#define CC_CIRCLES 1
+#define CC_PIE 2
+#define CC_CHORD 4
+#define CC_ELLIPSES 8
+#define CC_WIDE 16
+#define CC_STYLED 32
+#define CC_WIDESTYLED 64
+#define CC_INTERIORS 128
+#define CC_ROUNDRECT 256
+#define LINECAPS 30
+#define LC_NONE 0
+#define LC_POLYLINE 2
+#define LC_MARKER 4
+#define LC_POLYMARKER 8
+#define LC_WIDE 16
+#define LC_STYLED 32
+#define LC_WIDESTYLED 64
+#define LC_INTERIORS 128
+#define POLYGONALCAPS 32
+#define RC_BANDING 2
+#define RC_BIGFONT 1024
+#define RC_BITBLT 1
+#define RC_BITMAP64 8
+#define RC_DEVBITS 0x8000
+#define RC_DI_BITMAP 128
+#define RC_GDI20_OUTPUT 16
+#define RC_GDI20_STATE 32
+#define RC_NONE 0
+#define RC_OP_DX_OUTPUT 0x4000
+#define RC_PALETTE 256
+#define RC_SAVEBITMAP 64
+#define RC_SCALING 4
+#define PC_NONE 0
+#define PC_POLYGON 1
+#define PC_POLYPOLYGON 256
+#define PC_PATHS 512
+#define PC_RECTANGLE 2
+#define PC_WINDPOLYGON 4
+#define PC_SCANLINE 8
+#define PC_TRAPEZOID 4
+#define PC_WIDE 16
+#define PC_STYLED 32
+#define PC_WIDESTYLED 64
+#define PC_INTERIORS 128
+#define PC_PATHS 512
+#define TEXTCAPS 34
+#define TC_OP_CHARACTER 1
+#define TC_OP_STROKE 2
+#define TC_CP_STROKE 4
+#define TC_CR_90 8
+#define TC_CR_ANY 16
+#define TC_SF_X_YINDEP 32
+#define TC_SA_DOUBLE 64
+#define TC_SA_INTEGER 128
+#define TC_SA_CONTIN 256
+#define TC_EA_DOUBLE 512
+#define TC_IA_ABLE 1024
+#define TC_UA_ABLE 2048
+#define TC_SO_ABLE 4096
+#define TC_RA_ABLE 8192
+#define TC_VA_ABLE 16384
+#define TC_RESERVED 32768
+#define TC_SCROLLBLT 65536
+#define GCP_DBCS 1
+#define GCP_ERROR 0x8000
+#define GCP_CLASSIN 0x80000
+#define GCP_DIACRITIC 256
+#define GCP_DISPLAYZWG 0x400000
+#define GCP_GLYPHSHAPE 16
+#define GCP_JUSTIFY 0x10000
+#define GCP_JUSTIFYIN 0x200000
+#define GCP_KASHIDA 1024
+#define GCP_LIGATE 32
+#define GCP_MAXEXTENT 0x100000
+#define GCP_NEUTRALOVERRIDE 0x2000000
+#define GCP_NUMERICOVERRIDE 0x1000000
+#define GCP_NUMERICSLATIN 0x4000000
+#define GCP_NUMERICSLOCAL 0x8000000
+#define GCP_REORDER 2
+#define GCP_SYMSWAPOFF 0x800000
+#define GCP_USEKERNING 8
+#define FLI_GLYPHS 0x40000
+#define FLI_MASK 0x103b
+#define GGO_METRICS 0
+#define GGO_BITMAP 1
+#define GGO_NATIVE 2
+#define GGO_BEZIER 3
+#define GGO_GRAY2_BITMAP 4
+#define GGO_GRAY4_BITMAP 5
+#define GGO_GRAY8_BITMAP 6
+#define GGO_GLYPH_INDEX 128
+#define GGO_UNHINTED 256
+#define GM_COMPATIBLE 1
+#define GM_ADVANCED 2
+#define MM_ANISOTROPIC 8
+#define MM_HIENGLISH 5
+#define MM_HIMETRIC 3
+#define MM_ISOTROPIC 7
+#define MM_LOENGLISH 4
+#define MM_LOMETRIC 2
+#define MM_TEXT 1
+#define MM_TWIPS 6
+#define MM_MAX_FIXEDSCALE	MM_TWIPS
+#define ABSOLUTE	1
+#define RELATIVE	2
+#define PC_EXPLICIT 2
+#define PC_NOCOLLAPSE 4
+#define PC_RESERVED 1
+#define CLR_NONE 0xffffffff
+#define CLR_INVALID CLR_NONE
+#define CLR_DEFAULT 0xff000000
+#define PT_MOVETO 6
+#define PT_LINETO 2
+#define PT_BEZIERTO 4
+#define PT_CLOSEFIGURE 1
+#define TT_AVAILABLE 1
+#define TT_ENABLED 2
+#define BLACK_BRUSH 4
+#define DKGRAY_BRUSH 3
+#define GRAY_BRUSH 2
+#define HOLLOW_BRUSH 5
+#define LTGRAY_BRUSH 1
+#define NULL_BRUSH 5
+#define WHITE_BRUSH 0
+#define BLACK_PEN 7
+#define NULL_PEN 8
+#define WHITE_PEN 6
+#define ANSI_FIXED_FONT 11
+#define ANSI_VAR_FONT 12
+#define DEVICE_DEFAULT_FONT 14
+#define DEFAULT_GUI_FONT 17
+#define OEM_FIXED_FONT 10
+#define SYSTEM_FONT 13
+#define SYSTEM_FIXED_FONT 16
+#define DEFAULT_PALETTE 15
+#define SYSPAL_NOSTATIC 2
+#define SYSPAL_STATIC 1
+#define SYSPAL_ERROR 0
+#define TA_BASELINE 24
+#define TA_BOTTOM 8
+#define TA_TOP 0
+#define TA_CENTER 6
+#define TA_LEFT 0
+#define TA_RIGHT 2
+#define TA_RTLREADING 256
+#define TA_NOUPDATECP 0
+#define TA_UPDATECP 1
+#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
+#define VTA_BASELINE 24
+#define VTA_CENTER 6
+#define VTA_LEFT TA_BOTTOM
+#define VTA_RIGHT TA_TOP
+#define VTA_BOTTOM TA_RIGHT
+#define VTA_TOP TA_LEFT
+#define MWT_IDENTITY 1
+#define MWT_LEFTMULTIPLY 2
+#define MWT_RIGHTMULTIPLY 3
+#define OPAQUE 2
+#define TRANSPARENT 1
+#define BLACKONWHITE 1
+#define WHITEONBLACK 2
+#define COLORONCOLOR 3
+#define HALFTONE 4
+#define MAXSTRETCHBLTMODE 4
+#define STRETCH_ANDSCANS 1
+#define STRETCH_DELETESCANS 3
+#define STRETCH_HALFTONE 4
+#define STRETCH_ORSCANS 2
+#define TCI_SRCCHARSET 1
+#define TCI_SRCCODEPAGE 2
+#define TCI_SRCFONTSIG 3
+#define ICM_ON 2
+#define ICM_OFF 1
+#define ICM_QUERY 3
+#define NEWFRAME	1
+#define ABORTDOC	2
+#define NEXTBAND	3
+#define SETCOLORTABLE	4
+#define GETCOLORTABLE	5
+#define FLUSHOUTPUT	6
+#define DRAFTMODE	7
+#define QUERYESCSUPPORT	8
+#define SETABORTPROC	9
+#define STARTDOC	10
+#define ENDDOC	11
+#define GETPHYSPAGESIZE	12
+#define GETPRINTINGOFFSET	13
+#define GETSCALINGFACTOR	14
+#define MFCOMMENT	15
+#define GETPENWIDTH	16
+#define SETCOPYCOUNT	17
+#define SELECTPAPERSOURCE	18
+#define DEVICEDATA	19
+#define PASSTHROUGH	19
+#define GETTECHNOLGY	20
+#define GETTECHNOLOGY	20
+#define SETLINECAP	21
+#define SETLINEJOIN	22
+#define SETMITERLIMIT	23
+#define BANDINFO	24
+#define DRAWPATTERNRECT	25
+#define GETVECTORPENSIZE	26
+#define GETVECTORBRUSHSIZE	27
+#define ENABLEDUPLEX	28
+#define GETSETPAPERBINS	29
+#define GETSETPRINTORIENT	30
+#define ENUMPAPERBINS	31
+#define SETDIBSCALING	32
+#define EPSPRINTING	33
+#define ENUMPAPERMETRICS	34
+#define GETSETPAPERMETRICS	35
+#define POSTSCRIPT_DATA	37
+#define POSTSCRIPT_IGNORE	38
+#define MOUSETRAILS	39
+#define GETDEVICEUNITS	42
+#define GETEXTENDEDTEXTMETRICS	256
+#define GETEXTENTTABLE	257
+#define GETPAIRKERNTABLE	258
+#define GETTRACKKERNTABLE	259
+#define EXTTEXTOUT	512
+#define GETFACENAME	513
+#define DOWNLOADFACE	514
+#define ENABLERELATIVEWIDTHS	768
+#define ENABLEPAIRKERNING	769
+#define SETKERNTRACK	770
+#define SETALLJUSTVALUES	771
+#define SETCHARSET	772
+#define STRETCHBLT	2048
+#define GETSETSCREENPARAMS	3072
+#define QUERYDIBSUPPORT	3073
+#define BEGIN_PATH	4096
+#define CLIP_TO_PATH	4097
+#define END_PATH	4098
+#define EXT_DEVICE_CAPS	4099
+#define RESTORE_CTM	4100
+#define SAVE_CTM	4101
+#define SET_ARC_DIRECTION	4102
+#define SET_BACKGROUND_COLOR	4103
+#define SET_POLY_MODE	4104
+#define SET_SCREEN_ANGLE	4105
+#define SET_SPREAD	4106
+#define TRANSFORM_CTM	4107
+#define SET_CLIP_BOX	4108
+#define SET_BOUNDS	4109
+#define SET_MIRROR_MODE	4110
+#define OPENCHANNEL	4110
+#define DOWNLOADHEADER	4111
+#define CLOSECHANNEL	4112
+#define POSTSCRIPT_PASSTHROUGH	4115
+#define ENCAPSULATED_POSTSCRIPT	4116
+#define QDI_SETDIBITS	1
+#define QDI_GETDIBITS	2
+#define QDI_DIBTOSCREEN	4
+#define QDI_STRETCHDIB	8
+#define SP_NOTREPORTED	0x4000
+#define PR_JOBSTATUS	0
+#define ASPECT_FILTERING	1
+#define BS_SOLID	0
+#define BS_NULL	1
+#define BS_HOLLOW	1
+#define BS_HATCHED	2
+#define BS_PATTERN	3
+#define BS_INDEXED	4
+#define BS_DIBPATTERN	5
+#define BS_DIBPATTERNPT	6
+#define BS_PATTERN8X8	7
+#define BS_DIBPATTERN8X8	8
+#define LCS_CALIBRATED_RGB	0
+#define LCS_DEVICE_RGB	1
+#define LCS_DEVICE_CMYK	2
+#define LCS_GM_BUSINESS	1
+#define LCS_GM_GRAPHICS	2
+#define LCS_GM_IMAGES	4
+#define RASTER_FONTTYPE	1
+#define DEVICE_FONTTYPE	2
+#define TRUETYPE_FONTTYPE	4
+#define DMORIENT_PORTRAIT   1
+#define DMORIENT_LANDSCAPE  2
+#define DMPAPER_FIRST	1
+#define DMPAPER_LETTER	1
+#define DMPAPER_LETTERSMALL	2
+#define DMPAPER_TABLOID	3
+#define DMPAPER_LEDGER	4
+#define DMPAPER_LEGAL	5
+#define DMPAPER_STATEMENT	6
+#define DMPAPER_EXECUTIVE	7
+#define DMPAPER_A3	8
+#define DMPAPER_A4	9
+#define DMPAPER_A4SMALL	10
+#define DMPAPER_A5	11
+#define DMPAPER_B4	12
+#define DMPAPER_B5	13
+#define DMPAPER_FOLIO	14
+#define DMPAPER_QUARTO	15
+#define DMPAPER_10X14	16
+#define DMPAPER_11X17	17
+#define DMPAPER_NOTE	18
+#define DMPAPER_ENV_9	19
+#define DMPAPER_ENV_10	20
+#define DMPAPER_ENV_11	21
+#define DMPAPER_ENV_12	22
+#define DMPAPER_ENV_14	23
+#define DMPAPER_CSHEET	24
+#define DMPAPER_DSHEET	25
+#define DMPAPER_ESHEET	26
+#define DMPAPER_ENV_DL	27
+#define DMPAPER_ENV_C5	28
+#define DMPAPER_ENV_C3	29
+#define DMPAPER_ENV_C4	30
+#define DMPAPER_ENV_C6	31
+#define DMPAPER_ENV_C65	32
+#define DMPAPER_ENV_B4	33
+#define DMPAPER_ENV_B5	34
+#define DMPAPER_ENV_B6	35
+#define DMPAPER_ENV_ITALY	36
+#define DMPAPER_ENV_MONARCH	37
+#define DMPAPER_ENV_PERSONAL	38
+#define DMPAPER_FANFOLD_US	39
+#define DMPAPER_FANFOLD_STD_GERMAN	40
+#define DMPAPER_FANFOLD_LGL_GERMAN	41
+#define DMPAPER_ISO_B4	42
+#define DMPAPER_JAPANESE_POSTCARD	43
+#define DMPAPER_9X11	44
+#define DMPAPER_10X11	45
+#define DMPAPER_15X11	46
+#define DMPAPER_ENV_INVITE	47
+#define DMPAPER_RESERVED_48	48
+#define DMPAPER_RESERVED_49	49
+#define DMPAPER_LETTER_EXTRA	50
+#define DMPAPER_LEGAL_EXTRA	51
+#define DMPAPER_TABLOID_EXTRA	52
+#define DMPAPER_A4_EXTRA	53
+#define DMPAPER_LETTER_TRANSVERSE	54
+#define DMPAPER_A4_TRANSVERSE	55
+#define DMPAPER_LETTER_EXTRA_TRANSVERSE	56
+#define DMPAPER_A_PLUS	57
+#define DMPAPER_B_PLUS	58
+#define DMPAPER_LETTER_PLUS	59
+#define DMPAPER_A4_PLUS	60
+#define DMPAPER_A5_TRANSVERSE	61
+#define DMPAPER_B5_TRANSVERSE	62
+#define DMPAPER_A3_EXTRA	63
+#define DMPAPER_A5_EXTRA	64
+#define DMPAPER_B5_EXTRA	65
+#define DMPAPER_A2	66
+#define DMPAPER_A3_TRANSVERSE	67
+#define DMPAPER_A3_EXTRA_TRANSVERSE	68
+#define DMPAPER_LAST	68
+#define DMPAPER_USER	256
+#define DMBIN_FIRST	1
+#define DMBIN_UPPER	1
+#define DMBIN_ONLYONE	1
+#define DMBIN_LOWER	2
+#define DMBIN_MIDDLE	3
+#define DMBIN_MANUAL	4
+#define DMBIN_ENVELOPE	5
+#define DMBIN_ENVMANUAL	6
+#define DMBIN_AUTO	7
+#define DMBIN_TRACTOR	8
+#define DMBIN_SMALLFMT	9
+#define DMBIN_LARGEFMT	10
+#define DMBIN_LARGECAPACITY	11
+#define DMBIN_CASSETTE	14
+#define DMBIN_FORMSOURCE	15
+#define DMBIN_LAST	15
+#define DMBIN_USER	256
+#define DMRES_DRAFT	(-1)
+#define DMRES_LOW	(-2)
+#define DMRES_MEDIUM	(-3)
+#define DMRES_HIGH	(-4)
+#define DMCOLOR_MONOCHROME	1
+#define DMCOLOR_COLOR	2
+#define DMDUP_SIMPLEX	1
+#define DMDUP_VERTICAL	2
+#define DMDUP_HORIZONTAL	3
+#define DMTT_BITMAP	1
+#define DMTT_DOWNLOAD	2
+#define DMTT_SUBDEV	3
+#define DMTT_DOWNLOAD_OUTLINE	4
+#define DMCOLLATE_FALSE	0
+#define DMCOLLATE_TRUE	1
+#define DM_GRAYSCALE	1
+#define DM_INTERLACED	2
+#define DM_UPDATE	1
+#define DM_COPY	2
+#define DM_PROMPT	4
+#define DM_MODIFY	8
+#define DM_IN_BUFFER	DM_MODIFY
+#define DM_IN_PROMPT	DM_PROMPT
+#define DM_OUT_BUFFER	DM_COPY
+#define DM_OUT_DEFAULT	DM_UPDATE
+#define DM_ORIENTATION 1
+#define DM_PAPERSIZE 2
+#define DM_PAPERLENGTH 4
+#define DM_PAPERWIDTH 8
+#define DM_SCALE 16
+#define DM_COPIES 256
+#define DM_DEFAULTSOURCE 512
+#define DM_PRINTQUALITY 1024
+#define DM_COLOR 2048
+#define DM_DUPLEX 4096
+#define DM_YRESOLUTION 8192
+#define DM_TTOPTION 16384
+#define DM_COLLATE 32768
+#define DM_FORMNAME 65536
+#define DM_LOGPIXELS 0x20000
+#define DM_BITSPERPEL 0x40000
+#define DM_PELSWIDTH 0x80000
+#define DM_PELSHEIGHT 0x100000
+#define DM_DISPLAYFLAGS 0x200000
+#define DM_DISPLAYFREQUENCY 0x400000
+#define DM_ICMMETHOD 0x800000
+#define DM_ICMINTENT 0x1000000
+#define DM_MEDIATYPE 0x2000000
+#define DM_DITHERTYPE 0x4000000
+#define DMICMMETHOD_NONE	1
+#define DMICMMETHOD_SYSTEM	2
+#define DMICMMETHOD_DRIVER	3
+#define DMICMMETHOD_DEVICE	4
+#define DMICMMETHOD_USER	256
+#define DMICM_SATURATE	1
+#define DMICM_CONTRAST	2
+#define DMICM_COLORMETRIC	3
+#define DMICM_USER	256
+#define DMMEDIA_STANDARD	1
+#define DMMEDIA_TRANSPARENCY	2
+#define DMMEDIA_GLOSSY	3
+#define DMMEDIA_USER	256
+#define DMDITHER_NONE	1
+#define DMDITHER_COARSE	2
+#define DMDITHER_FINE	3
+#define DMDITHER_LINEART	4
+#define DMDITHER_ERRORDIFFUSION	5
+#define DMDITHER_RESERVED6	6
+#define DMDITHER_RESERVED7	7
+#define DMDITHER_RESERVED8	8
+#define DMDITHER_RESERVED9	9
+#define DMDITHER_GRAYSCALE	10
+#define DMDITHER_USER	256
+#define GDI_ERROR 0xFFFFFFFF
+#define HGDI_ERROR ((HANDLE)GDI_ERROR)
+#define TMPF_FIXED_PITCH 1
+#define TMPF_VECTOR 2
+#define TMPF_TRUETYPE 4
+#define TMPF_DEVICE 8
+#define NTM_ITALIC 1
+#define NTM_BOLD 32
+#define NTM_REGULAR 64
+#define TT_POLYGON_TYPE 24
+#define TT_PRIM_LINE 1
+#define TT_PRIM_QSPLINE 2
+#define FONTMAPPER_MAX 10
+#define ENHMETA_STOCK_OBJECT 0x80000000
+#define WGL_FONT_LINES 0
+#define WGL_FONT_POLYGONS 1
+#define LPD_DOUBLEBUFFER 1
+#define LPD_STEREO 2
+#define LPD_SUPPORT_GDI 16
+#define LPD_SUPPORT_OPENGL 32
+#define LPD_SHARE_DEPTH 64
+#define LPD_SHARE_STENCIL 128
+#define LPD_SHARE_ACCUM 256
+#define LPD_SWAP_EXCHANGE 512
+#define LPD_SWAP_COPY 1024
+#define LPD_TRANSPARENT 4096
+#define LPD_TYPE_RGBA 0
+#define LPD_TYPE_COLORINDEX 1
+#define WGL_SWAP_MAIN_PLANE 1
+#define WGL_SWAP_OVERLAY1 2
+#define WGL_SWAP_OVERLAY2 4
+#define WGL_SWAP_OVERLAY3 8
+#define WGL_SWAP_OVERLAY4 16
+#define WGL_SWAP_OVERLAY5 32
+#define WGL_SWAP_OVERLAY6 64
+#define WGL_SWAP_OVERLAY7 128
+#define WGL_SWAP_OVERLAY8 256
+#define WGL_SWAP_OVERLAY9 512
+#define WGL_SWAP_OVERLAY10 1024
+#define WGL_SWAP_OVERLAY11 2048
+#define WGL_SWAP_OVERLAY12 4096
+#define WGL_SWAP_OVERLAY13 8192
+#define WGL_SWAP_OVERLAY14 16384
+#define WGL_SWAP_OVERLAY15 32768
+#define WGL_SWAP_UNDERLAY1 65536
+#define WGL_SWAP_UNDERLAY2 0x20000
+#define WGL_SWAP_UNDERLAY3 0x40000
+#define WGL_SWAP_UNDERLAY4 0x80000
+#define WGL_SWAP_UNDERLAY5 0x100000
+#define WGL_SWAP_UNDERLAY6 0x200000
+#define WGL_SWAP_UNDERLAY7 0x400000
+#define WGL_SWAP_UNDERLAY8 0x800000
+#define WGL_SWAP_UNDERLAY9 0x1000000
+#define WGL_SWAP_UNDERLAY10 0x2000000
+#define WGL_SWAP_UNDERLAY11 0x4000000
+#define WGL_SWAP_UNDERLAY12 0x8000000
+#define WGL_SWAP_UNDERLAY13 0x10000000
+#define WGL_SWAP_UNDERLAY14 0x20000000
+#define WGL_SWAP_UNDERLAY15 0x40000000
+#define AC_SRC_OVER 0
+#define LAYOUT_RTL 1
+#define LAYOUT_BITMAPORIENTATIONPRESERVED 8
+
+#ifndef RC_INVOKED
+typedef struct _ABC {
+	int abcA;
+	UINT abcB;
+	int abcC;
+} ABC,*LPABC;
+typedef struct _ABCFLOAT {
+	FLOAT abcfA;
+	FLOAT abcfB;
+	FLOAT abcfC;
+} ABCFLOAT,*LPABCFLOAT;
+typedef struct tagBITMAP {
+	LONG	bmType;
+	LONG	bmWidth;
+	LONG	bmHeight;
+	LONG	bmWidthBytes;
+	WORD	bmPlanes;
+	WORD	bmBitsPixel;
+	LPVOID	bmBits;
+} BITMAP,*PBITMAP,*LPBITMAP;
+typedef struct tagBITMAPCOREHEADER {
+	DWORD	bcSize;
+	WORD	bcWidth;
+	WORD	bcHeight;
+	WORD	bcPlanes;
+	WORD	bcBitCount;
+} BITMAPCOREHEADER,*LPBITMAPCOREHEADER,*PBITMAPCOREHEADER;
+#pragma pack(push,1)
+typedef struct tagRGBTRIPLE {
+	BYTE rgbtBlue;
+	BYTE rgbtGreen;
+	BYTE rgbtRed;
+} RGBTRIPLE;
+#pragma pack(pop)
+#pragma pack(push,2)
+typedef struct tagBITMAPFILEHEADER {
+	WORD	bfType;
+	DWORD	bfSize;
+	WORD	bfReserved1;
+	WORD	bfReserved2;
+	DWORD	bfOffBits;
+} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
+#pragma pack(pop)
+typedef struct _BITMAPCOREINFO {
+	BITMAPCOREHEADER	bmciHeader;
+	RGBTRIPLE	bmciColors[1];
+} BITMAPCOREINFO,*LPBITMAPCOREINFO,*PBITMAPCOREINFO;
+typedef struct tagBITMAPINFOHEADER{
+	DWORD	biSize;
+	LONG	biWidth;
+	LONG	biHeight;
+	WORD	biPlanes;
+	WORD	biBitCount;
+	DWORD	biCompression;
+	DWORD	biSizeImage;
+	LONG	biXPelsPerMeter;
+	LONG	biYPelsPerMeter;
+	DWORD	biClrUsed;
+	DWORD	biClrImportant;
+} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
+typedef struct tagRGBQUAD {
+	BYTE	rgbBlue;
+	BYTE	rgbGreen;
+	BYTE	rgbRed;
+	BYTE	rgbReserved;
+} RGBQUAD;
+typedef struct tagBITMAPINFO {
+	BITMAPINFOHEADER bmiHeader;
+	RGBQUAD bmiColors[1];
+} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;
+typedef long FXPT16DOT16,*LPFXPT16DOT16;
+typedef long FXPT2DOT30,*LPFXPT2DOT30;
+typedef struct tagCIEXYZ {
+	FXPT2DOT30 ciexyzX;
+	FXPT2DOT30 ciexyzY;
+	FXPT2DOT30 ciexyzZ;
+} CIEXYZ,*LPCIEXYZ;
+typedef struct tagCIEXYZTRIPLE {
+	CIEXYZ ciexyzRed;
+	CIEXYZ ciexyzGreen;
+	CIEXYZ ciexyzBlue;
+} CIEXYZTRIPLE,*LPCIEXYZTRIPLE;
+typedef struct {
+	DWORD	bV4Size;
+	LONG	bV4Width;
+	LONG	bV4Height;
+	WORD	bV4Planes;
+	WORD	bV4BitCount;
+	DWORD	bV4V4Compression;
+	DWORD	bV4SizeImage;
+	LONG	bV4XPelsPerMeter;
+	LONG	bV4YPelsPerMeter;
+	DWORD	bV4ClrUsed;
+	DWORD	bV4ClrImportant;
+	DWORD	bV4RedMask;
+	DWORD	bV4GreenMask;
+	DWORD	bV4BlueMask;
+	DWORD	bV4AlphaMask;
+	DWORD	bV4CSType;
+	CIEXYZTRIPLE bV4Endpoints;
+	DWORD	bV4GammaRed;
+	DWORD	bV4GammaGreen;
+	DWORD	bV4GammaBlue;
+} BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER;
+typedef struct tagFONTSIGNATURE {
+	DWORD	fsUsb[4];
+	DWORD	fsCsb[2];
+} FONTSIGNATURE,*LPFONTSIGNATURE;
+typedef struct {
+	UINT ciCharset;
+	UINT ciACP;
+	FONTSIGNATURE fs;
+} CHARSETINFO,*LPCHARSETINFO;
+typedef struct  tagCOLORADJUSTMENT {
+	WORD	caSize;
+	WORD	caFlags;
+	WORD	caIlluminantIndex;
+	WORD	caRedGamma;
+	WORD	caGreenGamma;
+	WORD	caBlueGamma;
+	WORD	caReferenceBlack;
+	WORD	caReferenceWhite;
+	SHORT	caContrast;
+	SHORT	caBrightness;
+	SHORT	caColorfulness;
+	SHORT	caRedGreenTint;
+} COLORADJUSTMENT,*LPCOLORADJUSTMENT;
+typedef struct _devicemodeA {
+	BYTE dmDeviceName[CCHDEVICENAME];
+	WORD dmSpecVersion;
+	WORD dmDriverVersion;
+	WORD dmSize;
+	WORD dmDriverExtra;
+	DWORD dmFields;
+	short dmOrientation;
+	short dmPaperSize;
+	short dmPaperLength;
+	short dmPaperWidth;
+	short dmScale;
+	short dmCopies;
+	short dmDefaultSource;
+	short dmPrintQuality;
+	short dmColor;
+	short dmDuplex;
+	short dmYResolution;
+	short dmTTOption;
+	short dmCollate;
+	BYTE dmFormName[CCHFORMNAME];
+	WORD dmLogPixels;
+	DWORD dmBitsPerPel;
+	DWORD dmPelsWidth;
+	DWORD dmPelsHeight;
+	DWORD dmDisplayFlags;
+	DWORD dmDisplayFrequency;
+	DWORD dmICMMethod;
+	DWORD dmICMIntent;
+	DWORD dmMediaType;
+	DWORD dmDitherType;
+	DWORD dmICCManufacturer;
+	DWORD dmICCModel;
+} DEVMODEA,*LPDEVMODEA,*PDEVMODEA;
+typedef struct _devicemodeW {
+	WCHAR dmDeviceName[CCHDEVICENAME];
+	WORD dmSpecVersion;
+	WORD dmDriverVersion;
+	WORD dmSize;
+	WORD dmDriverExtra;
+	DWORD dmFields;
+	short dmOrientation;
+	short dmPaperSize;
+	short dmPaperLength;
+	short dmPaperWidth;
+	short dmScale;
+	short dmCopies;
+	short dmDefaultSource;
+	short dmPrintQuality;
+	short dmColor;
+	short dmDuplex;
+	short dmYResolution;
+	short dmTTOption;
+	short dmCollate;
+	WCHAR dmFormName[CCHFORMNAME];
+	WORD dmLogPixels;
+	DWORD dmBitsPerPel;
+	DWORD dmPelsWidth;
+	DWORD dmPelsHeight;
+	DWORD dmDisplayFlags;
+	DWORD dmDisplayFrequency;
+	DWORD dmICMMethod;
+	DWORD dmICMIntent;
+	DWORD dmMediaType;
+	DWORD dmDitherType;
+	DWORD dmICCManufacturer;
+	DWORD dmICCModel;
+} DEVMODEW,*LPDEVMODEW,*PDEVMODEW;
+typedef struct tagDIBSECTION {
+	BITMAP dsBm;
+	BITMAPINFOHEADER dsBmih;
+	DWORD dsBitfields[3];
+	HANDLE dshSection;
+	DWORD dsOffset;
+} DIBSECTION;
+typedef struct _DOCINFOA {
+	int cbSize;
+	LPCTSTR lpszDocName;
+	LPCTSTR lpszOutput;
+	LPCTSTR lpszDatatype;
+	DWORD fwType;
+} DOCINFOA,*LPDOCINFOA;
+typedef struct _DOCINFOW {
+	int cbSize;
+	LPCWSTR lpszDocName;
+	LPCWSTR lpszOutput;
+	LPCWSTR lpszDatatype;
+	DWORD fwType;
+} DOCINFOW,*LPDOCINFOW;
+typedef struct tagEMR {
+	DWORD iType;
+	DWORD nSize;
+} EMR,*PEMR;
+typedef struct tagEMRANGLEARC {
+	EMR emr;
+	POINTL ptlCenter;
+	DWORD nRadius;
+	FLOAT eStartAngle;
+	FLOAT eSweepAngle;
+} EMRANGLEARC,*PEMRANGLEARC;
+typedef struct tagEMRARC {
+	EMR emr;
+	RECTL rclBox;
+	POINTL ptlStart;
+	POINTL ptlEnd;
+} EMRARC,*PEMRARC,EMRARCTO,*PEMRARCTO,EMRCHORD,*PEMRCHORD,EMRPIE,*PEMRPIE;
+typedef struct  _XFORM {
+	FLOAT eM11;
+	FLOAT eM12;
+	FLOAT eM21;
+	FLOAT eM22;
+	FLOAT eDx;
+	FLOAT eDy;
+} XFORM,*LPXFORM;
+typedef struct tagEMRBITBLT {
+	EMR emr;
+	RECTL rclBounds;
+	LONG xDest;
+	LONG yDest;
+	LONG cxDest;
+	LONG cyDest;
+	DWORD dwRop;
+	LONG xSrc;
+	LONG ySrc;
+	XFORM xformSrc;
+	COLORREF crBkColorSrc;
+	DWORD iUsageSrc;
+	DWORD offBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+} EMRBITBLT,*PEMRBITBLT;
+typedef struct tagLOGBRUSH {
+	UINT lbStyle;
+	COLORREF lbColor;
+	LONG lbHatch;
+} LOGBRUSH,*LPLOGBRUSH;
+typedef LOGBRUSH PATTERN,*PPATTERN,*LPPATTERN;
+typedef struct tagEMRCREATEBRUSHINDIRECT {
+	EMR emr;
+	DWORD ihBrush;
+	LOGBRUSH lb;
+} EMRCREATEBRUSHINDIRECT,*PEMRCREATEBRUSHINDIRECT;
+typedef LONG LCSCSTYPE;
+typedef LONG LCSGAMUTMATCH;
+typedef struct tagLOGCOLORSPACEA {
+	DWORD lcsSignature;
+	DWORD lcsVersion;
+	DWORD lcsSize;
+	LCSCSTYPE lcsCSType;
+	LCSGAMUTMATCH lcsIntent;
+	CIEXYZTRIPLE lcsEndpoints;
+	DWORD lcsGammaRed;
+	DWORD lcsGammaGreen;
+	DWORD lcsGammaBlue;
+	CHAR lcsFilename[MAX_PATH];
+} LOGCOLORSPACEA,*LPLOGCOLORSPACEA;
+typedef struct tagLOGCOLORSPACEW {
+	DWORD lcsSignature;
+	DWORD lcsVersion;
+	DWORD lcsSize;
+	LCSCSTYPE lcsCSType;
+	LCSGAMUTMATCH lcsIntent;
+	CIEXYZTRIPLE lcsEndpoints;
+	DWORD lcsGammaRed;
+	DWORD lcsGammaGreen;
+	DWORD lcsGammaBlue;
+	WCHAR lcsFilename[MAX_PATH];
+} LOGCOLORSPACEW,*LPLOGCOLORSPACEW;
+typedef struct tagEMRCREATECOLORSPACE {
+	EMR emr;
+	DWORD ihCS;
+	LOGCOLORSPACEW lcs;
+} EMRCREATECOLORSPACE,*PEMRCREATECOLORSPACE;
+typedef struct tagEMRCREATEDIBPATTERNBRUSHPT {
+	EMR emr;
+	DWORD ihBrush;
+	DWORD iUsage;
+	DWORD offBmi;
+	DWORD cbBmi;
+	DWORD offBits;
+	DWORD cbBits;
+} EMRCREATEDIBPATTERNBRUSHPT,*PEMRCREATEDIBPATTERNBRUSHPT;
+typedef struct tagEMRCREATEMONOBRUSH {
+	EMR emr;
+	DWORD ihBrush;
+	DWORD iUsage;
+	DWORD offBmi;
+	DWORD cbBmi;
+	DWORD offBits;
+	DWORD cbBits;
+} EMRCREATEMONOBRUSH,*PEMRCREATEMONOBRUSH;
+typedef struct tagPALETTEENTRY {
+	BYTE peRed;
+	BYTE peGreen;
+	BYTE peBlue;
+	BYTE peFlags;
+} PALETTEENTRY,*LPPALETTEENTRY,*PPALETTEENTRY;
+typedef struct tagLOGPALETTE {
+	WORD palVersion;
+	WORD palNumEntries;
+	PALETTEENTRY palPalEntry[1];
+} LOGPALETTE,*NPLOGPALETTE,*PLOGPALETTE,*LPLOGPALETTE;
+typedef struct tagEMRCREATEPALETTE {
+	EMR emr;
+	DWORD ihPal;
+	LOGPALETTE lgpl;
+} EMRCREATEPALETTE,*PEMRCREATEPALETTE;
+typedef struct tagLOGPEN {
+	UINT lopnStyle;
+	POINT lopnWidth;
+	COLORREF lopnColor;
+} LOGPEN,*LPLOGPEN;
+typedef struct tagEMRCREATEPEN {
+	EMR emr;
+	DWORD ihPen;
+	LOGPEN lopn;
+} EMRCREATEPEN,*PEMRCREATEPEN;
+typedef struct tagEMRELLIPSE {
+	EMR emr;
+	RECTL rclBox;
+} EMRELLIPSE,*PEMRELLIPSE,EMRRECTANGLE,*PEMRRECTANGLE;
+typedef struct tagEMREOF {
+	EMR emr;
+	DWORD nPalEntries;
+	DWORD offPalEntries;
+	DWORD nSizeLast;
+} EMREOF,*PEMREOF;
+typedef struct tagEMREXCLUDECLIPRECT {
+	EMR emr;
+	RECTL rclClip;
+} EMREXCLUDECLIPRECT,*PEMREXCLUDECLIPRECT,EMRINTERSECTCLIPRECT,*PEMRINTERSECTCLIPRECT;
+typedef struct tagPANOSE {
+	BYTE bFamilyType;
+	BYTE bSerifStyle;
+	BYTE bWeight;
+	BYTE bProportion;
+	BYTE bContrast;
+	BYTE bStrokeVariation;
+	BYTE bArmStyle;
+	BYTE bLetterform;
+	BYTE bMidline;
+	BYTE bXHeight;
+} PANOSE;
+typedef struct tagLOGFONTA {
+	LONG	lfHeight;
+	LONG	lfWidth;
+	LONG	lfEscapement;
+	LONG	lfOrientation;
+	LONG	lfWeight;
+	BYTE	lfItalic;
+	BYTE	lfUnderline;
+	BYTE	lfStrikeOut;
+	BYTE	lfCharSet;
+	BYTE	lfOutPrecision;
+	BYTE	lfClipPrecision;
+	BYTE	lfQuality;
+	BYTE	lfPitchAndFamily;
+	CHAR	lfFaceName[LF_FACESIZE];
+} LOGFONTA,*PLOGFONTA,*LPLOGFONTA;
+typedef struct tagLOGFONTW {
+	LONG	lfHeight;
+	LONG	lfWidth;
+	LONG	lfEscapement;
+	LONG	lfOrientation;
+	LONG	lfWeight;
+	BYTE	lfItalic;
+	BYTE	lfUnderline;
+	BYTE	lfStrikeOut;
+	BYTE	lfCharSet;
+	BYTE	lfOutPrecision;
+	BYTE	lfClipPrecision;
+	BYTE	lfQuality;
+	BYTE	lfPitchAndFamily;
+	WCHAR	lfFaceName[LF_FACESIZE];
+} LOGFONTW,*PLOGFONTW,*LPLOGFONTW;
+typedef struct tagEXTLOGFONTA {
+	LOGFONTA	elfLogFont;
+	BYTE	elfFullName[LF_FULLFACESIZE];
+	BYTE	elfStyle[LF_FACESIZE];
+	DWORD	elfVersion;
+	DWORD	elfStyleSize;
+	DWORD	elfMatch;
+	DWORD	elfReserved;
+	BYTE	elfVendorId[ELF_VENDOR_SIZE];
+	DWORD	elfCulture;
+	PANOSE	elfPanose;
+} EXTLOGFONTA,*PEXTLOGFONTA,*LPEXTLOGFONTA;
+typedef struct tagEXTLOGFONTW {
+	LOGFONTW	elfLogFont;
+	WCHAR	elfFullName[LF_FULLFACESIZE];
+	WCHAR	elfStyle[LF_FACESIZE];
+	DWORD	elfVersion;
+	DWORD	elfStyleSize;
+	DWORD	elfMatch;
+	DWORD	elfReserved;
+	BYTE	elfVendorId[ELF_VENDOR_SIZE];
+	DWORD	elfCulture;
+	PANOSE	elfPanose;
+} EXTLOGFONTW,*PEXTLOGFONTW,*LPEXTLOGFONTW;
+typedef struct tagEMREXTCREATEFONTINDIRECTW {
+	EMR emr;
+	DWORD ihFont;
+	EXTLOGFONTW elfw;
+} EMREXTCREATEFONTINDIRECTW,*PEMREXTCREATEFONTINDIRECTW;
+typedef struct tagEXTLOGPEN {
+	UINT elpPenStyle;
+	UINT elpWidth;
+	UINT elpBrushStyle;
+	COLORREF elpColor;
+	LONG elpHatch;
+	DWORD elpNumEntries;
+	DWORD elpStyleEntry[1];
+} EXTLOGPEN,*PEXTLOGPEN,*LPEXTLOGPEN;
+typedef struct tagEMREXTCREATEPEN {
+	EMR emr;
+	DWORD ihPen;
+	DWORD offBmi;
+	DWORD cbBmi;
+	DWORD offBits;
+	DWORD cbBits;
+	EXTLOGPEN elp;
+} EMREXTCREATEPEN,*PEMREXTCREATEPEN;
+typedef struct tagEMREXTFLOODFILL {
+	EMR emr;
+	POINTL ptlStart;
+	COLORREF crColor;
+	DWORD iMode;
+} EMREXTFLOODFILL,*PEMREXTFLOODFILL;
+typedef struct tagEMREXTSELECTCLIPRGN {
+	EMR emr;
+	DWORD cbRgnData;
+	DWORD iMode;
+	BYTE RgnData[1];
+} EMREXTSELECTCLIPRGN,*PEMREXTSELECTCLIPRGN;
+typedef struct tagEMRTEXT {
+	POINTL ptlReference;
+	DWORD nChars;
+	DWORD offString;
+	DWORD fOptions;
+	RECTL rcl;
+	DWORD offDx;
+} EMRTEXT,*PEMRTEXT;
+typedef struct tagEMREXTTEXTOUTA {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD iGraphicsMode;
+	FLOAT exScale;
+	FLOAT eyScale;
+	EMRTEXT emrtext;
+} EMREXTTEXTOUTA,*PEMREXTTEXTOUTA,EMREXTTEXTOUTW,*PEMREXTTEXTOUTW;
+typedef struct tagEMRFILLPATH {
+	EMR emr;
+	RECTL rclBounds;
+} EMRFILLPATH,*PEMRFILLPATH,EMRSTROKEANDFILLPATH,*PEMRSTROKEANDFILLPATH,EMRSTROKEPATH,*PEMRSTROKEPATH;
+typedef struct tagEMRFILLRGN {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cbRgnData;
+	DWORD ihBrush;
+	BYTE RgnData[1];
+} EMRFILLRGN,*PEMRFILLRGN;
+typedef struct tagEMRFORMAT   {
+	DWORD dSignature;
+	DWORD nVersion;
+	DWORD cbData;
+	DWORD offData;
+} EMRFORMAT;
+typedef struct tagEMRFRAMERGN {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cbRgnData;
+	DWORD ihBrush;
+	SIZEL szlStroke;
+	BYTE RgnData[1];
+} EMRFRAMERGN,*PEMRFRAMERGN;
+typedef struct tagEMRGDICOMMENT {
+	EMR emr;
+	DWORD cbData;
+	BYTE Data[1];
+} EMRGDICOMMENT,*PEMRGDICOMMENT;
+typedef struct tagEMRINVERTRGN {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cbRgnData;
+	BYTE RgnData[1];
+} EMRINVERTRGN,*PEMRINVERTRGN,EMRPAINTRGN,*PEMRPAINTRGN;
+typedef struct tagEMRLINETO {
+	EMR emr;
+	POINTL ptl;
+} EMRLINETO,*PEMRLINETO,EMRMOVETOEX,*PEMRMOVETOEX;
+typedef struct tagEMRMASKBLT {
+	EMR emr;
+	RECTL rclBounds;
+	LONG xDest;
+	LONG yDest;
+	LONG cxDest;
+	LONG cyDest;
+	DWORD dwRop;
+	LONG xSrc;
+	LONG ySrc;
+	XFORM xformSrc;
+	COLORREF crBkColorSrc;
+	DWORD iUsageSrc;
+	DWORD offBmiSrc;
+	DWORD cbBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+	LONG xMask;
+	LONG yMask;
+	DWORD iUsageMask;
+	DWORD offBmiMask;
+	DWORD cbBmiMask;
+	DWORD offBitsMask;
+	DWORD cbBitsMask;
+} EMRMASKBLT,*PEMRMASKBLT;
+typedef struct tagEMRMODIFYWORLDTRANSFORM {
+	EMR emr;
+	XFORM xform;
+	DWORD iMode;
+} EMRMODIFYWORLDTRANSFORM,*PEMRMODIFYWORLDTRANSFORM;
+typedef struct tagEMROFFSETCLIPRGN {
+	EMR emr;
+	POINTL ptlOffset;
+} EMROFFSETCLIPRGN,*PEMROFFSETCLIPRGN;
+typedef struct tagEMRPLGBLT {
+	EMR emr;
+	RECTL rclBounds;
+	POINTL aptlDest[3];
+	LONG xSrc;
+	LONG ySrc;
+	LONG cxSrc;
+	LONG cySrc;
+	XFORM xformSrc;
+	COLORREF crBkColorSrc;
+	DWORD iUsageSrc;
+	DWORD offBmiSrc;
+	DWORD cbBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+	LONG xMask;
+	LONG yMask;
+	DWORD iUsageMask;
+	DWORD offBmiMask;
+	DWORD cbBmiMask;
+	DWORD offBitsMask;
+	DWORD cbBitsMask;
+} EMRPLGBLT,*PEMRPLGBLT;
+typedef struct tagEMRPOLYDRAW {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cptl;
+	POINTL aptl[1];
+	BYTE abTypes[1];
+} EMRPOLYDRAW,*PEMRPOLYDRAW;
+typedef struct tagEMRPOLYDRAW16 {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cpts;
+	POINTS apts[1];
+	BYTE abTypes[1];
+} EMRPOLYDRAW16,*PEMRPOLYDRAW16;
+typedef struct tagEMRPOLYLINE {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cptl;
+	POINTL aptl[1];
+} EMRPOLYLINE,*PEMRPOLYLINE,EMRPOLYBEZIER,*PEMRPOLYBEZIER,EMRPOLYGON,*PEMRPOLYGON,EMRPOLYBEZIERTO,*PEMRPOLYBEZIERTO,EMRPOLYLINETO,*PEMRPOLYLINETO;
+typedef struct tagEMRPOLYLINE16 {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD cpts;
+	POINTL apts[1];
+} EMRPOLYLINE16,*PEMRPOLYLINE16,EMRPOLYBEZIER16,*PEMRPOLYBEZIER16,EMRPOLYGON16,*PEMRPOLYGON16,EMRPOLYBEZIERTO16,*PEMRPOLYBEZIERTO16,EMRPOLYLINETO16,*PEMRPOLYLINETO16;
+typedef struct tagEMRPOLYPOLYLINE {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD nPolys;
+	DWORD cptl;
+	DWORD aPolyCounts[1];
+	POINTL aptl[1];
+} EMRPOLYPOLYLINE,*PEMRPOLYPOLYLINE,EMRPOLYPOLYGON,*PEMRPOLYPOLYGON;
+typedef struct tagEMRPOLYPOLYLINE16 {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD nPolys;
+	DWORD cpts;
+	DWORD aPolyCounts[1];
+	POINTS apts[1];
+} EMRPOLYPOLYLINE16,*PEMRPOLYPOLYLINE16,EMRPOLYPOLYGON16,*PEMRPOLYPOLYGON16;
+typedef struct tagEMRPOLYTEXTOUTA {
+	EMR emr;
+	RECTL rclBounds;
+	DWORD iGraphicsMode;
+	FLOAT exScale;
+	FLOAT eyScale;
+	LONG cStrings;
+	EMRTEXT aemrtext[1];
+} EMRPOLYTEXTOUTA,*PEMRPOLYTEXTOUTA,EMRPOLYTEXTOUTW,*PEMRPOLYTEXTOUTW;
+typedef struct tagEMRRESIZEPALETTE {
+	EMR emr;
+	DWORD ihPal;
+	DWORD cEntries;
+} EMRRESIZEPALETTE,*PEMRRESIZEPALETTE;
+typedef struct tagEMRRESTOREDC {
+	EMR emr;
+	LONG iRelative;
+} EMRRESTOREDC,*PEMRRESTOREDC;
+typedef struct tagEMRROUNDRECT {
+	EMR emr;
+	RECTL rclBox;
+	SIZEL szlCorner;
+} EMRROUNDRECT,*PEMRROUNDRECT;
+typedef struct tagEMRSCALEVIEWPORTEXTEX {
+	EMR emr;
+	LONG xNum;
+	LONG xDenom;
+	LONG yNum;
+	LONG yDenom;
+} EMRSCALEVIEWPORTEXTEX,*PEMRSCALEVIEWPORTEXTEX,EMRSCALEWINDOWEXTEX,*PEMRSCALEWINDOWEXTEX;
+typedef struct tagEMRSELECTCOLORSPACE {
+	EMR emr;
+	DWORD ihCS;
+} EMRSELECTCOLORSPACE,*PEMRSELECTCOLORSPACE,EMRDELETECOLORSPACE,*PEMRDELETECOLORSPACE;
+typedef struct tagEMRSELECTOBJECT {
+	EMR emr;
+	DWORD ihObject;
+} EMRSELECTOBJECT,*PEMRSELECTOBJECT,EMRDELETEOBJECT,*PEMRDELETEOBJECT;
+typedef struct tagEMRSELECTPALETTE {
+	EMR emr;
+	DWORD ihPal;
+} EMRSELECTPALETTE,*PEMRSELECTPALETTE;
+typedef struct tagEMRSETARCDIRECTION {
+	EMR emr;
+	DWORD iArcDirection;
+} EMRSETARCDIRECTION,*PEMRSETARCDIRECTION;
+typedef struct tagEMRSETTEXTCOLOR {
+	EMR emr;
+	COLORREF crColor;
+} EMRSETBKCOLOR,*PEMRSETBKCOLOR,EMRSETTEXTCOLOR,*PEMRSETTEXTCOLOR;
+typedef struct tagEMRSETCOLORADJUSTMENT {
+	EMR emr;
+	COLORADJUSTMENT ColorAdjustment;
+} EMRSETCOLORADJUSTMENT,*PEMRSETCOLORADJUSTMENT;
+typedef struct tagEMRSETDIBITSTODEVICE {
+	EMR emr;
+	RECTL rclBounds;
+	LONG xDest;
+	LONG yDest;
+	LONG xSrc;
+	LONG ySrc;
+	LONG cxSrc;
+	LONG cySrc;
+	DWORD offBmiSrc;
+	DWORD cbBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+	DWORD iUsageSrc;
+	DWORD iStartScan;
+	DWORD cScans;
+} EMRSETDIBITSTODEVICE,*PEMRSETDIBITSTODEVICE;
+typedef struct tagEMRSETMAPPERFLAGS {
+	EMR emr;
+	DWORD dwFlags;
+} EMRSETMAPPERFLAGS,*PEMRSETMAPPERFLAGS;
+typedef struct tagEMRSETMITERLIMIT {
+	EMR emr;
+	FLOAT eMiterLimit;
+} EMRSETMITERLIMIT,*PEMRSETMITERLIMIT;
+typedef struct tagEMRSETPALETTEENTRIES {
+	EMR emr;
+	DWORD ihPal;
+	DWORD iStart;
+	DWORD cEntries;
+	PALETTEENTRY aPalEntries[1];
+} EMRSETPALETTEENTRIES,*PEMRSETPALETTEENTRIES;
+typedef struct tagEMRSETPIXELV {
+	EMR emr;
+	POINTL ptlPixel;
+	COLORREF crColor;
+} EMRSETPIXELV,*PEMRSETPIXELV;
+typedef struct tagEMRSETVIEWPORTEXTEX {
+	EMR emr;
+	SIZEL szlExtent;
+} EMRSETVIEWPORTEXTEX,*PEMRSETVIEWPORTEXTEX,EMRSETWINDOWEXTEX,*PEMRSETWINDOWEXTEX;
+typedef struct tagEMRSETVIEWPORTORGEX {
+	EMR emr;
+	POINTL ptlOrigin;
+} EMRSETVIEWPORTORGEX,*PEMRSETVIEWPORTORGEX,EMRSETWINDOWORGEX,*PEMRSETWINDOWORGEX,EMRSETBRUSHORGEX,*PEMRSETBRUSHORGEX;
+typedef struct tagEMRSETWORLDTRANSFORM {
+	EMR emr;
+	XFORM xform;
+} EMRSETWORLDTRANSFORM,*PEMRSETWORLDTRANSFORM;
+typedef struct tagEMRSTRETCHBLT {
+	EMR emr;
+	RECTL rclBounds;
+	LONG xDest;
+	LONG yDest;
+	LONG cxDest;
+	LONG cyDest;
+	DWORD dwRop;
+	LONG xSrc;
+	LONG ySrc;
+	XFORM xformSrc;
+	COLORREF crBkColorSrc;
+	DWORD iUsageSrc;
+	DWORD offBmiSrc;
+	DWORD cbBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+	LONG cxSrc;
+	LONG cySrc;
+} EMRSTRETCHBLT,*PEMRSTRETCHBLT;
+typedef struct tagEMRSTRETCHDIBITS {
+	EMR emr;
+	RECTL rclBounds;
+	LONG xDest;
+	LONG yDest;
+	LONG xSrc;
+	LONG ySrc;
+	LONG cxSrc;
+	LONG cySrc;
+	DWORD offBmiSrc;
+	DWORD cbBmiSrc;
+	DWORD offBitsSrc;
+	DWORD cbBitsSrc;
+	DWORD iUsageSrc;
+	DWORD dwRop;
+	LONG cxDest;
+	LONG cyDest;
+} EMRSTRETCHDIBITS,*PEMRSTRETCHDIBITS;
+typedef struct tagABORTPATH {
+	EMR emr;
+} EMRABORTPATH,*PEMRABORTPATH,EMRBEGINPATH,*PEMRBEGINPATH,EMRENDPATH,*PEMRENDPATH,EMRCLOSEFIGURE,*PEMRCLOSEFIGURE,EMRFLATTENPATH,*PEMRFLATTENPATH,EMRWIDENPATH,*PEMRWIDENPATH,EMRSETMETARGN,*PEMRSETMETARGN,EMRSAVEDC,*PEMRSAVEDC,EMRREALIZEPALETTE,*PEMRREALIZEPALETTE;
+typedef struct tagEMRSELECTCLIPPATH {
+	EMR emr;
+	DWORD iMode;
+} EMRSELECTCLIPPATH,*PEMRSELECTCLIPPATH,EMRSETBKMODE,*PEMRSETBKMODE,EMRSETMAPMODE,*PEMRSETMAPMODE,EMRSETPOLYFILLMODE,*PEMRSETPOLYFILLMODE,EMRSETROP2,*PEMRSETROP2,EMRSETSTRETCHBLTMODE,*PEMRSETSTRETCHBLTMODE,EMRSETTEXTALIGN,*PEMRSETTEXTALIGN,EMRENABLEICM,*PEMRENABLEICM;
+#pragma pack(push,2)
+typedef struct tagMETAHEADER {
+	WORD mtType;
+	WORD mtHeaderSize;
+	WORD mtVersion;
+	DWORD mtSize;
+	WORD mtNoObjects;
+	DWORD mtMaxRecord;
+	WORD mtNoParameters;
+} METAHEADER,*PMETAHEADER,*LPMETAHEADER;
+#pragma pack(pop)
+typedef struct tagENHMETAHEADER {
+	DWORD iType;
+	DWORD nSize;
+	RECTL rclBounds;
+	RECTL rclFrame;
+	DWORD dSignature;
+	DWORD nVersion;
+	DWORD nBytes;
+	DWORD nRecords;
+	WORD nHandles;
+	WORD sReserved;
+	DWORD nDescription;
+	DWORD offDescription;
+	DWORD nPalEntries;
+	SIZEL szlDevice;
+	SIZEL szlMillimeters;
+} ENHMETAHEADER,*LPENHMETAHEADER;
+typedef struct tagMETARECORD {
+	DWORD rdSize;
+	WORD rdFunction;
+	WORD rdParm[1];
+} METARECORD,*PMETARECORD,*LPMETARECORD;
+typedef struct tagENHMETARECORD {
+	DWORD iType;
+	DWORD nSize;
+	DWORD dParm[1];
+} ENHMETARECORD,*LPENHMETARECORD;
+typedef struct tagHANDLETABLE {
+	HGDIOBJ objectHandle[1];
+} HANDLETABLE,*LPHANDLETABLE;
+typedef struct tagTEXTMETRICA {
+	LONG tmHeight;
+	LONG tmAscent;
+	LONG tmDescent;
+	LONG tmInternalLeading;
+	LONG tmExternalLeading;
+	LONG tmAveCharWidth;
+	LONG tmMaxCharWidth;
+	LONG tmWeight;
+	LONG tmOverhang;
+	LONG tmDigitizedAspectX;
+	LONG tmDigitizedAspectY;
+	BYTE tmFirstChar;
+	BYTE tmLastChar;
+	BYTE tmDefaultChar;
+	BYTE tmBreakChar;
+	BYTE tmItalic;
+	BYTE tmUnderlined;
+	BYTE tmStruckOut;
+	BYTE tmPitchAndFamily;
+	BYTE tmCharSet;
+} TEXTMETRICA,*PTEXTMETRICA,*LPTEXTMETRICA;
+typedef struct tagTEXTMETRICW {
+	LONG tmHeight;
+	LONG tmAscent;
+	LONG tmDescent;
+	LONG tmInternalLeading;
+	LONG tmExternalLeading;
+	LONG tmAveCharWidth;
+	LONG tmMaxCharWidth;
+	LONG tmWeight;
+	LONG tmOverhang;
+	LONG tmDigitizedAspectX;
+	LONG tmDigitizedAspectY;
+	WCHAR tmFirstChar;
+	WCHAR tmLastChar;
+	WCHAR tmDefaultChar;
+	WCHAR tmBreakChar;
+	BYTE tmItalic;
+	BYTE tmUnderlined;
+	BYTE tmStruckOut;
+	BYTE tmPitchAndFamily;
+	BYTE tmCharSet;
+} TEXTMETRICW,*PTEXTMETRICW,*LPTEXTMETRICW;
+typedef struct _RGNDATAHEADER {
+	DWORD dwSize;
+	DWORD iType;
+	DWORD nCount;
+	DWORD nRgnSize;
+	RECT rcBound;
+} RGNDATAHEADER;
+typedef struct _RGNDATA {
+	RGNDATAHEADER rdh;
+	char Buffer[1];
+} RGNDATA,*LPRGNDATA;
+/* for GetRandomRgn */
+#define SYSRGN  4
+typedef struct tagGCP_RESULTSA {
+	DWORD lStructSize;
+	LPSTR lpOutString;
+	UINT *lpOrder;
+	INT *lpDx;
+	INT *lpCaretPos;
+	LPSTR lpClass;
+	UINT *lpGlyphs;
+	UINT nGlyphs;
+	UINT nMaxFit;
+} GCP_RESULTSA,*LPGCP_RESULTSA;
+typedef struct tagGCP_RESULTSW {
+	DWORD lStructSize;
+	LPWSTR lpOutString;
+	UINT *lpOrder;
+	INT *lpDx;
+	INT *lpCaretPos;
+	LPWSTR lpClass;
+	UINT *lpGlyphs;
+	UINT nGlyphs;
+	UINT nMaxFit;
+} GCP_RESULTSW,*LPGCP_RESULTSW;
+typedef struct _GLYPHMETRICS {
+	UINT gmBlackBoxX;
+	UINT gmBlackBoxY;
+	POINT gmptGlyphOrigin;
+	short gmCellIncX;
+	short gmCellIncY;
+} GLYPHMETRICS,*LPGLYPHMETRICS;
+typedef struct tagKERNINGPAIR {
+	WORD wFirst;
+	WORD wSecond;
+	int iKernAmount;
+} KERNINGPAIR,*LPKERNINGPAIR;
+typedef struct _FIXED {
+	WORD fract;
+	short value;
+} FIXED;
+typedef struct _MAT2 {
+	FIXED eM11;
+	FIXED eM12;
+	FIXED eM21;
+	FIXED eM22;
+} MAT2,*LPMAT2;
+typedef struct _OUTLINETEXTMETRICA {
+	UINT otmSize;
+	TEXTMETRICA otmTextMetrics;
+	BYTE otmFiller;
+	PANOSE otmPanoseNumber;
+	UINT otmfsSelection;
+	UINT otmfsType;
+	int otmsCharSlopeRise;
+	int otmsCharSlopeRun;
+	int otmItalicAngle;
+	UINT otmEMSquare;
+	int otmAscent;
+	int otmDescent;
+	UINT otmLineGap;
+	UINT otmsCapEmHeight;
+	UINT otmsXHeight;
+	RECT otmrcFontBox;
+	int otmMacAscent;
+	int otmMacDescent;
+	UINT otmMacLineGap;
+	UINT otmusMinimumPPEM;
+	POINT otmptSubscriptSize;
+	POINT otmptSubscriptOffset;
+	POINT otmptSuperscriptSize;
+	POINT otmptSuperscriptOffset;
+	UINT otmsStrikeoutSize;
+	int otmsStrikeoutPosition;
+	int otmsUnderscoreSize;
+	int otmsUnderscorePosition;
+	PSTR otmpFamilyName;
+	PSTR otmpFaceName;
+	PSTR otmpStyleName;
+	PSTR otmpFullName;
+} OUTLINETEXTMETRICA,*POUTLINETEXTMETRICA,*LPOUTLINETEXTMETRICA;
+typedef struct _OUTLINETEXTMETRICW {
+	UINT otmSize;
+	TEXTMETRICW otmTextMetrics;
+	BYTE otmFiller;
+	PANOSE otmPanoseNumber;
+	UINT otmfsSelection;
+	UINT otmfsType;
+	int otmsCharSlopeRise;
+	int otmsCharSlopeRun;
+	int otmItalicAngle;
+	UINT otmEMSquare;
+	int otmAscent;
+	int otmDescent;
+	UINT otmLineGap;
+	UINT otmsCapEmHeight;
+	UINT otmsXHeight;
+	RECT otmrcFontBox;
+	int otmMacAscent;
+	int otmMacDescent;
+	UINT otmMacLineGap;
+	UINT otmusMinimumPPEM;
+	POINT otmptSubscriptSize;
+	POINT otmptSubscriptOffset;
+	POINT otmptSuperscriptSize;
+	POINT otmptSuperscriptOffset;
+	UINT otmsStrikeoutSize;
+	int otmsStrikeoutPosition;
+	int otmsUnderscoreSize;
+	int otmsUnderscorePosition;
+	PSTR otmpFamilyName;
+	PSTR otmpFaceName;
+	PSTR otmpStyleName;
+	PSTR otmpFullName;
+} OUTLINETEXTMETRICW,*POUTLINETEXTMETRICW,*LPOUTLINETEXTMETRICW;
+typedef struct _RASTERIZER_STATUS {
+	short nSize;
+	short wFlags;
+	short nLanguageID;
+} RASTERIZER_STATUS,*LPRASTERIZER_STATUS;
+typedef struct _POLYTEXTA {
+	int x;
+	int y;
+	UINT n;
+	LPCSTR lpstr;
+	UINT uiFlags;
+	RECT rcl;
+	int *pdx;
+} POLYTEXTA;
+typedef struct _POLYTEXTW {
+	int x;
+	int y;
+	UINT n;
+	LPCWSTR lpstr;
+	UINT uiFlags;
+	RECT rcl;
+	int *pdx;
+} POLYTEXTW;
+typedef struct tagPIXELFORMATDESCRIPTOR {
+	WORD nSize;
+	WORD nVersion;
+	DWORD dwFlags;
+	BYTE iPixelType;
+	BYTE cColorBits;
+	BYTE cRedBits;
+	BYTE cRedShift;
+	BYTE cGreenBits;
+	BYTE cGreenShift;
+	BYTE cBlueBits;
+	BYTE cBlueShift;
+	BYTE cAlphaBits;
+	BYTE cAlphaShift;
+	BYTE cAccumBits;
+	BYTE cAccumRedBits;
+	BYTE cAccumGreenBits;
+	BYTE cAccumBlueBits;
+	BYTE cAccumAlphaBits;
+	BYTE cDepthBits;
+	BYTE cStencilBits;
+	BYTE cAuxBuffers;
+	BYTE iLayerType;
+	BYTE bReserved;
+	DWORD dwLayerMask;
+	DWORD dwVisibleMask;
+	DWORD dwDamageMask;
+} PIXELFORMATDESCRIPTOR,*PPIXELFORMATDESCRIPTOR,*LPPIXELFORMATDESCRIPTOR;
+typedef struct tagMETAFILEPICT {
+	LONG mm;
+	LONG xExt;
+	LONG yExt;
+	HMETAFILE hMF;
+} METAFILEPICT,*LPMETAFILEPICT;
+typedef struct tagLOCALESIGNATURE {
+	DWORD lsUsb[4];
+	DWORD lsCsbDefault[2];
+	DWORD lsCsbSupported[2];
+} LOCALESIGNATURE,*PLOCALESIGNATURE,*LPLOCALESIGNATURE;
+typedef LONG LCSTYPE;
+#pragma pack(push,4)
+typedef struct tagNEWTEXTMETRICA {
+	LONG tmHeight;
+	LONG tmAscent;
+	LONG tmDescent;
+	LONG tmInternalLeading;
+	LONG tmExternalLeading;
+	LONG tmAveCharWidth;
+	LONG tmMaxCharWidth;
+	LONG tmWeight;
+	LONG tmOverhang;
+	LONG tmDigitizedAspectX;
+	LONG tmDigitizedAspectY;
+	BYTE tmFirstChar;
+	BYTE tmLastChar;
+	BYTE tmDefaultChar;
+	BYTE tmBreakChar;
+	BYTE tmItalic;
+	BYTE tmUnderlined;
+	BYTE tmStruckOut;
+	BYTE tmPitchAndFamily;
+	BYTE tmCharSet;
+	DWORD ntmFlags;
+	UINT ntmSizeEM;
+	UINT ntmCellHeight;
+	UINT ntmAvgWidth;
+} NEWTEXTMETRICA,*PNEWTEXTMETRICA,*LPNEWTEXTMETRICA;
+typedef struct tagNEWTEXTMETRICW {
+	LONG tmHeight;
+	LONG tmAscent;
+	LONG tmDescent;
+	LONG tmInternalLeading;
+	LONG tmExternalLeading;
+	LONG tmAveCharWidth;
+	LONG tmMaxCharWidth;
+	LONG tmWeight;
+	LONG tmOverhang;
+	LONG tmDigitizedAspectX;
+	LONG tmDigitizedAspectY;
+	WCHAR tmFirstChar;
+	WCHAR tmLastChar;
+	WCHAR tmDefaultChar;
+	WCHAR tmBreakChar;
+	BYTE tmItalic;
+	BYTE tmUnderlined;
+	BYTE tmStruckOut;
+	BYTE tmPitchAndFamily;
+	BYTE tmCharSet;
+	DWORD ntmFlags;
+	UINT ntmSizeEM;
+	UINT ntmCellHeight;
+	UINT ntmAvgWidth;
+} NEWTEXTMETRICW,*PNEWTEXTMETRICW,*LPNEWTEXTMETRICW;
+#pragma pack(pop)
+typedef struct tagNEWTEXTMETRICEXA {
+	NEWTEXTMETRICA ntmTm;
+	FONTSIGNATURE ntmFontSig;
+} NEWTEXTMETRICEXA;
+typedef struct tagNEWTEXTMETRICEXW {
+	NEWTEXTMETRICW ntmTm;
+	FONTSIGNATURE ntmFontSig;
+} NEWTEXTMETRICEXW;
+typedef struct tagPELARRAY {
+	LONG paXCount;
+	LONG paYCount;
+	LONG paXExt;
+	LONG paYExt;
+	BYTE paRGBs;
+} PELARRAY,*PPELARRAY,*LPPELARRAY;
+typedef struct tagENUMLOGFONTA {
+	LOGFONTA elfLogFont;
+	BYTE elfFullName[LF_FULLFACESIZE];
+	BYTE elfStyle[LF_FACESIZE];
+} ENUMLOGFONTA,*LPENUMLOGFONTA;
+typedef struct tagENUMLOGFONTW {
+	LOGFONTW elfLogFont;
+	WCHAR elfFullName[LF_FULLFACESIZE];
+	WCHAR elfStyle[LF_FACESIZE];
+} ENUMLOGFONTW,*LPENUMLOGFONTW;
+typedef struct tagENUMLOGFONTEXA {
+	LOGFONTA elfLogFont;
+	BYTE elfFullName[LF_FULLFACESIZE];
+	BYTE elfStyle[LF_FACESIZE];
+	BYTE elfScript[LF_FACESIZE];
+} ENUMLOGFONTEXA,*LPENUMLOGFONTEXA;
+typedef struct tagENUMLOGFONTEXW {
+	LOGFONTW elfLogFont;
+	WCHAR elfFullName[LF_FULLFACESIZE];
+	BYTE elfStyle[LF_FACESIZE];
+	BYTE elfScript[LF_FACESIZE];
+} ENUMLOGFONTEXW,*LPENUMLOGFONTEXW;
+typedef struct tagPOINTFX {
+	FIXED x;
+	FIXED y;
+} POINTFX,*LPPOINTFX;
+typedef struct tagTTPOLYCURVE {
+	WORD wType;
+	WORD cpfx;
+	POINTFX apfx[1];
+} TTPOLYCURVE,*LPTTPOLYCURVE;
+typedef struct tagTTPOLYGONHEADER {
+	DWORD cb;
+	DWORD dwType;
+	POINTFX pfxStart;
+} TTPOLYGONHEADER,*LPTTPOLYGONHEADER;
+typedef struct _POINTFLOAT {
+	FLOAT x;
+	FLOAT y;
+} POINTFLOAT,*PPOINTFLOAT;
+typedef struct _GLYPHMETRICSFLOAT {
+	FLOAT gmfBlackBoxX;
+	FLOAT gmfBlackBoxY;
+	POINTFLOAT gmfptGlyphOrigin;
+	FLOAT gmfCellIncX;
+	FLOAT gmfCellIncY;
+} GLYPHMETRICSFLOAT,*PGLYPHMETRICSFLOAT,*LPGLYPHMETRICSFLOAT;
+typedef struct tagLAYERPLANEDESCRIPTOR {
+	WORD nSize;
+	WORD nVersion;
+	DWORD dwFlags;
+	BYTE iPixelType;
+	BYTE cColorBits;
+	BYTE cRedBits;
+	BYTE cRedShift;
+	BYTE cGreenBits;
+	BYTE cGreenShift;
+	BYTE cBlueBits;
+	BYTE cBlueShift;
+	BYTE cAlphaBits;
+	BYTE cAlphaShift;
+	BYTE cAccumBits;
+	BYTE cAccumRedBits;
+	BYTE cAccumGreenBits;
+	BYTE cAccumBlueBits;
+	BYTE cAccumAlphaBits;
+	BYTE cDepthBits;
+	BYTE cStencilBits;
+	BYTE cAuxBuffers;
+	BYTE iLayerPlane;
+	BYTE bReserved;
+	COLORREF crTransparent;
+} LAYERPLANEDESCRIPTOR,*PLAYERPLANEDESCRIPTOR,*LPLAYERPLANEDESCRIPTOR;
+typedef struct _BLENDFUNCTION {
+    BYTE BlendOp;
+    BYTE BlendFlags;
+    BYTE SourceConstantAlpha;
+    BYTE AlphaFormat; 
+} BLENDFUNCTION,*PBLENDFUNCTION,*LPBLENDFUNCTION; 
+typedef BOOL (CALLBACK *ABORTPROC)(HDC,int);
+typedef int (CALLBACK *MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM);
+typedef int (CALLBACK *ENHMFENUMPROC)(HDC,HANDLETABLE*,ENHMETARECORD*,int,LPARAM);
+typedef int (CALLBACK *OLDFONTENUMPROCA)(const LOGFONTA*,const TEXTMETRICA*,DWORD,LPARAM);
+typedef int (CALLBACK *OLDFONTENUMPROCW)(const LOGFONTW*,const TEXTMETRICW*,DWORD,LPARAM);
+typedef OLDFONTENUMPROCA FONTENUMPROCA;
+typedef OLDFONTENUMPROCW FONTENUMPROCW;
+typedef int (CALLBACK *ICMENUMPROCA)(LPSTR,LPARAM);
+typedef int (CALLBACK *ICMENUMPROCW)(LPWSTR,LPARAM);
+typedef void (CALLBACK *GOBJENUMPROC)(LPVOID,LPARAM);
+typedef void (CALLBACK *LINEDDAPROC)(int,int,LPARAM);
+typedef UINT (CALLBACK *LPFNDEVMODE)(HWND,HMODULE,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,UINT);
+typedef DWORD (CALLBACK *LPFNDEVCAPS)(LPSTR,LPSTR,UINT,LPSTR,LPDEVMODEA);
+
+
+#define RGB(r,g,b)	((DWORD)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16)))
+#define MAKEPOINTS(l) (*((POINTS*)&(l)))
+#define MAKEROP4(f,b)	(DWORD)((((b)<<8)&0xFF000000)|(f))
+#define PALETTEINDEX(i)	((0x01000000|(COLORREF)(WORD)(i)))
+#define PALETTERGB(r,g,b)	(0x02000000|RGB(r,g,b))
+int WINAPI AbortDoc(HDC);
+BOOL WINAPI AbortPath(HDC);
+int WINAPI AddFontResourceA(LPCSTR);
+int WINAPI AddFontResourceW(LPCWSTR);
+BOOL WINAPI AngleArc(HDC,int,int,DWORD,FLOAT,FLOAT);
+BOOL WINAPI AnimatePalette(HPALETTE,UINT,UINT,const PALETTEENTRY*);
+BOOL WINAPI Arc(HDC,int,int,int,int,int,int,int,int);
+BOOL WINAPI ArcTo(HDC,int,int,int,int,int,int,int,int);
+BOOL WINAPI BeginPath(HDC);
+BOOL WINAPI BitBlt(HDC,int,int,int,int,HDC,int,int,DWORD);
+BOOL WINAPI CancelDC(HDC);
+BOOL WINAPI CheckColorsInGamut(HDC,PVOID,PVOID,DWORD);
+BOOL WINAPI Chord(HDC,int,int,int,int,int,int,int,int);
+int WINAPI ChoosePixelFormat(HDC,CONST PIXELFORMATDESCRIPTOR*);
+HENHMETAFILE WINAPI CloseEnhMetaFile(HDC);
+BOOL WINAPI CloseFigure(HDC);
+HMETAFILE WINAPI CloseMetaFile(HDC);
+BOOL WINAPI ColorMatchToTarget(HDC,HDC,DWORD);
+int WINAPI CombineRgn(HRGN,HRGN,HRGN,int);
+BOOL WINAPI CombineTransform(LPXFORM,const XFORM*,const XFORM*);
+HENHMETAFILE WINAPI CopyEnhMetaFileA(HENHMETAFILE,LPCSTR);
+HENHMETAFILE WINAPI CopyEnhMetaFileW(HENHMETAFILE,LPCWSTR);
+HMETAFILE WINAPI CopyMetaFileA(HMETAFILE,LPCSTR);
+HMETAFILE WINAPI CopyMetaFileW(HMETAFILE,LPCWSTR);
+HBITMAP WINAPI CreateBitmap(int,int,UINT,UINT,PCVOID);
+HBITMAP WINAPI CreateBitmapIndirect(const BITMAP*);
+HBRUSH WINAPI CreateBrushIndirect(const LOGBRUSH*);
+HCOLORSPACE WINAPI CreateColorSpaceA(LPLOGCOLORSPACEA);
+HCOLORSPACE WINAPI CreateColorSpaceW(LPLOGCOLORSPACEW);
+HBITMAP WINAPI CreateCompatibleBitmap(HDC,int,int);
+HDC WINAPI CreateCompatibleDC(HDC);
+HDC WINAPI CreateDCA(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);
+HDC WINAPI CreateDCW(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
+HBITMAP WINAPI CreateDIBitmap(HDC,const BITMAPINFOHEADER*,DWORD,PCVOID,const BITMAPINFO*,UINT);
+HBRUSH WINAPI CreateDIBPatternBrush(HGLOBAL,UINT);
+HBRUSH WINAPI CreateDIBPatternBrushPt(PCVOID,UINT);
+HBITMAP WINAPI CreateDIBSection(HDC,const BITMAPINFO*,UINT,void**,HANDLE,DWORD);
+HBITMAP WINAPI CreateDiscardableBitmap(HDC,int,int);
+HRGN WINAPI CreateEllipticRgn(int,int,int,int);
+HRGN WINAPI CreateEllipticRgnIndirect(LPCRECT);
+HDC WINAPI CreateEnhMetaFileA(HDC,LPCSTR,LPCRECT,LPCSTR);
+HDC WINAPI CreateEnhMetaFileW(HDC,LPCWSTR,LPCRECT,LPCWSTR);
+HFONT WINAPI CreateFontA(int,int,int,int,int,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPCSTR);
+HFONT WINAPI CreateFontW(int,int,int,int,int,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,LPCWSTR);
+HFONT WINAPI CreateFontIndirectA(const LOGFONTA*);
+HFONT WINAPI CreateFontIndirectW(const LOGFONTW*);
+HPALETTE WINAPI CreateHalftonePalette(HDC);
+HBRUSH WINAPI CreateHatchBrush(int,COLORREF);
+HDC WINAPI CreateICA(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);
+HDC WINAPI CreateICW(LPCWSTR,LPCWSTR,LPCWSTR,const DEVMODEW*);
+HDC WINAPI CreateMetaFileA(LPCSTR);
+HDC WINAPI CreateMetaFileW(LPCWSTR);
+HPALETTE WINAPI CreatePalette(const LOGPALETTE*);
+HBRUSH WINAPI CreatePatternBrush(HBITMAP);
+HPEN WINAPI CreatePen(int,int,COLORREF);
+HPEN WINAPI CreatePenIndirect(const LOGPEN*);
+HRGN WINAPI CreatePolygonRgn(const POINT*,int,int);
+HRGN WINAPI CreatePolyPolygonRgn(const POINT*,const INT*,int,int);
+HRGN WINAPI CreateRectRgn(int,int,int,int);
+HRGN WINAPI CreateRectRgnIndirect(LPCRECT);
+HRGN WINAPI CreateRoundRectRgn(int,int,int,int,int,int);
+BOOL WINAPI CreateScalableFontResourceA(DWORD,LPCSTR,LPCSTR,LPCSTR);
+BOOL WINAPI CreateScalableFontResourceW(DWORD,LPCWSTR,LPCWSTR,LPCWSTR);
+HBRUSH WINAPI CreateSolidBrush(COLORREF);
+BOOL WINAPI DeleteColorSpace(HCOLORSPACE);
+BOOL WINAPI DeleteDC(HDC);
+BOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE);
+BOOL WINAPI DeleteMetaFile(HMETAFILE);
+BOOL WINAPI DeleteObject(HGDIOBJ);
+int WINAPI DescribePixelFormat(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR);
+DWORD WINAPI DeviceCapabilitiesA(LPCSTR,LPCSTR,WORD,LPSTR,const DEVMODEA*);
+DWORD WINAPI DeviceCapabilitiesW(LPCWSTR,LPCWSTR,WORD,LPWSTR,const DEVMODEW*);
+BOOL WINAPI DPtoLP(HDC,LPPOINT,int);
+int WINAPI DrawEscape(HDC,int,int,LPCSTR);
+BOOL WINAPI Ellipse(HDC,int,int,int,int);
+int WINAPI EndDoc(HDC);
+int WINAPI EndPage(HDC);
+BOOL WINAPI EndPath(HDC);
+BOOL WINAPI EnumEnhMetaFile(HDC,HENHMETAFILE,ENHMFENUMPROC,PVOID,LPCRECT);
+int WINAPI EnumFontFamiliesA(HDC,LPCSTR,FONTENUMPROCA,LPARAM);
+int WINAPI EnumFontFamiliesW(HDC,LPCWSTR,FONTENUMPROCW,LPARAM);
+int WINAPI EnumFontFamiliesExA(HDC,PLOGFONTA,FONTENUMPROCA,LPARAM,DWORD);
+int WINAPI EnumFontFamiliesExW(HDC,PLOGFONTW,FONTENUMPROCW,LPARAM,DWORD);
+int WINAPI EnumFontsA(HDC,LPCSTR,FONTENUMPROCA,LPARAM);
+int WINAPI EnumFontsW(HDC,LPCWSTR,FONTENUMPROCA,LPARAM);
+int WINAPI EnumICMProfilesA(HDC,ICMENUMPROCA,LPARAM);
+int WINAPI EnumICMProfilesW(HDC,ICMENUMPROCW,LPARAM);
+BOOL WINAPI EnumMetaFile(HDC,HMETAFILE,MFENUMPROC,LPARAM);
+int WINAPI EnumObjects(HDC,int,GOBJENUMPROC,LPARAM);
+BOOL WINAPI EqualRgn(HRGN,HRGN);
+int WINAPI Escape(HDC,int,int,LPCSTR,PVOID);
+int WINAPI ExcludeClipRect(HDC,int,int,int,int);
+int WINAPI ExcludeUpdateRgn(HDC,HWND);
+HPEN WINAPI ExtCreatePen(DWORD,DWORD,const LOGBRUSH*,DWORD,const DWORD*);
+HRGN WINAPI ExtCreateRegion(const XFORM*,DWORD,const RGNDATA*);
+int WINAPI ExtEscape(HDC,int,int,LPCSTR,int,LPSTR);
+BOOL WINAPI ExtFloodFill(HDC,int,int,COLORREF,UINT);
+int WINAPI ExtSelectClipRgn(HDC,HRGN,int);
+BOOL WINAPI ExtTextOutA(HDC,int,int,UINT,LPCRECT,LPCSTR,UINT,const INT*);
+BOOL WINAPI ExtTextOutW(HDC,int,int,UINT,LPCRECT,LPCWSTR,UINT,const INT*);
+BOOL WINAPI FillPath(HDC);
+int WINAPI FillRect(HDC,LPCRECT,HBRUSH);
+int WINAPI FillRgn(HDC,HRGN,HBRUSH);
+BOOL WINAPI FixBrushOrgEx(HDC,int,int,LPPOINT);
+BOOL WINAPI FlattenPath(HDC);
+BOOL WINAPI FloodFill(HDC,int,int,COLORREF);
+BOOL WINAPI GdiComment(HDC,UINT,const BYTE*);
+BOOL WINAPI GdiFlush(void);
+DWORD WINAPI GdiGetBatchLimit(void);
+DWORD WINAPI GdiSetBatchLimit(DWORD);
+#define GetCValue(cmyk) ((BYTE)(cmyk))
+#define GetMValue(cmyk) ((BYTE)((cmyk)>> 8))
+#define GetYValue(cmyk) ((BYTE)((cmyk)>>16))
+#define GetKValue(cmyk) ((BYTE)((cmyk)>>24))
+#define CMYK(c,m,y,k) ((COLORREF)((((BYTE)(c)|((WORD)((BYTE)(m))<<8))|(((DWORD)(BYTE)(y))<<16))|(((DWORD)(BYTE)(k))<<24)))
+#define GetRValue(c) ((BYTE)(c))
+#define GetGValue(c) ((BYTE)(((WORD)(c))>>8))
+#define GetBValue(c) ((BYTE)((c)>>16))
+int WINAPI GetArcDirection(HDC);
+BOOL WINAPI GetAspectRatioFilterEx(HDC,LPSIZE);
+LONG WINAPI GetBitmapBits(HBITMAP,LONG,PVOID);
+BOOL WINAPI GetBitmapDimensionEx(HBITMAP,LPSIZE);
+COLORREF WINAPI GetBkColor(HDC);
+int WINAPI GetBkMode(HDC);
+UINT WINAPI GetBoundsRect(HDC,LPRECT,UINT);
+BOOL WINAPI GetBrushOrgEx(HDC,LPPOINT);
+BOOL WINAPI GetCharABCWidthsA(HDC,UINT,UINT,LPABC);
+BOOL WINAPI GetCharABCWidthsW(HDC,UINT,UINT,LPABC);
+BOOL WINAPI GetCharABCWidthsFloatA(HDC,UINT,UINT,LPABCFLOAT);
+BOOL WINAPI GetCharABCWidthsFloatW(HDC,UINT,UINT,LPABCFLOAT);
+DWORD WINAPI GetCharacterPlacementA(HDC,LPCSTR,int,int,LPGCP_RESULTSA,DWORD);
+DWORD WINAPI GetCharacterPlacementW(HDC,LPCWSTR,int,int,LPGCP_RESULTSW,DWORD);
+BOOL WINAPI GetCharWidth32A(HDC,UINT,UINT,LPINT);
+BOOL WINAPI GetCharWidth32W(HDC,UINT,UINT,LPINT);
+BOOL WINAPI GetCharWidthA(HDC,UINT,UINT,LPINT);
+BOOL WINAPI GetCharWidthW(HDC,UINT,UINT,LPINT);
+BOOL WINAPI GetCharWidthFloatA(HDC,UINT,UINT,PFLOAT);
+BOOL WINAPI GetCharWidthFloatW(HDC,UINT,UINT,PFLOAT);
+int WINAPI GetClipBox(HDC,LPRECT);
+int WINAPI GetClipRgn(HDC,HRGN);
+BOOL WINAPI GetColorAdjustment(HDC,LPCOLORADJUSTMENT);
+HANDLE WINAPI GetColorSpace(HDC);
+HGDIOBJ WINAPI GetCurrentObject(HDC,UINT);
+BOOL WINAPI GetCurrentPositionEx(HDC,LPPOINT);
+HCURSOR WINAPI GetCursor(void);
+BOOL WINAPI GetDCOrgEx(HDC,LPPOINT);
+int WINAPI GetDeviceCaps(HDC,int);
+BOOL WINAPI GetDeviceGammaRamp(HDC,PVOID);
+UINT WINAPI GetDIBColorTable(HDC,UINT,UINT,RGBQUAD*);
+int WINAPI GetDIBits(HDC,HBITMAP,UINT,UINT,PVOID,LPBITMAPINFO,UINT);
+HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR);
+HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR);
+UINT WINAPI GetEnhMetaFileDescriptionA(HENHMETAFILE,UINT,LPSTR);
+UINT WINAPI GetEnhMetaFileDescriptionW(HENHMETAFILE,UINT,LPWSTR);
+UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE,UINT,LPENHMETAHEADER);
+UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE,UINT,LPPALETTEENTRY);
+UINT WINAPI GetEnhMetaFilePixelFormat(HENHMETAFILE,DWORD,PIXELFORMATDESCRIPTOR*);
+DWORD WINAPI GetFontData(HDC,DWORD,DWORD,PVOID,DWORD);
+DWORD WINAPI GetFontLanguageInfo(HDC);
+DWORD WINAPI GetGlyphOutlineA(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*);
+DWORD WINAPI GetGlyphOutlineW(HDC,UINT,UINT,LPGLYPHMETRICS,DWORD,PVOID,const MAT2*);
+int WINAPI GetGraphicsMode(HDC);
+BOOL WINAPI GetICMProfileA(HDC,DWORD,LPSTR);
+BOOL WINAPI GetICMProfileW(HDC,DWORD,LPWSTR);
+DWORD WINAPI GetKerningPairsA(HDC,DWORD,LPKERNINGPAIR);
+DWORD WINAPI GetKerningPairsW(HDC,DWORD,LPKERNINGPAIR);
+BOOL WINAPI GetLogColorSpaceA(HCOLORSPACE,LPLOGCOLORSPACEA,DWORD);
+BOOL WINAPI GetLogColorSpaceW(HCOLORSPACE,LPLOGCOLORSPACEW,DWORD);
+int WINAPI GetMapMode(HDC);
+HMETAFILE WINAPI GetMetaFileA(LPCSTR);
+HMETAFILE WINAPI GetMetaFileW(LPCWSTR);
+UINT WINAPI GetMetaFileBitsEx(HMETAFILE,UINT,PVOID);
+int WINAPI GetMetaRgn(HDC,HRGN);
+BOOL WINAPI GetMiterLimit(HDC,PFLOAT);
+COLORREF WINAPI GetNearestColor(HDC,COLORREF);
+UINT WINAPI GetNearestPaletteIndex(HPALETTE,COLORREF);
+int WINAPI GetObjectA(HGDIOBJ,int,PVOID);
+int WINAPI GetObjectW(HGDIOBJ,int,PVOID);
+DWORD WINAPI GetObjectType(HGDIOBJ);
+UINT WINAPI GetOutlineTextMetricsA(HDC,UINT,LPOUTLINETEXTMETRICA);
+UINT WINAPI GetOutlineTextMetricsW(HDC,UINT,LPOUTLINETEXTMETRICW);
+UINT WINAPI GetPaletteEntries(HPALETTE,UINT,UINT,LPPALETTEENTRY);
+int WINAPI GetPath(HDC,LPPOINT,PBYTE,int);
+COLORREF WINAPI GetPixel(HDC,int,int);
+int WINAPI GetPixelFormat(HDC);
+int WINAPI GetPolyFillMode(HDC);
+BOOL WINAPI GetRasterizerCaps(LPRASTERIZER_STATUS,UINT);
+int WINAPI GetRandomRgn (HDC,HRGN,INT);
+DWORD WINAPI GetRegionData(HRGN,DWORD,LPRGNDATA);
+int WINAPI GetRgnBox(HRGN,LPRECT);
+int WINAPI GetROP2(HDC);
+HGDIOBJ WINAPI GetStockObject(int);
+int WINAPI GetStretchBltMode(HDC);
+UINT WINAPI GetSystemPaletteEntries(HDC,UINT,UINT,LPPALETTEENTRY);
+UINT WINAPI GetSystemPaletteUse(HDC);
+UINT WINAPI GetTextAlign(HDC);
+int WINAPI GetTextCharacterExtra(HDC);
+int WINAPI GetTextCharset(HDC);
+int WINAPI GetTextCharsetInfo(HDC,LPFONTSIGNATURE,DWORD);
+COLORREF WINAPI GetTextColor(HDC);
+BOOL WINAPI GetTextExtentExPointA(HDC,LPCSTR,int,int,LPINT,LPINT,LPSIZE);
+BOOL WINAPI GetTextExtentExPointW( HDC,LPCWSTR,int,int,LPINT,LPINT,LPSIZE );
+BOOL WINAPI GetTextExtentPointA(HDC,LPCSTR,int,LPSIZE);
+BOOL WINAPI GetTextExtentPointW(HDC,LPCWSTR,int,LPSIZE);
+BOOL WINAPI GetTextExtentPoint32A(HDC,LPCSTR,int,LPSIZE);
+BOOL WINAPI GetTextExtentPoint32W( HDC,LPCWSTR,int,LPSIZE);
+int WINAPI GetTextFaceA(HDC,int,LPSTR);
+int WINAPI GetTextFaceW(HDC,int,LPWSTR);
+BOOL WINAPI GetTextMetricsA(HDC,LPTEXTMETRICA);
+BOOL WINAPI GetTextMetricsW(HDC,LPTEXTMETRICW);
+BOOL WINAPI GetViewportExtEx(HDC,LPSIZE);
+BOOL WINAPI GetViewportOrgEx(HDC,LPPOINT);
+BOOL WINAPI GetWindowExtEx(HDC,LPSIZE);
+BOOL WINAPI GetWindowOrgEx(HDC,LPPOINT);
+UINT WINAPI GetWinMetaFileBits(HENHMETAFILE,UINT,LPBYTE,INT,HDC);
+BOOL WINAPI GetWorldTransform(HDC,LPXFORM);
+int WINAPI IntersectClipRect(HDC,int,int,int,int);
+BOOL WINAPI InvertRgn(HDC,HRGN);
+BOOL WINAPI LineDDA(int,int,int,int,LINEDDAPROC,LPARAM);
+BOOL WINAPI LineTo(HDC,int,int);
+BOOL WINAPI LPtoDP(HDC,LPPOINT,int);
+BOOL WINAPI MaskBlt(HDC,int,int,int,int,HDC,int,int,HBITMAP,int,int,DWORD);
+BOOL WINAPI ModifyWorldTransform(HDC,const XFORM*,DWORD);
+BOOL WINAPI MoveToEx(HDC,int,int,LPPOINT);
+int WINAPI OffsetClipRgn(HDC,int,int);
+int WINAPI OffsetRgn(HRGN,int,int);
+BOOL WINAPI OffsetViewportOrgEx(HDC,int,int,LPPOINT);
+BOOL WINAPI OffsetWindowOrgEx(HDC,int,int,LPPOINT);
+BOOL WINAPI PaintRgn(HDC,HRGN);
+BOOL WINAPI PatBlt(HDC,int,int,int,int,DWORD);
+HRGN WINAPI PathToRegion(HDC);
+BOOL WINAPI Pie(HDC,int,int,int,int,int,int,int,int);
+BOOL WINAPI PlayEnhMetaFile(HDC,HENHMETAFILE,LPCRECT);
+BOOL WINAPI PlayEnhMetaFileRecord(HDC,LPHANDLETABLE,const ENHMETARECORD*,UINT);
+BOOL WINAPI PlayMetaFile(HDC,HMETAFILE);
+BOOL WINAPI PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,UINT);
+BOOL WINAPI PlgBlt(HDC,const POINT*,HDC,int,int,int,int,HBITMAP,int,int);
+BOOL WINAPI PolyBezier(HDC,const POINT*,DWORD);
+BOOL WINAPI PolyBezierTo(HDC,const POINT*,DWORD);
+BOOL WINAPI PolyDraw(HDC,const POINT*,const BYTE*,int);
+BOOL WINAPI Polygon(HDC,const POINT*,int);
+BOOL WINAPI Polyline(HDC,const POINT*,int);
+BOOL WINAPI PolylineTo(HDC,const POINT*,DWORD);
+BOOL WINAPI PolyPolygon(HDC,const POINT*,const INT*,int);
+BOOL WINAPI PolyPolyline(HDC,const POINT*,const DWORD*,DWORD);
+BOOL WINAPI PolyTextOutA(HDC,const POLYTEXTA*,int);
+BOOL WINAPI PolyTextOutW(HDC,const POLYTEXTW*,int);
+BOOL WINAPI PtInRegion(HRGN,int,int);
+BOOL WINAPI PtVisible(HDC,int,int);
+UINT WINAPI RealizePalette(HDC);
+BOOL WINAPI Rectangle(HDC,int,int,int,int);
+BOOL WINAPI RectInRegion(HRGN,LPCRECT);
+BOOL WINAPI RectVisible(HDC,LPCRECT);
+BOOL WINAPI RemoveFontResourceA(LPCSTR);
+BOOL WINAPI RemoveFontResourceW(LPCWSTR);
+HDC WINAPI ResetDCA(HDC,const DEVMODEA*);
+HDC WINAPI ResetDCW(HDC,const DEVMODEW*);
+BOOL WINAPI ResizePalette(HPALETTE,UINT);
+BOOL WINAPI RestoreDC(HDC,int);
+BOOL WINAPI RoundRect(HDC,int,int,int,int,int,int);
+int WINAPI SaveDC(HDC);
+BOOL WINAPI ScaleViewportExtEx(HDC,int,int,int,int,LPSIZE);
+BOOL WINAPI ScaleWindowExtEx(HDC,int,int,int,int,LPSIZE);
+BOOL WINAPI SelectClipPath(HDC,int);
+int WINAPI SelectClipRgn(HDC,HRGN);
+HGDIOBJ WINAPI SelectObject(HDC,HGDIOBJ);
+HPALETTE WINAPI SelectPalette(HDC,HPALETTE,BOOL);
+int WINAPI SetAbortProc(HDC,ABORTPROC);
+int WINAPI SetArcDirection(HDC,int);
+LONG WINAPI SetBitmapBits(HBITMAP,DWORD,PCVOID);
+BOOL WINAPI SetBitmapDimensionEx(HBITMAP,int,int,LPSIZE);
+COLORREF WINAPI SetBkColor(HDC,COLORREF);
+int WINAPI SetBkMode(HDC,int);
+UINT WINAPI SetBoundsRect(HDC,LPCRECT,UINT);
+BOOL WINAPI SetBrushOrgEx(HDC,int,int,LPPOINT);
+BOOL WINAPI SetColorAdjustment(HDC,const COLORADJUSTMENT*);
+BOOL WINAPI SetColorSpace(HDC,HCOLORSPACE);
+BOOL WINAPI SetDeviceGammaRamp(HDC,PVOID);
+UINT WINAPI SetDIBColorTable(HDC,UINT,UINT,const RGBQUAD*);
+int WINAPI SetDIBits(HDC,HBITMAP,UINT,UINT,PCVOID,const BITMAPINFO*,UINT);
+int WINAPI SetDIBitsToDevice(HDC,int,int,DWORD,DWORD,int,int,UINT,UINT,PCVOID,const BITMAPINFO*,UINT);
+HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT,const BYTE*);
+int WINAPI SetGraphicsMode(HDC,int);
+int WINAPI SetICMMode(HDC,int);
+BOOL WINAPI SetICMProfileA(HDC,LPSTR);
+BOOL WINAPI SetICMProfileW(HDC,LPWSTR);
+int WINAPI SetMapMode(HDC,int);
+DWORD WINAPI SetMapperFlags(HDC,DWORD);
+HMETAFILE WINAPI SetMetaFileBitsEx(UINT,const BYTE *);
+int WINAPI SetMetaRgn(HDC);
+BOOL WINAPI SetMiterLimit(HDC,FLOAT,PFLOAT);
+UINT WINAPI SetPaletteEntries(HPALETTE,UINT,UINT,const PALETTEENTRY*);
+COLORREF WINAPI SetPixel(HDC,int,int,COLORREF);
+BOOL WINAPI SetPixelFormat(HDC,int,const PIXELFORMATDESCRIPTOR*);
+BOOL WINAPI SetPixelV(HDC,int,int,COLORREF);
+int WINAPI SetPolyFillMode(HDC,int);
+BOOL WINAPI SetRectRgn(HRGN,int,int,int,int);
+int WINAPI SetROP2(HDC,int);
+int WINAPI SetStretchBltMode(HDC,int);
+UINT WINAPI SetSystemPaletteUse(HDC,UINT);
+UINT WINAPI SetTextAlign(HDC,UINT);
+int WINAPI SetTextCharacterExtra(HDC,int);
+COLORREF WINAPI SetTextColor(HDC,COLORREF);
+BOOL WINAPI SetTextJustification(HDC,int,int);
+BOOL WINAPI SetViewportExtEx(HDC,int,int,LPSIZE);
+BOOL WINAPI SetViewportOrgEx(HDC,int,int,LPPOINT);
+BOOL WINAPI SetWindowExtEx(HDC,int,int,LPSIZE);
+BOOL WINAPI SetWindowOrgEx(HDC,int,int,LPPOINT);
+HENHMETAFILE WINAPI SetWinMetaFileBits(UINT,const BYTE*,HDC,const METAFILEPICT*);
+BOOL WINAPI SetWorldTransform(HDC,const XFORM *);
+int WINAPI StartDocA(HDC,const DOCINFOA*);
+int WINAPI StartDocW(HDC,const DOCINFOW*);
+int WINAPI StartPage(HDC);
+BOOL WINAPI StretchBlt(HDC,int,int,int,int,HDC,int,int,int,int,DWORD);
+int WINAPI StretchDIBits(HDC,int,int,int,int,int,int,int,int,const VOID *,const BITMAPINFO *,UINT,DWORD);
+BOOL WINAPI StrokeAndFillPath(HDC);
+BOOL WINAPI StrokePath(HDC);
+BOOL WINAPI SwapBuffers(HDC);
+BOOL WINAPI TextOutA(HDC,int,int,LPCSTR,int);
+BOOL WINAPI TextOutW(HDC,int,int,LPCWSTR,int);
+BOOL WINAPI TranslateCharsetInfo(PDWORD,LPCHARSETINFO,DWORD);
+BOOL WINAPI UnrealizeObject(HGDIOBJ);
+BOOL WINAPI UpdateColors(HDC);
+BOOL WINAPI UpdateICMRegKeyA(DWORD,DWORD,LPSTR,UINT);
+BOOL WINAPI UpdateICMRegKeyW(DWORD,DWORD,LPWSTR,UINT);
+BOOL WINAPI WidenPath(HDC);
+BOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT);
+HGLRC WINAPI wglCreateContext(HDC);
+HGLRC WINAPI wglCreateLayerContext(HDC,int);
+BOOL WINAPI wglDeleteContext(HGLRC);
+BOOL WINAPI wglDescribeLayerPlane(HDC,int,int,UINT,LPLAYERPLANEDESCRIPTOR);
+HGLRC WINAPI wglGetCurrentContext(void);
+HDC WINAPI wglGetCurrentDC(void);
+int WINAPI wglGetLayerPaletteEntries(HDC,int,int,int,COLORREF*);
+PROC WINAPI wglGetProcAddress(LPCSTR);
+BOOL WINAPI wglMakeCurrent(HDC,HGLRC);
+BOOL WINAPI wglRealizeLayerPalette(HDC,int,BOOL);
+int WINAPI wglSetLayerPaletteEntries(HDC,int,int,int,const COLORREF*);
+BOOL WINAPI wglShareLists(HGLRC,HGLRC);
+BOOL WINAPI wglSwapLayerBuffers(HDC,UINT);
+BOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD);
+BOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD);
+BOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+BOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT);
+
+#ifdef UNICODE
+typedef WCHAR BCHAR;
+typedef DOCINFOW DOCINFO, *LPDOCINFO;
+typedef LOGFONTW LOGFONT,*PLOGFONT,*LPLOGFONT;
+typedef TEXTMETRICW TEXTMETRIC,*PTEXTMETRIC,*LPTEXTMETRIC;
+#define ICMENUMPROC ICMENUMPROCW
+#define FONTENUMPROC FONTENUMPROCW
+typedef DEVMODEW DEVMODE,*PDEVMODE,*LPDEVMODE;
+typedef EXTLOGFONTW EXTLOGFONT,*PEXTLOGFONT,*LPEXTLOGFONT;
+typedef GCP_RESULTSW GCP_RESULTS,*LPGCP_RESULTS;
+typedef OUTLINETEXTMETRICW OUTLINETEXTMETRIC,*POUTLINETEXTMETRIC,*LPOUTLINETEXTMETRIC;
+typedef POLYTEXTW POLYTEXT;
+typedef LOGCOLORSPACEW LOGCOLORSPACE,*LPLOGCOLORSPACE;
+typedef NEWTEXTMETRICW NEWTEXTMETRIC,*PNEWTEXTMETRIC,*LPNEWTEXTMETRIC;
+typedef NEWTEXTMETRICEXW NEWTEXTMETRICEX;
+typedef ENUMLOGFONTW ENUMLOGFONT,*LPENUMLOGFONT;
+typedef ENUMLOGFONTEXW ENUMLOGFONTEX,*LPENUMLOGFONTEX;
+#define AddFontResource AddFontResourceW
+#define CopyEnhMetaFile CopyEnhMetaFileW
+#define CopyMetaFile CopyMetaFileW
+#define CreateDC CreateDCW
+#define CreateEnhMetaFile CreateEnhMetaFileW
+#define CreateFont CreateFontW
+#define CreateFontIndirect CreateFontIndirectW
+#define CreateIC CreateICW
+#define CreateMetaFile CreateMetaFileW
+#define CreateScalableFontResource CreateScalableFontResourceW
+#define DeviceCapabilities DeviceCapabilitiesW
+#define EnumFontFamilies EnumFontFamiliesW
+#define EnumFontFamiliesEx EnumFontFamiliesExW
+#define EnumFonts EnumFontsW
+#define EnumICMProfiles EnumICMProfilesW
+#define ExtTextOut ExtTextOutW
+#define GetCharABCWidthsFloat GetCharABCWidthsFloatW
+#define GetCharABCWidths GetCharABCWidthsW
+#define GetCharacterPlacement GetCharacterPlacementW
+#define GetCharWidth32 GetCharWidth32W
+#define GetCharWidthFloat GetCharWidthFloatW
+#define GetCharWidth GetCharWidthW
+#define GetEnhMetaFile GetEnhMetaFileW
+#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionW
+#define GetGlyphOutline GetGlyphOutlineW
+#define GetICMProfile GetICMProfileW
+#define GetKerningPairs GetKerningPairsW
+#define GetLogColorSpace GetLogColorSpaceW
+#define GetMetaFile GetMetaFileW
+#define GetObject GetObjectW
+#define GetOutlineTextMetrics GetOutlineTextMetricsW
+#define GetTextExtentPoint GetTextExtentPointW
+#define GetTextExtentExPoint GetTextExtentExPointW
+#define GetTextExtentPoint32 GetTextExtentPoint32W
+#define GetTextFace GetTextFaceW
+#define GetTextMetrics GetTextMetricsW
+#define PolyTextOut PolyTextOutW
+#define RemoveFontResource RemoveFontResourceW
+#define ResetDC ResetDCW
+#define SetICMProfile SetICMProfileW
+#define StartDoc StartDocW
+#define TextOut TextOutW
+#define UpdateICMRegKey UpdateICMRegKeyW
+#define wglUseFontBitmaps wglUseFontBitmapsW
+#define wglUseFontOutlines wglUseFontOutlinesW
+#else
+typedef BYTE BCHAR;
+typedef DOCINFOA DOCINFO, *LPDOCINFO;
+typedef LOGFONTA LOGFONT,*PLOGFONT,*LPLOGFONT;
+typedef TEXTMETRICA TEXTMETRIC,*PTEXTMETRIC,*LPTEXTMETRIC;
+#define ICMENUMPROC ICMENUMPROCA
+#define FONTENUMPROC FONTENUMPROCA
+typedef DEVMODEA DEVMODE,*PDEVMODE,*LPDEVMODE;
+typedef EXTLOGFONTA EXTLOGFONT,*PEXTLOGFONT,*LPEXTLOGFONT;
+typedef GCP_RESULTSA GCP_RESULTS,*LPGCP_RESULTS;
+typedef OUTLINETEXTMETRICA OUTLINETEXTMETRIC,*POUTLINETEXTMETRIC,*LPOUTLINETEXTMETRIC;
+typedef POLYTEXTA POLYTEXT;
+typedef LOGCOLORSPACEA LOGCOLORSPACE,*LPLOGCOLORSPACE;
+typedef NEWTEXTMETRICA NEWTEXTMETRIC,*PNEWTEXTMETRIC,*LPNEWTEXTMETRIC;
+typedef NEWTEXTMETRICEXA NEWTEXTMETRICEX;
+typedef ENUMLOGFONTA ENUMLOGFONT,*LPENUMLOGFONT;
+typedef ENUMLOGFONTEXA ENUMLOGFONTEX,*LPENUMLOGFONTEX;
+#define AddFontResource AddFontResourceA
+#define CopyEnhMetaFile CopyEnhMetaFileA
+#define CopyMetaFile CopyMetaFileA
+#define CreateDC CreateDCA
+#define CreateEnhMetaFile CreateEnhMetaFileA
+#define CreateFont CreateFontA
+#define CreateFontIndirect CreateFontIndirectA
+#define CreateIC CreateICA
+#define CreateMetaFile CreateMetaFileA
+#define CreateScalableFontResource CreateScalableFontResourceA
+#define DeviceCapabilities DeviceCapabilitiesA
+#define EnumFontFamilies EnumFontFamiliesA
+#define EnumFontFamiliesEx EnumFontFamiliesExA
+#define EnumFonts EnumFontsA
+#define EnumICMProfiles EnumICMProfilesA
+#define ExtTextOut ExtTextOutA
+#define GetCharWidthFloat GetCharWidthFloatA
+#define GetCharWidth GetCharWidthA
+#define GetCharacterPlacement GetCharacterPlacementA
+#define GetCharABCWidths GetCharABCWidthsA
+#define GetCharABCWidthsFloat GetCharABCWidthsFloatA
+#define GetCharWidth32 GetCharWidth32A
+#define GetEnhMetaFile GetEnhMetaFileA
+#define GetEnhMetaFileDescription GetEnhMetaFileDescriptionA
+#define GetGlyphOutline GetGlyphOutlineA
+#define GetICMProfile GetICMProfileA
+#define GetKerningPairs GetKerningPairsA
+#define GetLogColorSpace GetLogColorSpaceA
+#define GetMetaFile GetMetaFileA
+#define GetObject GetObjectA
+#define GetOutlineTextMetrics GetOutlineTextMetricsA
+#define GetTextExtentPoint GetTextExtentPointA
+#define GetTextExtentExPoint GetTextExtentExPointA
+#define GetTextExtentPoint32 GetTextExtentPoint32A
+#define GetTextFace GetTextFaceA
+#define GetTextMetrics GetTextMetricsA
+#define PolyTextOut PolyTextOutA
+#define RemoveFontResource RemoveFontResourceA
+#define ResetDC ResetDCA
+#define SetICMProfile SetICMProfileA
+#define StartDoc StartDocA
+#define TextOut TextOutA
+#define UpdateICMRegKey UpdateICMRegKeyA
+#define wglUseFontBitmaps wglUseFontBitmapsA
+#define wglUseFontOutlines wglUseFontOutlinesA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/winnetwk.h b/tinyc/win32/include/winapi/winnetwk.h
new file mode 100755
index 000000000..662fba9f8
--- /dev/null
+++ b/tinyc/win32/include/winapi/winnetwk.h
@@ -0,0 +1,346 @@
+#ifndef _WINNETWK_H
+#define _WINNETWK_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define WNNC_NET_MSNET      0x00010000
+#define WNNC_NET_LANMAN     0x00020000
+#define WNNC_NET_NETWARE    0x00030000
+#define WNNC_NET_VINES      0x00040000
+#define WNNC_NET_10NET      0x00050000
+#define WNNC_NET_LOCUS      0x00060000
+#define WNNC_NET_SUN_PC_NFS 0x00070000
+#define WNNC_NET_LANSTEP    0x00080000
+#define WNNC_NET_9TILES     0x00090000
+#define WNNC_NET_LANTASTIC  0x000A0000
+#define WNNC_NET_AS400      0x000B0000
+#define WNNC_NET_FTP_NFS    0x000C0000
+#define WNNC_NET_PATHWORKS  0x000D0000
+#define WNNC_NET_LIFENET    0x000E0000
+#define WNNC_NET_POWERLAN   0x000F0000
+#define WNNC_NET_BWNFS      0x00100000
+#define WNNC_NET_COGENT     0x00110000
+#define WNNC_NET_FARALLON	0x00120000
+#define WNNC_NET_APPLETALK	0x00130000
+#define WNNC_NET_INTERGRAPH	0x00140000
+#define WNNC_NET_SYMFONET   0x00150000
+#define WNNC_NET_CLEARCASE  0x00160000
+#define WNNC_NET_FRONTIER   0x00170000
+#define WNNC_NET_BMC        0x00180000
+#define WNNC_NET_DCE        0x00190000
+#define WNNC_NET_AVID       0x001A0000
+#define WNNC_NET_DOCUSPACE  0x001B0000
+#define WNNC_NET_MANGOSOFT  0x001C0000
+#define WNNC_NET_SERNET     0x001D0000
+#define WNNC_NET_DECORB     0x00200000
+#define WNNC_NET_PROTSTOR   0x00210000
+#define WNNC_NET_FJ_REDIR   0x00220000
+#define WNNC_NET_DISTINCT   0x00230000
+#define WNNC_NET_TWINS      0x00240000
+#define WNNC_NET_RDR2SAMPLE 0x00250000
+#define WNNC_NET_CSC        0x00260000
+#define WNNC_NET_3IN1       0x00270000
+#define WNNC_NET_EXTENDNET  0x00290000
+#define WNNC_NET_OBJECT_DIRE 0x00300000
+#define WNNC_NET_MASFAX     0x00310000
+#define WNNC_NET_HOB_NFS    0x00320000
+#define WNNC_NET_SHIVA      0x00330000
+#define WNNC_NET_IBMAL      0x00340000
+#define WNNC_CRED_MANAGER   0xFFFF0000
+
+#define RESOURCE_CONNECTED 1
+#define RESOURCE_GLOBALNET 2
+#define RESOURCE_REMEMBERED 3
+#define RESOURCE_RECENT 4
+#define RESOURCE_CONTEXT 5
+#define RESOURCETYPE_ANY 0
+#define RESOURCETYPE_DISK 1
+#define RESOURCETYPE_PRINT 2
+#define RESOURCETYPE_RESERVED 8
+#define RESOURCETYPE_UNKNOWN        0xFFFFFFFF
+#define RESOURCEUSAGE_CONNECTABLE   0x00000001
+#define RESOURCEUSAGE_CONTAINER     0x00000002
+#define RESOURCEUSAGE_NOLOCALDEVICE 0x00000004
+#define RESOURCEUSAGE_SIBLING       0x00000008
+#define RESOURCEUSAGE_ATTACHED      0x00000010
+#define RESOURCEUSAGE_ALL           (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED)
+#define RESOURCEUSAGE_RESERVED      0x80000000
+#define RESOURCEDISPLAYTYPE_GENERIC 0
+#define RESOURCEDISPLAYTYPE_DOMAIN 1
+#define RESOURCEDISPLAYTYPE_SERVER 2
+#define RESOURCEDISPLAYTYPE_SHARE 3
+#define RESOURCEDISPLAYTYPE_FILE 4
+#define RESOURCEDISPLAYTYPE_GROUP 5
+#define RESOURCEDISPLAYTYPE_NETWORK 6
+#define RESOURCEDISPLAYTYPE_ROOT 7
+#define RESOURCEDISPLAYTYPE_SHAREADMIN 8
+#define RESOURCEDISPLAYTYPE_DIRECTORY 9
+#define RESOURCEDISPLAYTYPE_TREE 10
+#define NETPROPERTY_PERSISTENT 1
+#define CONNECT_UPDATE_PROFILE 1
+#define CONNECT_UPDATE_RECENT 2
+#define CONNECT_TEMPORARY 4
+#define CONNECT_INTERACTIVE 8
+#define CONNECT_PROMPT 16
+#define CONNECT_NEED_DRIVE 32
+#define CONNECT_REFCOUNT 64
+#define CONNECT_REDIRECT 128
+#define CONNECT_LOCALDRIVE 256
+#define CONNECT_CURRENT_MEDIA 512
+#define CONNDLG_RO_PATH 1
+#define CONNDLG_CONN_POINT 2
+#define CONNDLG_USE_MRU 4
+#define CONNDLG_HIDE_BOX 8
+#define CONNDLG_PERSIST 16
+#define CONNDLG_NOT_PERSIST 32
+#define DISC_UPDATE_PROFILE 1
+#define DISC_NO_FORCE 64
+#define WNFMT_MULTILINE 1
+#define WNFMT_ABBREVIATED 2
+#define WNFMT_INENUM 16
+#define WNFMT_CONNECTION 32
+#define WN_SUCCESS NO_ERROR
+#define WN_NO_ERROR NO_ERROR
+#define WN_NOT_SUPPORTED ERROR_NOT_SUPPORTED
+#define WN_CANCEL ERROR_CANCELLED
+#define WN_RETRY ERROR_RETRY
+#define WN_NET_ERROR ERROR_UNEXP_NET_ERR
+#define WN_MORE_DATA ERROR_MORE_DATA
+#define WN_BAD_POINTER ERROR_INVALID_ADDRESS
+#define WN_BAD_VALUE ERROR_INVALID_PARAMETER
+#define WN_BAD_USER ERROR_BAD_USERNAME
+#define WN_BAD_PASSWORD ERROR_INVALID_PASSWORD
+#define WN_ACCESS_DENIED ERROR_ACCESS_DENIED
+#define WN_FUNCTION_BUSY ERROR_BUSY
+#define WN_WINDOWS_ERROR ERROR_UNEXP_NET_ERR
+#define WN_OUT_OF_MEMORY ERROR_NOT_ENOUGH_MEMORY
+#define WN_NO_NETWORK ERROR_NO_NETWORK
+#define WN_EXTENDED_ERROR ERROR_EXTENDED_ERROR
+#define WN_BAD_LEVEL ERROR_INVALID_LEVEL
+#define WN_BAD_HANDLE ERROR_INVALID_HANDLE
+#define WN_NOT_INITIALIZING ERROR_ALREADY_INITIALIZED
+#define WN_NO_MORE_DEVICES ERROR_NO_MORE_DEVICES
+#define WN_NOT_CONNECTED ERROR_NOT_CONNECTED
+#define WN_OPEN_FILES ERROR_OPEN_FILES
+#define WN_DEVICE_IN_USE ERROR_DEVICE_IN_USE
+#define WN_BAD_NETNAME ERROR_BAD_NET_NAME
+#define WN_BAD_LOCALNAME ERROR_BAD_DEVICE
+#define WN_ALREADY_CONNECTED ERROR_ALREADY_ASSIGNED
+#define WN_DEVICE_ERROR ERROR_GEN_FAILURE
+#define WN_CONNECTION_CLOSED ERROR_CONNECTION_UNAVAIL
+#define WN_NO_NET_OR_BAD_PATH ERROR_NO_NET_OR_BAD_PATH
+#define WN_BAD_PROVIDER ERROR_BAD_PROVIDER
+#define WN_CANNOT_OPEN_PROFILE ERROR_CANNOT_OPEN_PROFILE
+#define WN_BAD_PROFILE ERROR_BAD_PROFILE
+#define WN_BAD_DEV_TYPE ERROR_BAD_DEV_TYPE
+#define WN_DEVICE_ALREADY_REMEMBERED ERROR_DEVICE_ALREADY_REMEMBERED
+#define WN_NO_MORE_ENTRIES ERROR_NO_MORE_ITEMS
+#define WN_NOT_CONTAINER ERROR_NOT_CONTAINER
+#define WN_NOT_AUTHENTICATED ERROR_NOT_AUTHENTICATED
+#define WN_NOT_LOGGED_ON ERROR_NOT_LOGGED_ON
+#define WN_NOT_VALIDATED ERROR_NO_LOGON_SERVERS
+#define UNIVERSAL_NAME_INFO_LEVEL 1
+#define REMOTE_NAME_INFO_LEVEL 2
+#define NETINFO_DLL16 1
+#define NETINFO_DISKRED 4
+#define NETINFO_PRINTERRED 8
+#define RP_LOGON 1
+#define RP_INIFILE 2
+#define PP_DISPLAYERRORS 1
+#define WNCON_FORNETCARD 1
+#define WNCON_NOTROUTED 2
+#define WNCON_SLOWLINK 4
+#define WNCON_DYNAMIC 8
+
+#ifndef RC_INVOKED
+typedef struct _NETRESOURCEA {
+	DWORD dwScope;
+	DWORD dwType;
+	DWORD dwDisplayType;
+	DWORD dwUsage;
+	LPSTR lpLocalName;
+	LPSTR lpRemoteName;
+	LPSTR lpComment ;
+	LPSTR lpProvider;
+}NETRESOURCEA,*LPNETRESOURCEA;
+typedef struct _NETRESOURCEW {
+	DWORD dwScope;
+	DWORD dwType;
+	DWORD dwDisplayType;
+	DWORD dwUsage;
+	LPWSTR lpLocalName;
+	LPWSTR lpRemoteName;
+	LPWSTR lpComment ;
+	LPWSTR lpProvider;
+}NETRESOURCEW,*LPNETRESOURCEW;
+typedef struct _CONNECTDLGSTRUCTA{
+	DWORD cbStructure;
+	HWND hwndOwner;
+	LPNETRESOURCEA lpConnRes;
+	DWORD dwFlags;
+	DWORD dwDevNum;
+} CONNECTDLGSTRUCTA,*LPCONNECTDLGSTRUCTA;
+typedef struct _CONNECTDLGSTRUCTW{
+	DWORD cbStructure;
+	HWND hwndOwner;
+	LPNETRESOURCEW lpConnRes;
+	DWORD dwFlags;
+	DWORD dwDevNum;
+} CONNECTDLGSTRUCTW,*LPCONNECTDLGSTRUCTW;
+typedef struct _DISCDLGSTRUCTA{
+	DWORD cbStructure;
+	HWND hwndOwner;
+	LPSTR lpLocalName;
+	LPSTR lpRemoteName;
+	DWORD dwFlags;
+} DISCDLGSTRUCTA,*LPDISCDLGSTRUCTA;
+typedef struct _DISCDLGSTRUCTW{
+	DWORD cbStructure;
+	HWND hwndOwner;
+	LPWSTR lpLocalName;
+	LPWSTR lpRemoteName;
+	DWORD dwFlags;
+} DISCDLGSTRUCTW,*LPDISCDLGSTRUCTW;
+typedef struct _UNIVERSAL_NAME_INFOA { LPSTR lpUniversalName; }UNIVERSAL_NAME_INFOA,*LPUNIVERSAL_NAME_INFOA;
+typedef struct _UNIVERSAL_NAME_INFOW { LPWSTR lpUniversalName; }UNIVERSAL_NAME_INFOW,*LPUNIVERSAL_NAME_INFOW;
+typedef struct _REMOTE_NAME_INFOA {
+	LPSTR lpUniversalName;
+	LPSTR lpConnectionName;
+	LPSTR lpRemainingPath;
+}REMOTE_NAME_INFOA,*LPREMOTE_NAME_INFOA;
+typedef struct _REMOTE_NAME_INFOW {
+	LPWSTR lpUniversalName;
+	LPWSTR lpConnectionName;
+	LPWSTR lpRemainingPath;
+}REMOTE_NAME_INFOW,*LPREMOTE_NAME_INFOW;
+typedef struct _NETINFOSTRUCT{
+	DWORD cbStructure;
+	DWORD dwProviderVersion;
+	DWORD dwStatus;
+	DWORD dwCharacteristics;
+	DWORD dwHandle;
+	WORD wNetType;
+	DWORD dwPrinters;
+	DWORD dwDrives;
+} NETINFOSTRUCT,*LPNETINFOSTRUCT;
+typedef UINT(PASCAL *PFNGETPROFILEPATHA)(LPCSTR,LPSTR,UINT);
+typedef UINT(PASCAL *PFNGETPROFILEPATHW)(LPCWSTR,LPWSTR,UINT);
+typedef UINT(PASCAL *PFNRECONCILEPROFILEA)(LPCSTR,LPCSTR,DWORD);
+typedef UINT(PASCAL *PFNRECONCILEPROFILEW)(LPCWSTR,LPCWSTR,DWORD);
+typedef BOOL(PASCAL *PFNPROCESSPOLICIESA)(HWND,LPCSTR,LPCSTR,LPCSTR,DWORD);
+typedef BOOL(PASCAL *PFNPROCESSPOLICIESW)(HWND,LPCWSTR,LPCWSTR,LPCWSTR,DWORD);
+typedef struct _NETCONNECTINFOSTRUCT{
+	DWORD cbStructure;
+	DWORD dwFlags;
+	DWORD dwSpeed;
+	DWORD dwDelay;
+	DWORD dwOptDataSize;
+} NETCONNECTINFOSTRUCT,*LPNETCONNECTINFOSTRUCT;
+
+DWORD APIENTRY WNetAddConnectionA(LPCSTR,LPCSTR,LPCSTR);
+DWORD APIENTRY WNetAddConnectionW(LPCWSTR,LPCWSTR,LPCWSTR);
+DWORD APIENTRY WNetAddConnection2A(LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD);
+DWORD APIENTRY WNetAddConnection2W(LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD);
+DWORD APIENTRY WNetAddConnection3A(HWND,LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD);
+DWORD APIENTRY WNetAddConnection3W(HWND,LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD);
+DWORD APIENTRY WNetCancelConnectionA(LPCSTR,BOOL);
+DWORD APIENTRY WNetCancelConnectionW(LPCWSTR,BOOL);
+DWORD APIENTRY WNetCancelConnection2A(LPCSTR,DWORD,BOOL);
+DWORD APIENTRY WNetCancelConnection2W(LPCWSTR,DWORD,BOOL);
+DWORD APIENTRY WNetGetConnectionA(LPCSTR,LPSTR,PDWORD);
+DWORD APIENTRY WNetGetConnectionW(LPCWSTR,LPWSTR,PDWORD);
+DWORD APIENTRY WNetUseConnectionA(HWND,LPNETRESOURCEA,LPCSTR,LPCSTR,DWORD,LPSTR,PDWORD,PDWORD);
+DWORD APIENTRY WNetUseConnectionW(HWND,LPNETRESOURCEW,LPCWSTR,LPCWSTR,DWORD,LPWSTR,PDWORD,PDWORD);
+DWORD APIENTRY WNetSetConnectionA(LPCSTR,DWORD,PVOID);
+DWORD APIENTRY WNetSetConnectionW(LPCWSTR,DWORD,PVOID);
+DWORD APIENTRY WNetConnectionDialog(HWND,DWORD);
+DWORD APIENTRY WNetDisconnectDialog(HWND,DWORD);
+DWORD APIENTRY WNetConnectionDialog1A(LPCONNECTDLGSTRUCTA);
+DWORD APIENTRY WNetConnectionDialog1W(LPCONNECTDLGSTRUCTW);
+DWORD APIENTRY WNetDisconnectDialog1A(LPDISCDLGSTRUCTA);
+DWORD APIENTRY WNetDisconnectDialog1W(LPDISCDLGSTRUCTW);
+DWORD APIENTRY WNetOpenEnumA(DWORD,DWORD,DWORD,LPNETRESOURCEA,LPHANDLE);
+DWORD APIENTRY WNetOpenEnumW(DWORD,DWORD,DWORD,LPNETRESOURCEW,LPHANDLE);
+DWORD APIENTRY WNetEnumResourceA(HANDLE,PDWORD,PVOID,PDWORD);
+DWORD APIENTRY WNetEnumResourceW(HANDLE,PDWORD,PVOID,PDWORD);
+DWORD APIENTRY WNetCloseEnum(HANDLE);
+DWORD APIENTRY WNetGetUniversalNameA(LPCSTR,DWORD,PVOID,PDWORD);
+DWORD APIENTRY WNetGetUniversalNameW(LPCWSTR,DWORD,PVOID,PDWORD);
+DWORD APIENTRY WNetGetUserA(LPCSTR,LPSTR,PDWORD);
+DWORD APIENTRY WNetGetUserW(LPCWSTR,LPWSTR,PDWORD);
+DWORD APIENTRY WNetGetProviderNameA(DWORD,LPSTR,PDWORD);
+DWORD APIENTRY WNetGetProviderNameW(DWORD,LPWSTR,PDWORD);
+DWORD APIENTRY WNetGetNetworkInformationA(LPCSTR,LPNETINFOSTRUCT);
+DWORD APIENTRY WNetGetNetworkInformationW(LPCWSTR,LPNETINFOSTRUCT);
+DWORD APIENTRY WNetGetResourceInformationA(LPNETRESOURCEA,LPVOID,LPDWORD,LPCSTR*);
+DWORD APIENTRY WNetGetResourceInformationW(LPNETRESOURCEA,LPVOID,LPDWORD,LPCWSTR*);
+DWORD APIENTRY WNetGetLastErrorA(PDWORD,LPSTR,DWORD,LPSTR,DWORD);
+DWORD APIENTRY WNetGetLastErrorW(PDWORD,LPWSTR,DWORD,LPWSTR,DWORD);
+DWORD APIENTRY MultinetGetConnectionPerformanceA(LPNETRESOURCEA,LPNETCONNECTINFOSTRUCT);
+DWORD APIENTRY MultinetGetConnectionPerformanceW(LPNETRESOURCEW,LPNETCONNECTINFOSTRUCT);
+#ifdef UNICODE
+#define PFNPROCESSPOLICIES PFNPROCESSPOLICIESW
+#define PFNRECONCILEPROFILE PFNRECONCILEPROFILEW
+#define PFNGETPROFILEPATH PFNGETPROFILEPATHW
+typedef NETRESOURCEW NETRESOURCE,*LPNETRESOURCE;
+typedef CONNECTDLGSTRUCTW CONNECTDLGSTRUCT,*LPCONNECTDLGSTRUCT;
+typedef DISCDLGSTRUCTW DISCDLGSTRUCT,*LPDISCDLGSTRUCT;
+typedef REMOTE_NAME_INFOW REMOTE_NAME_INFO,*LPREMOTE_NAME_INFO;
+typedef UNIVERSAL_NAME_INFOW UNIVERSAL_NAME_INFO,*LPUNIVERSAL_NAME_INFO;
+#define WNetEnumResource WNetEnumResourceW
+#define WNetOpenEnum WNetOpenEnumW
+#define WNetGetResourceInformation WNetGetResourceInformationW
+#define WNetGetUniversalName WNetGetUniversalNameW
+#define WNetSetConnection WNetSetConnectionW
+#define WNetUseConnection WNetUseConnectionW
+#define WNetGetConnection WNetGetConnectionW
+#define WNetCancelConnection2 WNetCancelConnection2W
+#define WNetCancelConnection WNetCancelConnectionW
+#define WNetAddConnection3 WNetAddConnection3W
+#define WNetAddConnection2 WNetAddConnection2W
+#define WNetAddConnection WNetAddConnectionW
+#define WNetConnectionDialog1 WNetConnectionDialog1W
+#define WNetDisconnectDialog1 WNetDisconnectDialog1W
+#define WNetGetNetworkInformation WNetGetNetworkInformationW
+#define WNetGetProviderName WNetGetProviderNameW
+#define WNetGetUser WNetGetUserW
+#define MultinetGetConnectionPerformance MultinetGetConnectionPerformanceW
+#define WNetGetLastError WNetGetLastErrorW
+#else
+#define PFNGETPROFILEPATH PFNGETPROFILEPATHA
+#define PFNRECONCILEPROFILE PFNRECONCILEPROFILEA
+#define PFNPROCESSPOLICIES PFNPROCESSPOLICIESA
+typedef NETRESOURCEA NETRESOURCE,*LPNETRESOURCE;
+typedef CONNECTDLGSTRUCTA CONNECTDLGSTRUCT,*LPCONNECTDLGSTRUCT;
+typedef DISCDLGSTRUCTA DISCDLGSTRUCT,*LPDISCDLGSTRUCT;
+typedef UNIVERSAL_NAME_INFOA UNIVERSAL_NAME_INFO,*LPUNIVERSAL_NAME_INFO;
+typedef REMOTE_NAME_INFOA REMOTE_NAME_INFO,*LPREMOTE_NAME_INFO;
+#define WNetOpenEnum WNetOpenEnumA
+#define WNetEnumResource WNetEnumResourceA
+#define WNetGetResourceInformation WNetGetResourceInformationA
+#define WNetGetUniversalName WNetGetUniversalNameA
+#define WNetConnectionDialog1 WNetConnectionDialog1A
+#define WNetDisconnectDialog1 WNetDisconnectDialog1A
+#define WNetAddConnection2 WNetAddConnection2A
+#define WNetAddConnection3 WNetAddConnection3A
+#define WNetCancelConnection WNetCancelConnectionA
+#define WNetCancelConnection2 WNetCancelConnection2A
+#define WNetGetConnection WNetGetConnectionA
+#define WNetUseConnection WNetUseConnectionA
+#define WNetSetConnection WNetSetConnectionA
+#define WNetAddConnection WNetAddConnectionA
+#define WNetGetUser WNetGetUserA
+#define WNetGetProviderName WNetGetProviderNameA
+#define WNetGetNetworkInformation WNetGetNetworkInformationA
+#define WNetGetLastError WNetGetLastErrorA
+#define MultinetGetConnectionPerformance MultinetGetConnectionPerformanceA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/winnls.h b/tinyc/win32/include/winapi/winnls.h
new file mode 100755
index 000000000..3933812b7
--- /dev/null
+++ b/tinyc/win32/include/winapi/winnls.h
@@ -0,0 +1,651 @@
+#ifndef _WINNLS_H
+#define _WINNLS_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_LEADBYTES 	12
+#define MAX_DEFAULTCHAR	2
+#define LOCALE_NOUSEROVERRIDE	0x80000000
+#define LOCALE_USE_CP_ACP	0x40000000
+#define LOCALE_ILANGUAGE	1
+#define LOCALE_SLANGUAGE	2
+#define LOCALE_SENGLANGUAGE	0x1001
+#define LOCALE_SABBREVLANGNAME	3
+#define LOCALE_SNATIVELANGNAME	4
+#define LOCALE_ICOUNTRY	5
+#define LOCALE_SCOUNTRY	6
+#define LOCALE_SENGCOUNTRY	0x1002
+#define LOCALE_SABBREVCTRYNAME	7
+#define LOCALE_SNATIVECTRYNAME	8
+#define LOCALE_IDEFAULTLANGUAGE	9
+#define LOCALE_IDEFAULTCOUNTRY	10
+#define LOCALE_IDEFAULTCODEPAGE	11
+#define LOCALE_IDEFAULTANSICODEPAGE 0x1004
+#define LOCALE_SLIST	12
+#define LOCALE_IMEASURE	13
+#define LOCALE_SDECIMAL	14
+#define LOCALE_STHOUSAND	15
+#define LOCALE_SGROUPING	16
+#define LOCALE_IDIGITS	17
+#define LOCALE_ILZERO	18
+#define LOCALE_INEGNUMBER	0x1010
+#define LOCALE_SNATIVEDIGITS	19
+#define LOCALE_SCURRENCY	20
+#define LOCALE_SINTLSYMBOL	21
+#define LOCALE_SMONDECIMALSEP	22
+#define LOCALE_SMONTHOUSANDSEP	23
+#define LOCALE_SMONGROUPING	24
+#define LOCALE_ICURRDIGITS	25
+#define LOCALE_IINTLCURRDIGITS	26
+#define LOCALE_ICURRENCY	27
+#define LOCALE_INEGCURR	28
+#define LOCALE_SDATE	29
+#define LOCALE_STIME	30
+#define LOCALE_SSHORTDATE	31
+#define LOCALE_SLONGDATE	32
+#define LOCALE_STIMEFORMAT	0x1003
+#define LOCALE_IDATE	33
+#define LOCALE_ILDATE	34
+#define LOCALE_ITIME	35
+#define LOCALE_ITIMEMARKPOSN	0x1005
+#define LOCALE_ICENTURY	36
+#define LOCALE_ITLZERO	37
+#define LOCALE_IDAYLZERO	38
+#define LOCALE_IMONLZERO	39
+#define LOCALE_S1159	40
+#define LOCALE_S2359	41
+#define LOCALE_ICALENDARTYPE	0x1009
+#define LOCALE_IOPTIONALCALENDAR	0x100B
+#define LOCALE_IFIRSTDAYOFWEEK	0x100C
+#define LOCALE_IFIRSTWEEKOFYEAR	0x100D
+#define LOCALE_SDAYNAME1	42
+#define LOCALE_SDAYNAME2	43
+#define LOCALE_SDAYNAME3	44
+#define LOCALE_SDAYNAME4	45
+#define LOCALE_SDAYNAME5	46
+#define LOCALE_SDAYNAME6	47
+#define LOCALE_SDAYNAME7	48
+#define LOCALE_SABBREVDAYNAME1	49
+#define LOCALE_SABBREVDAYNAME2	50
+#define LOCALE_SABBREVDAYNAME3	51
+#define LOCALE_SABBREVDAYNAME4	52
+#define LOCALE_SABBREVDAYNAME5	53
+#define LOCALE_SABBREVDAYNAME6	54
+#define LOCALE_SABBREVDAYNAME7	55
+#define LOCALE_SMONTHNAME1	56
+#define LOCALE_SMONTHNAME2	57
+#define LOCALE_SMONTHNAME3	58
+#define LOCALE_SMONTHNAME4	59
+#define LOCALE_SMONTHNAME5	60
+#define LOCALE_SMONTHNAME6	61
+#define LOCALE_SMONTHNAME7	62
+#define LOCALE_SMONTHNAME8	63
+#define LOCALE_SMONTHNAME9	64
+#define LOCALE_SMONTHNAME10	65
+#define LOCALE_SMONTHNAME11	66
+#define LOCALE_SMONTHNAME12	67
+#define LOCALE_SMONTHNAME13	0x100E
+#define LOCALE_SABBREVMONTHNAME1	68
+#define LOCALE_SABBREVMONTHNAME2	69
+#define LOCALE_SABBREVMONTHNAME3	70
+#define LOCALE_SABBREVMONTHNAME4	71
+#define LOCALE_SABBREVMONTHNAME5	72
+#define LOCALE_SABBREVMONTHNAME6	73
+#define LOCALE_SABBREVMONTHNAME7	74
+#define LOCALE_SABBREVMONTHNAME8	75
+#define LOCALE_SABBREVMONTHNAME9	76
+#define LOCALE_SABBREVMONTHNAME10	77
+#define LOCALE_SABBREVMONTHNAME11	78
+#define LOCALE_SABBREVMONTHNAME12	79
+#define LOCALE_SABBREVMONTHNAME13	0x100F
+#define LOCALE_SPOSITIVESIGN	80
+#define LOCALE_SNEGATIVESIGN	81
+#define LOCALE_IPOSSIGNPOSN	82
+#define LOCALE_INEGSIGNPOSN	83
+#define LOCALE_IPOSSYMPRECEDES	84
+#define LOCALE_IPOSSEPBYSPACE	85
+#define LOCALE_INEGSYMPRECEDES	86
+#define LOCALE_INEGSEPBYSPACE	87
+#define LOCALE_FONTSIGNATURE	88
+#define LOCALE_SISO639LANGNAME 89
+#define LOCALE_SISO3166CTRYNAME 90
+#define LOCALE_SYSTEM_DEFAULT	0x800
+#define LOCALE_USER_DEFAULT	0x400
+#define NORM_IGNORECASE	1
+#define NORM_IGNOREKANATYPE	65536
+#define NORM_IGNORENONSPACE	2
+#define NORM_IGNORESYMBOLS	4
+#define NORM_IGNOREWIDTH	131072
+#define SORT_STRINGSORT	4096
+#define LCMAP_LOWERCASE 0x00000100
+#define LCMAP_UPPERCASE 0x00000200
+#define LCMAP_SORTKEY 0x00000400
+#define LCMAP_BYTEREV 0x00000800
+#define LCMAP_HIRAGANA 0x00100000
+#define LCMAP_KATAKANA 0x00200000
+#define LCMAP_HALFWIDTH 0x00400000
+#define LCMAP_FULLWIDTH 0x00800000
+#define LCMAP_LINGUISTIC_CASING 0x01000000
+#define LCMAP_SIMPLIFIED_CHINESE 0x02000000
+#define LCMAP_TRADITIONAL_CHINESE 0x04000000
+#define ENUM_ALL_CALENDARS (-1)
+#define DATE_SHORTDATE 1
+#define DATE_LONGDATE 2
+#define DATE_USE_ALT_CALENDAR 4
+#define CP_INSTALLED 1
+#define CP_SUPPORTED 2
+#define LCID_INSTALLED 1
+#define LCID_SUPPORTED 2
+#define LCID_ALTERNATE_SORTS 4
+#define MAP_FOLDCZONE 16
+#define MAP_FOLDDIGITS 128
+#define MAP_PRECOMPOSED 32
+#define MAP_COMPOSITE 64
+#define CP_ACP 0
+#define CP_OEMCP 1
+#define CP_MACCP 2
+#define CP_THREAD_ACP 3
+#define CP_SYMBOL 42
+#define CP_UTF7 65000
+#define CP_UTF8 65001
+#define CT_CTYPE1 1
+#define CT_CTYPE2 2
+#define CT_CTYPE3 4
+#define C1_UPPER 1
+#define C1_LOWER 2
+#define C1_DIGIT 4
+#define C1_SPACE 8
+#define C1_PUNCT 16
+#define C1_CNTRL 32
+#define C1_BLANK 64
+#define C1_XDIGIT 128
+#define C1_ALPHA 256
+#define C2_LEFTTORIGHT 1
+#define C2_RIGHTTOLEFT 2
+#define C2_EUROPENUMBER 3
+#define C2_EUROPESEPARATOR 4
+#define C2_EUROPETERMINATOR 5
+#define C2_ARABICNUMBER 6
+#define C2_COMMONSEPARATOR 7
+#define C2_BLOCKSEPARATOR 8
+#define C2_SEGMENTSEPARATOR 9
+#define C2_WHITESPACE 10
+#define C2_OTHERNEUTRAL 11
+#define C2_NOTAPPLICABLE 0
+#define C3_NONSPACING 1
+#define C3_DIACRITIC 2
+#define C3_VOWELMARK 4
+#define C3_SYMBOL 8
+#define C3_KATAKANA 16
+#define C3_HIRAGANA 32
+#define C3_HALFWIDTH 64
+#define C3_FULLWIDTH 128
+#define C3_IDEOGRAPH 256
+#define C3_KASHIDA 512
+#define C3_LEXICAL 1024
+#define C3_ALPHA 32768
+#define C3_NOTAPPLICABLE 0
+#define TIME_NOMINUTESORSECONDS 1
+#define TIME_NOSECONDS 2
+#define TIME_NOTIMEMARKER 4
+#define TIME_FORCE24HOURFORMAT 8
+#define MB_PRECOMPOSED 1
+#define MB_COMPOSITE 2
+#define MB_ERR_INVALID_CHARS 8
+#define MB_USEGLYPHCHARS 4
+#define WC_COMPOSITECHECK 512
+#define WC_DISCARDNS 16
+#define WC_SEPCHARS 32
+#define WC_DEFAULTCHAR 64
+#define CTRY_DEFAULT 0
+#define CTRY_ALBANIA 355
+#define CTRY_ALGERIA 213
+#define CTRY_ARGENTINA 54
+#define CTRY_ARMENIA 374
+#define CTRY_AUSTRALIA 61
+#define CTRY_AUSTRIA 43
+#define CTRY_AZERBAIJAN 994
+#define CTRY_BAHRAIN 973
+#define CTRY_BELARUS 375
+#define CTRY_BELGIUM 32
+#define CTRY_BELIZE 501
+#define CTRY_BOLIVIA 591
+#define CTRY_BRAZIL 55
+#define CTRY_BRUNEI_DARUSSALAM 673
+#define CTRY_BULGARIA 359
+#define CTRY_CANADA 2
+#define CTRY_CARIBBEAN 1
+#define CTRY_CHILE 56
+#define CTRY_COLOMBIA 57
+#define CTRY_COSTA_RICA 506
+#define CTRY_CROATIA 385
+#define CTRY_CZECH 420
+#define CTRY_DENMARK 45
+#define CTRY_DOMINICAN_REPUBLIC 1
+#define CTRY_ECUADOR 593
+#define CTRY_EGYPT 20
+#define CTRY_EL_SALVADOR 503
+#define CTRY_ESTONIA 372
+#define CTRY_FAEROE_ISLANDS 298
+#define CTRY_FINLAND 358
+#define CTRY_FRANCE 33
+#define CTRY_GEORGIA 995
+#define CTRY_GERMANY 49
+#define CTRY_GREECE 30
+#define CTRY_GUATEMALA 502
+#define CTRY_HONDURAS 504
+#define CTRY_HONG_KONG 852
+#define CTRY_HUNGARY 36
+#define CTRY_ICELAND 354
+#define CTRY_INDIA 91
+#define CTRY_INDONESIA 62
+#define CTRY_IRAN 981
+#define CTRY_IRAQ 964
+#define CTRY_IRELAND 353
+#define CTRY_ISRAEL 972
+#define CTRY_ITALY 39
+#define CTRY_JAMAICA 1
+#define CTRY_JAPAN 81
+#define CTRY_JORDAN 962
+#define CTRY_KAZAKSTAN 7
+#define CTRY_KENYA 254
+#define CTRY_KUWAIT 965
+#define CTRY_LATVIA 371
+#define CTRY_LEBANON 961
+#define CTRY_LIBYA 218
+#define CTRY_LIECHTENSTEIN 41
+#define CTRY_LITHUANIA 370
+#define CTRY_LUXEMBOURG 352
+#define CTRY_MACAU 853
+#define CTRY_MACEDONIA 389
+#define CTRY_MALAYSIA 60
+#define CTRY_MEXICO 52
+#define CTRY_MONACO 33
+#define CTRY_MOROCCO 212
+#define CTRY_NETHERLANDS 31
+#define CTRY_NEW_ZEALAND 64
+#define CTRY_NICARAGUA 505
+#define CTRY_NORWAY 47
+#define CTRY_OMAN 968
+#define CTRY_PAKISTAN 92
+#define CTRY_PANAMA 507
+#define CTRY_PARAGUAY 595
+#define CTRY_PERU 51
+#define CTRY_PHILIPPINES 63
+#define CTRY_POLAND 48
+#define CTRY_PORTUGAL 351
+#define CTRY_PRCHINA 86
+#define CTRY_PUERTO_RICO 1
+#define CTRY_QATAR 974
+#define CTRY_ROMANIA 40
+#define CTRY_RUSSIA 7
+#define CTRY_SAUDI_ARABIA 966
+#define CTRY_SERBIA 381
+#define CTRY_SINGAPORE 65
+#define CTRY_SLOVAK 421
+#define CTRY_SLOVENIA 386
+#define CTRY_SOUTH_AFRICA 27
+#define CTRY_SOUTH_KOREA 82
+#define CTRY_SPAIN 34
+#define CTRY_SWEDEN 46
+#define CTRY_SWITZERLAND 41
+#define CTRY_SYRIA 963
+#define CTRY_TAIWAN 886
+#define CTRY_TATARSTAN 7
+#define CTRY_THAILAND 66
+#define CTRY_TRINIDAD_Y_TOBAGO 1
+#define CTRY_TUNISIA 216
+#define CTRY_TURKEY 90
+#define CTRY_UAE 971
+#define CTRY_UKRAINE 380
+#define CTRY_UNITED_KINGDOM 44
+#define CTRY_UNITED_STATES 1
+#define CTRY_URUGUAY 598
+#define CTRY_UZBEKISTAN 7
+#define CTRY_VENEZUELA 58
+#define CTRY_VIET_NAM 84
+#define CTRY_YEMEN 967
+#define CTRY_ZIMBABWE 263
+#define CAL_ICALINTVALUE 1
+#define CAL_SCALNAME 2
+#define CAL_IYEAROFFSETRANGE 3
+#define CAL_SERASTRING 4
+#define CAL_SSHORTDATE 5
+#define CAL_SLONGDATE 6
+#define CAL_SDAYNAME1 7
+#define CAL_SDAYNAME2 8
+#define CAL_SDAYNAME3 9
+#define CAL_SDAYNAME4 10
+#define CAL_SDAYNAME5 11
+#define CAL_SDAYNAME6 12
+#define CAL_SDAYNAME7 13
+#define CAL_SABBREVDAYNAME1 14
+#define CAL_SABBREVDAYNAME2 15
+#define CAL_SABBREVDAYNAME3 16
+#define CAL_SABBREVDAYNAME4 17
+#define CAL_SABBREVDAYNAME5 18
+#define CAL_SABBREVDAYNAME6 19
+#define CAL_SABBREVDAYNAME7 20
+#define CAL_SMONTHNAME1 21
+#define CAL_SMONTHNAME2 22
+#define CAL_SMONTHNAME3 23
+#define CAL_SMONTHNAME4 24
+#define CAL_SMONTHNAME5 25
+#define CAL_SMONTHNAME6 26
+#define CAL_SMONTHNAME7 27
+#define CAL_SMONTHNAME8 28
+#define CAL_SMONTHNAME9 29
+#define CAL_SMONTHNAME10 30
+#define CAL_SMONTHNAME11 31
+#define CAL_SMONTHNAME12 32
+#define CAL_SMONTHNAME13 33
+#define CAL_SABBREVMONTHNAME1 34
+#define CAL_SABBREVMONTHNAME2 35
+#define CAL_SABBREVMONTHNAME3 36
+#define CAL_SABBREVMONTHNAME4 37
+#define CAL_SABBREVMONTHNAME5 38
+#define CAL_SABBREVMONTHNAME6 39
+#define CAL_SABBREVMONTHNAME7 40
+#define CAL_SABBREVMONTHNAME8 41
+#define CAL_SABBREVMONTHNAME9 42
+#define CAL_SABBREVMONTHNAME10 43
+#define CAL_SABBREVMONTHNAME11 44
+#define CAL_SABBREVMONTHNAME12 45
+#define CAL_SABBREVMONTHNAME13 46
+#define CAL_GREGORIAN 1
+#define CAL_GREGORIAN_US 2
+#define CAL_JAPAN 3
+#define CAL_TAIWAN 4
+#define CAL_KOREA 5
+#define CAL_HIJRI 6
+#define CAL_THAI 7
+#define CAL_HEBREW 8
+#define CAL_GREGORIAN_ME_FRENCH 9
+#define CAL_GREGORIAN_ARABIC 10
+#define CAL_GREGORIAN_XLIT_ENGLISH 11
+#define CAL_GREGORIAN_XLIT_FRENCH 12
+#define CSTR_LESS_THAN 1
+#define CSTR_EQUAL 2
+#define CSTR_GREATER_THAN 3
+#define LGRPID_INSTALLED 1
+#define LGRPID_SUPPORTED 2
+#define LGRPID_WESTERN_EUROPE 1
+#define LGRPID_CENTRAL_EUROPE 2
+#define LGRPID_BALTIC 3
+#define LGRPID_GREEK 4
+#define LGRPID_CYRILLIC 5
+#define LGRPID_TURKISH 6
+#define LGRPID_JAPANESE 7
+#define LGRPID_KOREAN 8
+#define LGRPID_TRADITIONAL_CHINESE 9
+#define LGRPID_SIMPLIFIED_CHINESE 10
+#define LGRPID_THAI 11
+#define LGRPID_HEBREW 12
+#define LGRPID_ARABIC 13
+#define LGRPID_VIETNAMESE 14
+#define LGRPID_INDIC 15
+#define LGRPID_GEORGIAN 16
+#define LGRPID_ARMENIAN 17
+
+#if(WINVER >= 0x0500)
+#define LOCALE_SYEARMONTH 0x1006
+#define LOCALE_SENGCURRNAME 0x1007
+#define LOCALE_SNATIVECURRNAME 0x1008
+#define LOCALE_IDEFAULTEBCDICCODEPAGE 0x1012
+#define LOCALE_SSORTNAME 0x1013
+#define LOCALE_IDIGITSUBSTITUTION 0x1014
+#define LOCALE_IPAPERSIZE 0x100A
+#define DATE_YEARMONTH 8
+#define DATE_LTRREADING 16
+#define DATE_RTLREADING 32
+#define MAP_EXPAND_LIGATURES   0x2000
+#define WC_NO_BEST_FIT_CHARS 1024
+#define CAL_SYEARMONTH 47
+#define CAL_ITWODIGITYEARMAX 48
+#define CAL_NOUSEROVERRIDE LOCALE_NOUSEROVERRIDE
+#define CAL_RETURN_NUMBER LOCALE_RETURN_NUMBER
+#define CAL_USE_CP_ACP LOCALE_USE_CP_ACP
+#endif /* WINVER >= 0x0500 */
+#ifndef  _BASETSD_H
+typedef long LONG_PTR;
+#endif 
+
+#ifndef RC_INVOKED
+typedef DWORD LCTYPE;
+typedef DWORD CALTYPE;
+typedef DWORD CALID;
+typedef DWORD LGRPID;
+typedef BOOL (CALLBACK *CALINFO_ENUMPROCA)(LPSTR);
+typedef BOOL (CALLBACK *CALINFO_ENUMPROCW)(LPWSTR);
+typedef BOOL (CALLBACK* CALINFO_ENUMPROCEXA)(LPSTR, CALID);
+typedef BOOL (CALLBACK* CALINFO_ENUMPROCEXW)(LPWSTR, CALID);
+typedef BOOL (CALLBACK* LANGUAGEGROUP_ENUMPROCA)(LGRPID, LPSTR, LPSTR, DWORD, LONG_PTR);
+typedef BOOL (CALLBACK* LANGUAGEGROUP_ENUMPROCW)(LGRPID, LPWSTR, LPWSTR, DWORD, LONG_PTR);
+typedef BOOL (CALLBACK* LANGGROUPLOCALE_ENUMPROCA)(LGRPID, LCID, LPSTR, LONG_PTR);
+typedef BOOL (CALLBACK* LANGGROUPLOCALE_ENUMPROCW)(LGRPID, LCID, LPWSTR, LONG_PTR);
+typedef BOOL (CALLBACK* UILANGUAGE_ENUMPROCW)(LPWSTR, LONG_PTR);
+typedef BOOL (CALLBACK* UILANGUAGE_ENUMPROCA)(LPSTR, LONG_PTR);
+typedef BOOL (CALLBACK *LOCALE_ENUMPROCA)(LPSTR);
+typedef BOOL (CALLBACK *LOCALE_ENUMPROCW)(LPWSTR);
+typedef BOOL (CALLBACK *CODEPAGE_ENUMPROCA)(LPSTR);
+typedef BOOL (CALLBACK *CODEPAGE_ENUMPROCW)(LPWSTR);
+typedef BOOL (CALLBACK *DATEFMT_ENUMPROCA)(LPSTR);
+typedef BOOL (CALLBACK *DATEFMT_ENUMPROCW)(LPWSTR);
+typedef BOOL (CALLBACK* DATEFMT_ENUMPROCEXA)(LPSTR, CALID);
+typedef BOOL (CALLBACK* DATEFMT_ENUMPROCEXW)(LPWSTR, CALID);
+typedef BOOL (CALLBACK *TIMEFMT_ENUMPROCA)(LPSTR);
+typedef BOOL (CALLBACK *TIMEFMT_ENUMPROCW)(LPWSTR);
+
+typedef struct _cpinfo {
+	UINT MaxCharSize;
+	BYTE DefaultChar[MAX_DEFAULTCHAR];
+	BYTE LeadByte[MAX_LEADBYTES];
+} CPINFO,*LPCPINFO;
+typedef struct _cpinfoexA {
+    UINT MaxCharSize;
+    BYTE DefaultChar[MAX_DEFAULTCHAR];
+    BYTE LeadByte[MAX_LEADBYTES];
+    WCHAR UnicodeDefaultChar;
+    UINT CodePage;
+    CHAR CodePageName[MAX_PATH];
+} CPINFOEXA, *LPCPINFOEXA;
+typedef struct _cpinfoexW {
+    UINT MaxCharSize;
+    BYTE DefaultChar[MAX_DEFAULTCHAR];
+    BYTE LeadByte[MAX_LEADBYTES];
+    WCHAR UnicodeDefaultChar;
+    UINT CodePage;
+    WCHAR CodePageName[MAX_PATH];
+} CPINFOEXW, *LPCPINFOEXW;
+typedef struct _currencyfmtA {
+	UINT NumDigits;
+	UINT LeadingZero;
+	UINT Grouping;
+	LPSTR lpDecimalSep;
+	LPSTR lpThousandSep;
+	UINT NegativeOrder;
+	UINT PositiveOrder;
+	LPSTR lpCurrencySymbol;
+} CURRENCYFMTA, *LPCURRENCYFMTA;
+typedef struct _currencyfmtW {
+	UINT NumDigits;
+	UINT LeadingZero;
+	UINT Grouping;
+	LPWSTR lpDecimalSep;
+	LPWSTR lpThousandSep;
+	UINT NegativeOrder;
+	UINT PositiveOrder;
+	LPWSTR lpCurrencySymbol;
+} CURRENCYFMTW, *LPCURRENCYFMTW;
+typedef struct _numberfmtA {
+	UINT NumDigits;
+	UINT LeadingZero;
+	UINT Grouping;
+	LPSTR lpDecimalSep;
+	LPSTR lpThousandSep;
+	UINT NegativeOrder;
+} NUMBERFMTA, *LPNUMBERFMTA;
+typedef struct _numberfmtW {
+	UINT NumDigits;
+	UINT LeadingZero;
+	UINT Grouping;
+	LPWSTR lpDecimalSep;
+	LPWSTR lpThousandSep;
+	UINT NegativeOrder;
+} NUMBERFMTW, *LPNUMBERFMTW;
+
+int WINAPI CompareStringA(LCID,DWORD,LPCSTR,int,LPCSTR,int);
+int WINAPI CompareStringW(LCID,DWORD,LPCWSTR,int,LPCWSTR,int);
+LCID WINAPI ConvertDefaultLocale(LCID);
+BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA,LCID,CALID,CALTYPE);
+BOOL WINAPI EnumCalendarInfoW(CALINFO_ENUMPROCW,LCID,CALID,CALTYPE);
+BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA,LCID,DWORD);
+BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW,LCID,DWORD);
+BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA,DWORD);
+BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW,DWORD);
+BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD);
+BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD);
+BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA,LCID,DWORD);
+BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW,LCID,DWORD);
+int WINAPI FoldStringA(DWORD,LPCSTR,int,LPSTR,int);
+int WINAPI FoldStringW(DWORD,LPCWSTR,int,LPWSTR,int);
+UINT WINAPI GetACP(void);
+BOOL WINAPI GetCPInfo(UINT,LPCPINFO);
+BOOL WINAPI GetCPInfoExA(UINT,DWORD,LPCPINFOEXA);
+BOOL WINAPI GetCPInfoExW(UINT,DWORD,LPCPINFOEXW);
+int WINAPI GetCurrencyFormatA(LCID,DWORD,LPCSTR,const CURRENCYFMTA*,LPSTR,int);
+int WINAPI GetCurrencyFormatW(LCID,DWORD,LPCWSTR,const CURRENCYFMTW*,LPWSTR,int);
+int WINAPI GetDateFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,int);
+int WINAPI GetDateFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,int);
+int WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,int);
+int WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,int);
+int WINAPI GetNumberFormatA(LCID,DWORD,LPCSTR,const NUMBERFMTA*,LPSTR,int);
+int WINAPI GetNumberFormatW(LCID,DWORD,LPCWSTR,const NUMBERFMTW*,LPWSTR,int);
+UINT WINAPI GetOEMCP(void);
+BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,int,LPWORD);
+BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,int,LPWORD);
+BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,int,LPWORD);
+BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,int,LPWORD);
+LANGID WINAPI GetSystemDefaultLangID(void);
+LCID WINAPI GetSystemDefaultLCID(void);
+LCID WINAPI GetThreadLocale(void);
+int WINAPI GetTimeFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,int);
+int WINAPI GetTimeFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,int);
+LANGID WINAPI GetUserDefaultLangID(void);
+LCID WINAPI GetUserDefaultLCID(void);
+BOOL WINAPI IsDBCSLeadByte(BYTE);
+BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE);
+BOOL WINAPI IsValidCodePage(UINT);
+BOOL WINAPI IsValidLocale(LCID,DWORD);
+int WINAPI LCMapStringA(LCID,DWORD,LPCSTR,int,LPSTR,int);
+int WINAPI LCMapStringW(LCID,DWORD,LPCWSTR,int,LPWSTR,int);
+int WINAPI MultiByteToWideChar(UINT,DWORD,LPCSTR,int,LPWSTR,int);
+BOOL WINAPI SetLocaleInfoA(LCID,LCTYPE,LPCSTR);
+BOOL WINAPI SetLocaleInfoW(LCID,LCTYPE,LPCWSTR);
+BOOL WINAPI SetThreadLocale(LCID);
+int WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
+#if (WINVER >= 0x0500)
+BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA,LCID,CALID,CALTYPE);
+BOOL WINAPI EnumCalendarInfoExW(CALINFO_ENUMPROCEXW,LCID,CALID,CALTYPE);
+BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA,LCID,DWORD);
+BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW,LCID,DWORD);
+BOOL WINAPI EnumSystemLanguageGroupsA(LANGUAGEGROUP_ENUMPROCA,DWORD,LONG_PTR);
+BOOL WINAPI EnumSystemLanguageGroupsW(LANGUAGEGROUP_ENUMPROCW,DWORD,LONG_PTR);
+BOOL WINAPI EnumLanguageGroupLocalesA(LANGGROUPLOCALE_ENUMPROCA,LGRPID,DWORD,LONG_PTR);
+BOOL WINAPI EnumLanguageGroupLocalesW(LANGGROUPLOCALE_ENUMPROCW,LGRPID,DWORD,LONG_PTR);
+BOOL WINAPI EnumUILanguagesA(UILANGUAGE_ENUMPROCA,DWORD,LONG_PTR);
+BOOL WINAPI EnumUILanguagesW(UILANGUAGE_ENUMPROCW,DWORD,LONG_PTR);
+LANGID WINAPI GetSystemDefaultUILanguage(void);
+LANGID WINAPI GetUserDefaultUILanguage(void);
+BOOL WINAPI IsValidLanguageGroup(LGRPID,DWORD);
+#endif /* (WINVER >= 0x0500) */
+
+#ifdef UNICODE
+#define CALINFO_ENUMPROC CALINFO_ENUMPROCW
+#define CALINFO_ENUMPROCEX CALINFO_ENUMPROCEXW
+#define LOCALE_ENUMPROC LOCALE_ENUMPROCW
+#define CODEPAGE_ENUMPROC CODEPAGE_ENUMPROCW
+#define DATEFMT_ENUMPROC DATEFMT_ENUMPROCW
+#define DATEFMT_ENUMPROCEX DATEFMT_ENUMPROCEXW
+#define TIMEFMT_ENUMPROC TIMEFMT_ENUMPROCW
+#define LANGUAGEGROUP_ENUMPROC LANGUAGEGROUP_ENUMPROCW
+#define LANGGROUPLOCALE_ENUMPROC LANGGROUPLOCALE_ENUMPROCW
+#define UILANGUAGE_ENUMPROC UILANGUAGE_ENUMPROCW
+typedef CPINFOEXW CPINFOEX;
+typedef LPCPINFOEXW LPCPINFOEX;
+typedef CURRENCYFMTW CURRENCYFMT;
+typedef LPCURRENCYFMTW LPCURRENCYFMT;
+typedef NUMBERFMTW NUMBERFMT;
+typedef LPNUMBERFMTW LPNUMBERFMT;
+#define CompareString CompareStringW
+#define EnumCalendarInfo EnumCalendarInfoW
+#define EnumSystemCodePages EnumSystemCodePagesW
+#define EnumSystemLocales EnumSystemLocalesW
+#define EnumTimeFormats EnumTimeFormatsW
+#define FoldString FoldStringW
+#define GetCPInfoEx GetCPInfoExW
+#define GetCurrencyFormat GetCurrencyFormatW
+#define GetDateFormat GetDateFormatW
+#define GetLocaleInfo GetLocaleInfoW
+#define GetNumberFormat GetNumberFormatW
+#define GetStringTypeEx GetStringTypeExW
+#define GetTimeFormat GetTimeFormatW
+#define LCMapString LCMapStringW
+#define SetLocaleInfo SetLocaleInfoW
+#if (WINVER >= 0x0500)
+#define EnumCalendarInfoEx EnumCalendarInfoExW;
+#define EnumDateFormatsEx EnumDateFormatsExW;
+#define EnumSystemLanguageGroups EnumSystemLanguageGroupsW;
+#define EnumLanguageGroupLocales EnumLanguageGroupLocalesW;
+#define EnumUILanguages EnumUILanguagesW;
+#endif /* (WINVER >= 0x0500) */
+#else
+#define CALINFO_ENUMPROC CALINFO_ENUMPROCA
+#define CALINFO_ENUMPROCEX CALINFO_ENUMPROCEXA
+#define LOCALE_ENUMPROC LOCALE_ENUMPROCA
+#define CODEPAGE_ENUMPROC CODEPAGE_ENUMPROCA
+#define DATEFMT_ENUMPROC DATEFMT_ENUMPROCA
+#define DATEFMT_ENUMPROCEX DATEFMT_ENUMPROCEXA
+#define TIMEFMT_ENUMPROC TIMEFMT_ENUMPROCA
+#define LANGUAGEGROUP_ENUMPROC LANGUAGEGROUP_ENUMPROCA
+#define LANGGROUPLOCALE_ENUMPROC LANGGROUPLOCALE_ENUMPROCA
+#define UILANGUAGE_ENUMPROC UILANGUAGE_ENUMPROCA
+typedef CPINFOEXA CPINFOEX;
+typedef LPCPINFOEXA LPCPINFOEX;
+typedef CURRENCYFMTA CURRENCYFMT;
+typedef LPCURRENCYFMTA LPCURRENCYFMT;
+typedef NUMBERFMTA NUMBERFMT;
+typedef LPNUMBERFMTA LPNUMBERFMT;
+#define CompareString CompareStringA
+#define EnumCalendarInfo EnumCalendarInfoA
+#define EnumSystemCodePages EnumSystemCodePagesA
+#define EnumSystemLocales EnumSystemLocalesA
+#define EnumTimeFormats EnumTimeFormatsA
+#define FoldString FoldStringA
+#define GetCPInfoEx GetCPInfoExA
+#define GetCurrencyFormat GetCurrencyFormatA
+#define GetDateFormat GetDateFormatA
+#define GetLocaleInfo GetLocaleInfoA
+#define GetNumberFormat GetNumberFormatA
+#define GetStringTypeEx GetStringTypeExA
+#define GetTimeFormat GetTimeFormatA
+#define LCMapString LCMapStringA
+#define SetLocaleInfo SetLocaleInfoA
+#if (WINVER >= 0x0500)
+#define EnumCalendarInfoEx EnumCalendarInfoExA;
+#define EnumDateFormatsEx EnumDateFormatsExA;
+#define EnumSystemLanguageGroups EnumSystemLanguageGroupsA;
+#define EnumLanguageGroupLocales EnumLanguageGroupLocalesA;
+#define EnumUILanguages EnumUILanguagesA;
+#endif /* (WINVER >= 0x0500) */
+#endif /* UNICODE */
+#endif /* RC_INVOKED */
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/winnt.h b/tinyc/win32/include/winapi/winnt.h
new file mode 100755
index 000000000..810d99158
--- /dev/null
+++ b/tinyc/win32/include/winapi/winnt.h
@@ -0,0 +1,2667 @@
+#ifndef _WINNT_H
+#define _WINNT_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+/* translate GCC target defines to MS equivalents. Keep this synchronized
+   with windows.h. */
+#if defined(__i686__) && !defined(_M_IX86)
+#define _M_IX86 600
+#elif defined(__i586__) && !defined(_M_IX86)
+#define _M_IX86 500
+#elif defined(__i486__) && !defined(_M_IX86)
+#define _M_IX86 400
+#elif defined(__i386__) && !defined(_M_IX86)
+#define _M_IX86 300
+#endif
+#if defined(_M_IX86) && !defined(_X86_)
+#define _X86_
+#elif defined(_M_ALPHA) && !defined(_ALPHA_)
+#define _ALPHA_
+#elif defined(_M_PPC) && !defined(_PPC_)
+#define _PPC_
+#elif defined(_M_MRX000) && !defined(_MIPS_)
+#define _MIPS_
+#elif defined(_M_M68K) && !defined(_68K_)
+#define _68K_
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <winerror.h>
+
+#ifndef RC_INVOKED
+#include <string.h>
+
+/* FIXME: add more architectures. Is there a way to specify this in GCC? */
+#ifdef _X86_
+#define UNALIGNED
+#else
+#define UNALIGNED
+#endif
+
+#ifndef VOID
+#define VOID void
+#endif
+typedef char CHAR;
+typedef short SHORT;
+typedef long LONG;
+typedef CHAR CCHAR;
+typedef unsigned char UCHAR,*PUCHAR;
+typedef unsigned short USHORT,*PUSHORT;
+typedef unsigned long ULONG,*PULONG;
+typedef char *PSZ;
+
+#ifndef _WCHAR_T_DEFINED
+#define _WCHAR_T_DEFINED
+#ifndef _WCHAR_T_
+#define _WCHAR_T_
+#undef __need_wchar_t
+#ifndef __cplusplus
+typedef unsigned short wchar_t;
+#endif
+#endif
+#endif
+
+typedef wchar_t WCHAR;
+typedef WCHAR *PWCHAR,*LPWCH,*PWCH,*NWPSTR,*LPWSTR,*PWSTR;
+typedef CONST WCHAR *LPCWCH,*PCWCH,*LPCWSTR,*PCWSTR;
+typedef CHAR *PCHAR,*LPCH,*PCH,*NPSTR,*LPSTR,*PSTR;
+typedef CONST CHAR *LPCCH,*PCSTR,*LPCSTR;
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+#ifdef UNICODE
+/*
+ * NOTE: This tests UNICODE, which is different from the _UNICODE define
+ *       used to differentiate standard C runtime calls.
+ */
+typedef WCHAR TCHAR;
+typedef WCHAR _TCHAR;
+#else
+typedef CHAR TCHAR;
+typedef CHAR _TCHAR;
+#endif
+#endif
+typedef TCHAR TBYTE,*PTCH,*PTBYTE;
+typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR;
+typedef const TCHAR *LPCTSTR;
+#ifdef UNICODE
+/*
+ * __TEXT is a private macro whose specific use is to force the expansion of a
+ * macro passed as an argument to the macro TEXT.  DO NOT use this
+ * macro within your programs.  It's name and function could change without
+ * notice.
+ */
+#define __TEXT(q) L##q
+#else
+#define __TEXT(q) q
+#endif
+/*
+ * UNICODE a constant string when UNICODE is defined, else returns the string
+ * unmodified.
+ * The corresponding macros  _TEXT() and _T() for mapping _UNICODE strings
+ * passed to C runtime functions are defined in mingw/tchar.h
+ */
+#define TEXT(q) __TEXT(q)    
+typedef SHORT *PSHORT;
+typedef LONG *PLONG;
+typedef void *HANDLE;
+typedef HANDLE *PHANDLE,*LPHANDLE;
+#ifdef STRICT
+#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n
+#else
+#define DECLARE_HANDLE(n) typedef HANDLE n
+#endif
+typedef DWORD LCID;
+typedef PDWORD PLCID;
+typedef WORD LANGID;
+#ifdef __GNUC__
+#define _HAVE_INT64
+#define _INTEGRAL_MAX_BITS 64
+#undef __int64
+#define __int64 long long
+#elif defined(__WATCOMC__) && (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 )
+#define _HAVE_INT64
+#endif /* __GNUC__/__WATCOMC */
+#if defined(_HAVE_INT64) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)
+typedef __int64 LONGLONG;
+typedef unsigned __int64 DWORDLONG;
+#else
+typedef double LONGLONG,DWORDLONG;
+#endif
+typedef LONGLONG *PLONGLONG;
+typedef DWORDLONG *PDWORDLONG;
+typedef DWORDLONG ULONGLONG,*PULONGLONG;
+typedef LONGLONG USN;
+#ifdef _HAVE_INT64
+#define Int32x32To64(a,b) ((LONGLONG)(a)*(LONGLONG)(b))
+#define UInt32x32To64(a,b) ((DWORDLONG)(a)*(DWORDLONG)(b))
+#define Int64ShllMod32(a,b) ((DWORDLONG)(a)<<(b))
+#define Int64ShraMod32(a,b) ((LONGLONG)(a)>>(b))
+#define Int64ShrlMod32(a,b) ((DWORDLONG)(a)>>(b))
+#endif
+#define ANSI_NULL '\0'
+#define UNICODE_NULL L'\0'
+typedef BYTE BOOLEAN,*PBOOLEAN;
+#endif
+
+#define NTAPI __stdcall
+#include <basetsd.h>
+#define APPLICATION_ERROR_MASK       0x20000000
+#define ERROR_SEVERITY_SUCCESS       0x00000000
+#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
+#define ERROR_SEVERITY_WARNING       0x80000000
+#define ERROR_SEVERITY_ERROR         0xC0000000
+#define COMPRESSION_FORMAT_NONE 0
+#define COMPRESSION_FORMAT_DEFAULT 1
+#define COMPRESSION_FORMAT_LZNT1 2
+#define COMPRESSION_ENGINE_STANDARD 0
+#define COMPRESSION_ENGINE_MAXIMUM 256
+#define ACCESS_ALLOWED_ACE_TYPE	0
+#define ACCESS_DENIED_ACE_TYPE	1
+#define ANYSIZE_ARRAY 1
+#define SYSTEM_AUDIT_ACE_TYPE	2
+#define SYSTEM_ALARM_ACE_TYPE	3
+#define OBJECT_INHERIT_ACE	1
+#define CONTAINER_INHERIT_ACE	2
+#define NO_PROPAGATE_INHERIT_ACE	4
+#define INHERIT_ONLY_ACE	8
+#define VALID_INHERIT_FLAGS	16
+#define SUCCESSFUL_ACCESS_ACE_FLAG	64
+#define FAILED_ACCESS_ACE_FLAG	128
+#define DELETE	0x00010000L
+#define READ_CONTROL	0x20000L
+#define WRITE_DAC	0x40000L
+#define WRITE_OWNER	0x80000L
+#define SYNCHRONIZE	0x100000L
+#define STANDARD_RIGHTS_REQUIRED	0xF0000
+#define STANDARD_RIGHTS_READ	0x20000
+#define STANDARD_RIGHTS_WRITE	0x20000
+#define STANDARD_RIGHTS_EXECUTE	0x20000
+#define STANDARD_RIGHTS_ALL	0x1F0000
+#define SPECIFIC_RIGHTS_ALL	0xFFFF
+#define ACCESS_SYSTEM_SECURITY	0x1000000
+#define MAXIMUM_ALLOWED	0x2000000
+#define GENERIC_READ	0x80000000
+#define GENERIC_WRITE	0x40000000
+#define GENERIC_EXECUTE	0x20000000
+#define GENERIC_ALL	0x10000000
+#define FILE_READ_DATA	1
+#define FILE_LIST_DIRECTORY	1
+#define FILE_WRITE_DATA	2
+#define FILE_ADD_FILE	2
+#define FILE_APPEND_DATA	4
+#define FILE_ADD_SUBDIRECTORY	4
+#define FILE_CREATE_PIPE_INSTANCE	4
+#define FILE_READ_EA	8
+#define FILE_READ_PROPERTIES	8
+#define FILE_WRITE_EA	16
+#define FILE_WRITE_PROPERTIES	16
+#define FILE_EXECUTE	32
+#define FILE_TRAVERSE	32
+#define FILE_DELETE_CHILD	64
+#define FILE_READ_ATTRIBUTES	128
+#define FILE_WRITE_ATTRIBUTES	256
+#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1FF)
+#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ|FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA|SYNCHRONIZE)
+#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE)
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE|FILE_READ_ATTRIBUTES|FILE_EXECUTE|SYNCHRONIZE)
+#define FILE_SHARE_READ	1
+#define FILE_SHARE_WRITE 2
+#define FILE_SHARE_DELETE 4
+#define FILE_ATTRIBUTE_READONLY	1
+#define FILE_ATTRIBUTE_HIDDEN	2
+#define FILE_ATTRIBUTE_SYSTEM	4
+#define FILE_ATTRIBUTE_DIRECTORY	16
+#define FILE_ATTRIBUTE_ARCHIVE	32
+#define FILE_ATTRIBUTE_DEVICE	64
+#define FILE_ATTRIBUTE_NORMAL	128
+#define FILE_ATTRIBUTE_TEMPORARY	256
+#define FILE_ATTRIBUTE_SPARSE_FILE	512
+#define FILE_ATTRIBUTE_REPARSE_POINT	1024
+#define FILE_ATTRIBUTE_COMPRESSED	2048
+#define FILE_ATTRIBUTE_OFFLINE	0x1000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED	0x2000
+#define FILE_ATTRIBUTE_ENCRYPTED	0x4000
+#define INVALID_FILE_ATTRIBUTES	((DWORD)-1)
+#define FILE_NOTIFY_CHANGE_FILE_NAME	1
+#define FILE_NOTIFY_CHANGE_DIR_NAME	2
+#define FILE_NOTIFY_CHANGE_ATTRIBUTES	4
+#define FILE_NOTIFY_CHANGE_SIZE	8
+#define FILE_NOTIFY_CHANGE_LAST_WRITE	16
+#define FILE_NOTIFY_CHANGE_LAST_ACCESS  32
+#define FILE_NOTIFY_CHANGE_CREATION	64
+#define FILE_NOTIFY_CHANGE_SECURITY	256
+#define MAILSLOT_NO_MESSAGE	((DWORD)-1)
+#define MAILSLOT_WAIT_FOREVER	((DWORD)-1)
+#define FILE_CASE_SENSITIVE_SEARCH	1
+#define FILE_CASE_PRESERVED_NAMES	2
+#define FILE_UNICODE_ON_DISK	4
+#define FILE_PERSISTENT_ACLS	8
+#define FILE_FILE_COMPRESSION	16
+#define FILE_VOLUME_QUOTAS      32
+#define FILE_SUPPORTS_SPARSE_FILES      64
+#define FILE_SUPPORTS_REPARSE_POINTS    128
+#define FILE_SUPPORTS_REMOTE_STORAGE    256
+#define FILE_VOLUME_IS_COMPRESSED	0x8000
+#define FILE_SUPPORTS_OBJECT_IDS        0x10000  
+#define FILE_SUPPORTS_ENCRYPTION        0x20000  
+#define FILE_NAMED_STREAMS              0x40000
+#define IO_COMPLETION_MODIFY_STATE	2
+#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|3)
+#define DUPLICATE_CLOSE_SOURCE	1
+#define DUPLICATE_SAME_ACCESS	2
+#define PROCESS_TERMINATE	1
+#define PROCESS_CREATE_THREAD	2
+#define PROCESS_VM_OPERATION	8
+#define PROCESS_VM_READ	16
+#define PROCESS_VM_WRITE	32
+#define PROCESS_DUP_HANDLE	64
+#define PROCESS_CREATE_PROCESS	128
+#define PROCESS_SET_QUOTA	256
+#define PROCESS_SET_INFORMATION	512
+#define PROCESS_QUERY_INFORMATION	1024
+#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xFFF)
+#define THREAD_TERMINATE	1
+#define THREAD_SUSPEND_RESUME	2
+#define THREAD_GET_CONTEXT	8
+#define THREAD_SET_CONTEXT	16
+#define THREAD_SET_INFORMATION	32
+#define THREAD_QUERY_INFORMATION	64
+#define THREAD_SET_THREAD_TOKEN	128
+#define THREAD_IMPERSONATE	256
+#define THREAD_DIRECT_IMPERSONATION	0x200
+#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF)
+#define EXCEPTION_NONCONTINUABLE	1
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+/*
+ * To prevent gcc compiler warnings, bracket these defines when initialising
+ * a  SID_IDENTIFIER_AUTHORITY, eg.
+ * SID_IDENTIFIER_AUTHORITY aNullSidAuthority = {SECURITY_NULL_SID_AUTHORITY};
+ */
+#define SECURITY_NULL_SID_AUTHORITY	{0,0,0,0,0,0}
+#define SECURITY_WORLD_SID_AUTHORITY	{0,0,0,0,0,1}
+#define SECURITY_LOCAL_SID_AUTHORITY	{0,0,0,0,0,2}
+#define SECURITY_CREATOR_SID_AUTHORITY	{0,0,0,0,0,3}
+#define SECURITY_NON_UNIQUE_AUTHORITY	{0,0,0,0,0,4}
+#define SECURITY_NT_AUTHORITY	{0,0,0,0,0,5}
+#define SECURITY_NULL_RID	0
+#define SECURITY_WORLD_RID	0
+#define SECURITY_LOCAL_RID	0
+#define SECURITY_CREATOR_OWNER_RID	0
+#define SECURITY_CREATOR_GROUP_RID	1
+#define SECURITY_DIALUP_RID	1
+#define SECURITY_NETWORK_RID	2
+#define SECURITY_BATCH_RID	3
+#define SECURITY_INTERACTIVE_RID	4
+#define SECURITY_LOGON_IDS_RID	5
+#define SECURITY_SERVICE_RID	6
+#define SECURITY_LOCAL_SYSTEM_RID	18
+#define SECURITY_BUILTIN_DOMAIN_RID   32
+#define SECURITY_PRINCIPAL_SELF_RID   10
+#define SID_REVISION 1
+#define DOMAIN_USER_RID_ADMIN 0x1F4L
+#define DOMAIN_USER_RID_GUEST 0x1F5L
+#define DOMAIN_GROUP_RID_ADMINS	0x200L
+#define DOMAIN_GROUP_RID_USERS	0x201L
+#define DOMAIN_ALIAS_RID_ADMINS	0x220L
+#define DOMAIN_ALIAS_RID_USERS	0x221L
+#define DOMAIN_ALIAS_RID_GUESTS	0x222L
+#define DOMAIN_ALIAS_RID_POWER_USERS	0x223L
+#define DOMAIN_ALIAS_RID_ACCOUNT_OPS	0x224L
+#define DOMAIN_ALIAS_RID_SYSTEM_OPS	0x225L
+#define DOMAIN_ALIAS_RID_PRINT_OPS	0x226L
+#define DOMAIN_ALIAS_RID_BACKUP_OPS	0x227L
+#define DOMAIN_ALIAS_RID_REPLICATOR	0x228L
+#define SE_CREATE_TOKEN_NAME	TEXT("SeCreateTokenPrivilege")
+#define SE_ASSIGNPRIMARYTOKEN_NAME	TEXT("SeAssignPrimaryTokenPrivilege")
+#define SE_LOCK_MEMORY_NAME	TEXT("SeLockMemoryPrivilege")
+#define SE_INCREASE_QUOTA_NAME	TEXT("SeIncreaseQuotaPrivilege")
+#define SE_UNSOLICITED_INPUT_NAME	TEXT("SeUnsolicitedInputPrivilege")
+#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
+#define SE_TCB_NAME	TEXT("SeTcbPrivilege")
+#define SE_SECURITY_NAME	TEXT("SeSecurityPrivilege")
+#define SE_TAKE_OWNERSHIP_NAME	TEXT("SeTakeOwnershipPrivilege")
+#define SE_LOAD_DRIVER_NAME	TEXT("SeLoadDriverPrivilege")
+#define SE_SYSTEM_PROFILE_NAME	TEXT("SeSystemProfilePrivilege")
+#define SE_SYSTEMTIME_NAME	TEXT("SeSystemtimePrivilege")
+#define SE_PROF_SINGLE_PROCESS_NAME	TEXT("SeProfileSingleProcessPrivilege")
+#define SE_INC_BASE_PRIORITY_NAME	TEXT("SeIncreaseBasePriorityPrivilege")
+#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
+#define SE_CREATE_PERMANENT_NAME	TEXT("SeCreatePermanentPrivilege")
+#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
+#define SE_RESTORE_NAME	TEXT("SeRestorePrivilege")
+#define SE_SHUTDOWN_NAME	TEXT("SeShutdownPrivilege")
+#define SE_DEBUG_NAME	TEXT("SeDebugPrivilege")
+#define SE_AUDIT_NAME	TEXT("SeAuditPrivilege")
+#define SE_SYSTEM_ENVIRONMENT_NAME	TEXT("SeSystemEnvironmentPrivilege")
+#define SE_CHANGE_NOTIFY_NAME	TEXT("SeChangeNotifyPrivilege")
+#define SE_REMOTE_SHUTDOWN_NAME	TEXT("SeRemoteShutdownPrivilege")
+#define SE_GROUP_MANDATORY 1
+#define SE_GROUP_ENABLED_BY_DEFAULT 2
+#define SE_GROUP_ENABLED 4
+#define SE_GROUP_OWNER 8
+#define SE_GROUP_USE_FOR_DENY_ONLY 16
+#define SE_GROUP_LOGON_ID 3221225472U
+#define SE_GROUP_RESOURCE 536870912
+#define LANG_NEUTRAL	0x00
+#define LANG_ARABIC 	0x01
+#define LANG_BULGARIAN 	0x02
+#define LANG_CATALAN 	0x03
+#define LANG_CHINESE	0x04
+#define LANG_CZECH	0x05
+#define LANG_DANISH	0x06
+#define LANG_GERMAN	0x07
+#define LANG_GREEK	0x08
+#define LANG_ENGLISH	0x09
+#define LANG_SPANISH	0x0a
+#define LANG_FINNISH	0x0b
+#define LANG_FRENCH	0x0c
+#define LANG_HEBREW	0x0d
+#define LANG_HUNGARIAN	0x0e
+#define LANG_ICELANDIC	0x0f
+#define LANG_ITALIAN	0x10
+#define LANG_JAPANESE	0x11
+#define LANG_KOREAN	0x12
+#define LANG_DUTCH	0x13
+#define LANG_NORWEGIAN	0x14
+#define LANG_POLISH	0x15
+#define LANG_PORTUGUESE	0x16
+#define LANG_ROMANIAN	0x18
+#define LANG_RUSSIAN	0x19
+#define LANG_CROATIAN	0x1a
+#define LANG_SERBIAN	0x1a
+#define LANG_SLOVAK	0x1b
+#define LANG_ALBANIAN	0x1c
+#define LANG_SWEDISH	0x1d
+#define LANG_THAI	0x1e
+#define LANG_TURKISH	0x1f
+#define LANG_URDU	0x20
+#define LANG_INDONESIAN	0x21
+#define LANG_UKRAINIAN	0x22
+#define LANG_BELARUSIAN	0x23
+#define LANG_SLOVENIAN	0x24
+#define LANG_ESTONIAN	0x25
+#define LANG_LATVIAN	0x26
+#define LANG_LITHUANIAN	0x27
+#define LANG_FARSI	0x29
+#define LANG_VIETNAMESE	0x2a
+#define LANG_ARMENIAN	0x2b
+#define LANG_AZERI	0x2c
+#define LANG_BASQUE	0x2d
+#define LANG_MACEDONIAN	0x2f
+#define LANG_AFRIKAANS	0x36
+#define LANG_GEORGIAN	0x37
+#define LANG_FAEROESE	0x38
+#define LANG_HINDI	0x39
+#define LANG_MALAY	0x3e
+#define LANG_KAZAK	0x3f
+#define LANG_SWAHILI	0x41
+#define LANG_UZBEK	0x43
+#define LANG_TATAR	0x44
+#define LANG_BENGALI	0x45
+#define LANG_PUNJABI	0x46
+#define LANG_GUJARATI	0x47
+#define LANG_ORIYA	0x48
+#define LANG_TAMIL	0x49
+#define LANG_TELUGU	0x4a
+#define LANG_KANNADA	0x4b
+#define LANG_MALAYALAM	0x4c
+#define LANG_ASSAMESE	0x4d
+#define LANG_MARATHI	0x4e
+#define LANG_SANSKRIT	0x4f
+#define LANG_KONKANI	0x57
+#define LANG_MANIPURI	0x58
+#define LANG_SINDHI	0x59
+#define LANG_KASHMIRI	0x60
+#define LANG_NEPALI	0x61
+#define SUBLANG_NEUTRAL	0x00
+#define SUBLANG_DEFAULT	0x01
+#define SUBLANG_SYS_DEFAULT	0x02
+#define SUBLANG_ARABIC_SAUDI_ARABIA	0x01
+#define SUBLANG_ARABIC_IRAQ	0x02
+#define SUBLANG_ARABIC_EGYPT	0x03
+#define SUBLANG_ARABIC_LIBYA	0x04
+#define SUBLANG_ARABIC_ALGERIA	0x05
+#define SUBLANG_ARABIC_MOROCCO	0x06
+#define SUBLANG_ARABIC_TUNISIA	0x07
+#define SUBLANG_ARABIC_OMAN	0x08
+#define SUBLANG_ARABIC_YEMEN	0x09
+#define SUBLANG_ARABIC_SYRIA	0x0a
+#define SUBLANG_ARABIC_JORDAN	0x0b
+#define SUBLANG_ARABIC_LEBANON	0x0c
+#define SUBLANG_ARABIC_KUWAIT	0x0d
+#define SUBLANG_ARABIC_UAE	0x0e
+#define SUBLANG_ARABIC_BAHRAIN	0x0f
+#define SUBLANG_ARABIC_QATAR	0x10
+#define SUBLANG_AZERI_CYRILLIC	0x01
+#define SUBLANG_AZERI_LATIN	0x02
+#define SUBLANG_CHINESE_TRADITIONAL	0x01
+#define SUBLANG_CHINESE_SIMPLIFIED	0x02
+#define SUBLANG_CHINESE_HONGKONG	0x03
+#define SUBLANG_CHINESE_SINGAPORE	0x04
+#define SUBLANG_CHINESE_MACAU	0x05
+#define SUBLANG_DUTCH	0x01
+#define SUBLANG_DUTCH_BELGIAN	0x02
+#define SUBLANG_ENGLISH_US	0x01
+#define SUBLANG_ENGLISH_UK	0x02
+#define SUBLANG_ENGLISH_AUS	0x03
+#define SUBLANG_ENGLISH_CAN	0x04
+#define SUBLANG_ENGLISH_NZ	0x05
+#define SUBLANG_ENGLISH_EIRE	0x06
+#define SUBLANG_ENGLISH_SOUTH_AFRICA	0x07
+#define SUBLANG_ENGLISH_JAMAICA	0x08
+#define SUBLANG_ENGLISH_CARIBBEAN	0x09
+#define SUBLANG_ENGLISH_BELIZE	0x0a
+#define SUBLANG_ENGLISH_TRINIDAD	0x0b
+#define SUBLANG_ENGLISH_PHILIPPINES	0x0c
+#define SUBLANG_ENGLISH_ZIMBABWE	0x0d
+#define SUBLANG_FRENCH	0x01
+#define SUBLANG_FRENCH_BELGIAN	0x02
+#define SUBLANG_FRENCH_CANADIAN	0x03
+#define SUBLANG_FRENCH_SWISS	0x04
+#define SUBLANG_FRENCH_LUXEMBOURG	0x05
+#define SUBLANG_FRENCH_MONACO	0x06
+#define SUBLANG_GERMAN	0x01
+#define SUBLANG_GERMAN_SWISS	0x02
+#define SUBLANG_GERMAN_AUSTRIAN	0x03
+#define SUBLANG_GERMAN_LUXEMBOURG	0x04
+#define SUBLANG_GERMAN_LIECHTENSTEIN	0x05
+#define SUBLANG_ITALIAN	0x01
+#define SUBLANG_ITALIAN_SWISS	0x02
+#define SUBLANG_KASHMIRI_INDIA	0x02
+#define SUBLANG_KOREAN	0x01
+#define SUBLANG_LITHUANIAN	0x01
+#define SUBLANG_MALAY_MALAYSIA	0x01
+#define SUBLANG_MALAY_BRUNEI_DARUSSALAM	0x02
+#define SUBLANG_NEPALI_INDIA	0x02
+#define SUBLANG_NORWEGIAN_BOKMAL	0x01
+#define SUBLANG_NORWEGIAN_NYNORSK	0x02
+#define SUBLANG_PORTUGUESE	0x01
+#define SUBLANG_PORTUGUESE_BRAZILIAN	0x02
+#define SUBLANG_SERBIAN_LATIN	0x02
+#define SUBLANG_SERBIAN_CYRILLIC	0x03
+#define SUBLANG_SPANISH	0x01
+#define SUBLANG_SPANISH_MEXICAN	0x02
+#define SUBLANG_SPANISH_MODERN	0x03
+#define SUBLANG_SPANISH_GUATEMALA	0x04
+#define SUBLANG_SPANISH_COSTA_RICA	0x05
+#define SUBLANG_SPANISH_PANAMA	0x06
+#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC	0x07
+#define SUBLANG_SPANISH_VENEZUELA	0x08
+#define SUBLANG_SPANISH_COLOMBIA	0x09
+#define SUBLANG_SPANISH_PERU	0x0a
+#define SUBLANG_SPANISH_ARGENTINA	0x0b
+#define SUBLANG_SPANISH_ECUADOR	0x0c
+#define SUBLANG_SPANISH_CHILE	0x0d
+#define SUBLANG_SPANISH_URUGUAY	0x0e
+#define SUBLANG_SPANISH_PARAGUAY	0x0f
+#define SUBLANG_SPANISH_BOLIVIA	0x10
+#define SUBLANG_SPANISH_EL_SALVADOR	0x11
+#define SUBLANG_SPANISH_HONDURAS	0x12
+#define SUBLANG_SPANISH_NICARAGUA	0x13
+#define SUBLANG_SPANISH_PUERTO_RICO	0x14
+#define SUBLANG_SWEDISH	0x01
+#define SUBLANG_SWEDISH_FINLAND	0x02
+#define SUBLANG_URDU_PAKISTAN	0x01
+#define SUBLANG_URDU_INDIA	0x02
+#define SUBLANG_UZBEK_LATIN	0x01
+#define SUBLANG_UZBEK_CYRILLIC	0x02
+#define NLS_VALID_LOCALE_MASK	1048575
+#define SORT_DEFAULT	0
+#define SORT_JAPANESE_XJIS	0
+#define SORT_JAPANESE_UNICODE	1
+#define SORT_CHINESE_BIG5	0
+#define SORT_CHINESE_PRCP	0
+#define SORT_CHINESE_UNICODE	1
+#define SORT_CHINESE_PRC	2
+#define SORT_CHINESE_BOPOMOFO	3
+#define SORT_KOREAN_KSC	0
+#define SORT_KOREAN_UNICODE	1
+#define SORT_GERMAN_PHONE_BOOK	1
+#define SORT_HUNGARIAN_DEFAULT	0
+#define SORT_HUNGARIAN_TECHNICAL	1
+#define SORT_GEORGIAN_TRADITIONAL	0
+#define SORT_GEORGIAN_MODERN	1
+#define MAKELANGID(p,s)	((((WORD)(s))<<10)|(WORD)(p))
+#define MAKELCID(l,s) ((DWORD)((((DWORD)((WORD)(s)))<<16)|((DWORD)((WORD)(l)))))
+#define PRIMARYLANGID(l)	((WORD)(l)&0x3ff)
+#define SORTIDFROMLCID(l)	((WORD)((((DWORD)(l))&NLS_VALID_LOCALE_MASK)>>16))
+#define SORTVERSIONFROMLCID(l) ((WORD)((((DWORD)(l))>>20)&0xf))
+#define SUBLANGID(l)	((WORD)(l)>>10)
+#define LANGIDFROMLCID(l)	((WORD)(l))
+#define LANG_SYSTEM_DEFAULT	MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT)
+#define LANG_USER_DEFAULT	MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT)
+#define LOCALE_NEUTRAL	MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)
+#define ACL_REVISION	2
+#define ACL_REVISION_DS 4
+#define ACL_REVISION1 1
+#define ACL_REVISION2 2
+#define ACL_REVISION3 3
+#define ACL_REVISION4 4
+#define MIN_ACL_REVISION 2
+#define MAX_ACL_REVISION 4
+#define MINCHAR	0x80
+#define MAXCHAR	0x7f
+#define MINSHORT	0x8000
+#define MAXSHORT	0x7fff
+#define MINLONG	0x80000000
+#define MAXLONG	0x7fffffff
+#define MAXBYTE	0xff
+#define MAXWORD	0xffff
+#define MAXDWORD	0xffffffff
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_ARCHITECTURE_INTEL 0
+#define PROCESSOR_ARCHITECTURE_MIPS 1
+#define PROCESSOR_ARCHITECTURE_ALPHA 2
+#define PROCESSOR_ARCHITECTURE_PPC 3
+#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
+#define PF_FLOATING_POINT_PRECISION_ERRATA 0
+#define PF_FLOATING_POINT_EMULATED 1
+#define PF_COMPARE_EXCHANGE_DOUBLE 2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+#define PF_PPC_MOVEMEM_64BIT_OK 4
+#define PF_ALPHA_BYTE_INSTRUCTIONS 5
+#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
+#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
+#define PF_RDTSC_INSTRUCTION_AVAILABLE 8
+#define PF_PAE_ENABLED 9
+#define PAGE_READONLY 2
+#define PAGE_READWRITE 4
+#define PAGE_WRITECOPY 8
+#define FILE_ACTION_ADDED	1
+#define FILE_ACTION_REMOVED	2
+#define FILE_ACTION_MODIFIED	3
+#define FILE_ACTION_RENAMED_OLD_NAME	4
+#define FILE_ACTION_RENAMED_NEW_NAME	5
+#define HEAP_NO_SERIALIZE 1
+#define HEAP_GROWABLE 2
+#define HEAP_GENERATE_EXCEPTIONS 4
+#define HEAP_ZERO_MEMORY 8
+#define HEAP_REALLOC_IN_PLACE_ONLY 16
+#define HEAP_TAIL_CHECKING_ENABLED 32
+#define HEAP_FREE_CHECKING_ENABLED 64
+#define HEAP_DISABLE_COALESCE_ON_FREE 128
+#define HEAP_CREATE_ALIGN_16 0x0000
+#define HEAP_CREATE_ENABLE_TRACING 0x20000
+#define HEAP_MAXIMUM_TAG 0xFFF
+#define HEAP_PSEUDO_TAG_FLAG 0x8000
+#define HEAP_TAG_SHIFT 16
+#define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b)+(o)<<16)))
+#define KEY_QUERY_VALUE 1
+#define KEY_SET_VALUE 2
+#define KEY_CREATE_SUB_KEY 4
+#define KEY_ENUMERATE_SUB_KEYS 8
+#define KEY_NOTIFY 16
+#define KEY_CREATE_LINK 32
+#define KEY_WRITE 0x20006
+#define KEY_EXECUTE 0x20019
+#define KEY_READ 0x20019
+#define KEY_ALL_ACCESS 0xf003f
+#define REG_WHOLE_HIVE_VOLATILE	1
+#define REG_REFRESH_HIVE	2
+#define REG_NO_LAZY_FLUSH	4
+#define REG_OPTION_RESERVED	0
+#define REG_OPTION_NON_VOLATILE	0
+#define REG_OPTION_VOLATILE	1
+#define REG_OPTION_CREATE_LINK	2
+#define REG_OPTION_BACKUP_RESTORE	4
+#define REG_OPTION_OPEN_LINK	8
+#define REG_LEGAL_OPTION	15
+#define OWNER_SECURITY_INFORMATION 1
+#define GROUP_SECURITY_INFORMATION 2
+#define DACL_SECURITY_INFORMATION 4
+#define SACL_SECURITY_INFORMATION 8
+#define MAXIMUM_PROCESSORS 32
+#define PAGE_EXECUTE 16
+#define PAGE_EXECUTE_READ 32
+#define PAGE_EXECUTE_READWRITE 64
+#define PAGE_GUARD 256
+#define PAGE_NOACCESS 1
+#define PAGE_NOCACHE 512
+#define MEM_COMMIT           0x1000
+#define MEM_RESERVE          0x2000
+#define MEM_DECOMMIT         0x4000
+#define MEM_RELEASE          0x8000
+#define MEM_FREE            0x10000
+#define MEM_PRIVATE         0x20000
+#define MEM_MAPPED          0x40000
+#define MEM_RESET           0x80000
+#define MEM_TOP_DOWN       0x100000
+#define MEM_WRITE_WATCH	   0x200000 /* 98/Me */
+#define MEM_PHYSICAL	   0x400000
+#define MEM_4MB_PAGES    0x80000000
+#define MEM_IMAGE 16777216
+#define SEC_FILE 0x800000
+#define SEC_IMAGE 0x1000000
+#define SEC_VLM 0x2000000
+#define SEC_RESERVE 0x4000000
+#define SEC_COMMIT 0x8000000
+#define SEC_NOCACHE 0x10000000
+#define PAGE_EXECUTE_WRITECOPY 128
+#define SECTION_EXTEND_SIZE 16
+#define SECTION_MAP_READ 4
+#define SECTION_MAP_WRITE 2
+#define SECTION_QUERY 1
+#define SECTION_ALL_ACCESS 0xf001f
+#define MESSAGE_RESOURCE_UNICODE 1
+#define RTL_CRITSECT_TYPE 0
+#define RTL_RESOURCE_TYPE 1
+#define FIELD_OFFSET(t,f) ((LONG)&(((t*)0)->f))
+#define IMAGE_SIZEOF_FILE_HEADER	20
+#define IMAGE_FILE_RELOCS_STRIPPED	1
+#define IMAGE_FILE_EXECUTABLE_IMAGE	2
+#define IMAGE_FILE_LINE_NUMS_STRIPPED	4
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED	8
+#define IMAGE_FILE_BYTES_REVERSED_LO	128
+#define IMAGE_FILE_32BIT_MACHINE	256
+#define IMAGE_FILE_DEBUG_STRIPPED	512
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP	1024
+#define IMAGE_FILE_NET_RUN_FROM_SWAP	2048
+#define IMAGE_FILE_SYSTEM	4096
+#define IMAGE_FILE_DLL	8192
+#define IMAGE_FILE_UP_SYSTEM_ONLY	16384
+#define IMAGE_FILE_BYTES_REVERSED_HI	32768
+#define IMAGE_FILE_MACHINE_UNKNOWN	0
+#define IMAGE_FILE_MACHINE_I386	332
+#define IMAGE_FILE_MACHINE_R3000	354
+#define IMAGE_FILE_MACHINE_R4000	358
+#define IMAGE_FILE_MACHINE_R10000	360
+#define IMAGE_FILE_MACHINE_ALPHA	388
+#define IMAGE_FILE_MACHINE_POWERPC	496
+#define IMAGE_DOS_SIGNATURE 0x5A4D
+#define IMAGE_OS2_SIGNATURE 0x454E
+#define IMAGE_OS2_SIGNATURE_LE 0x454C
+#define IMAGE_VXD_SIGNATURE 0x454C
+#define IMAGE_NT_SIGNATURE 0x00004550
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
+#define IMAGE_SIZEOF_SHORT_NAME 8
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+#define IMAGE_SIZEOF_SYMBOL 18
+#define IMAGE_SIZEOF_AUX_SYMBOL 18
+#define IMAGE_SIZEOF_RELOCATION 10
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+#define IMAGE_SIZEOF_LINENUMBER 6
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+#define SIZEOF_RFPO_DATA 16
+#define IMAGE_SUBSYSTEM_UNKNOWN	0
+#define IMAGE_SUBSYSTEM_NATIVE	1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI	2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI	3
+#define IMAGE_SUBSYSTEM_OS2_CUI	5
+#define IMAGE_SUBSYSTEM_POSIX_CUI	7
+#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((DWORD)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))
+#define IMAGE_DIRECTORY_ENTRY_EXPORT	0
+#define IMAGE_DIRECTORY_ENTRY_IMPORT	1
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE	2
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION	3
+#define IMAGE_DIRECTORY_ENTRY_SECURITY	4
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC	5
+#define IMAGE_DIRECTORY_ENTRY_DEBUG	6
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT	7
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR	8
+#define IMAGE_DIRECTORY_ENTRY_TLS	9
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG	10
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT	11
+#define IMAGE_DIRECTORY_ENTRY_IAT	12
+#define IMAGE_SCN_TYPE_NO_PAD 8
+#define IMAGE_SCN_CNT_CODE 32
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 64
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128
+#define IMAGE_SCN_LNK_OTHER 256
+#define IMAGE_SCN_LNK_INFO 512
+#define IMAGE_SCN_LNK_REMOVE 2048
+#define IMAGE_SCN_LNK_COMDAT 4096
+#define IMAGE_SCN_MEM_FARDATA 0x8000
+#define IMAGE_SCN_MEM_PURGEABLE 0x20000
+#define IMAGE_SCN_MEM_16BIT 0x20000
+#define IMAGE_SCN_MEM_LOCKED  0x40000
+#define IMAGE_SCN_MEM_PRELOAD 0x80000
+#define IMAGE_SCN_ALIGN_1BYTES 0x100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x700000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x1000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+#define IMAGE_SYM_UNDEFINED	0
+#define IMAGE_SYM_ABSOLUTE (-1)
+#define IMAGE_SYM_DEBUG	(-2)
+#define IMAGE_SYM_TYPE_NULL 0
+#define IMAGE_SYM_TYPE_VOID 1
+#define IMAGE_SYM_TYPE_CHAR 2
+#define IMAGE_SYM_TYPE_SHORT 3
+#define IMAGE_SYM_TYPE_INT 4
+#define IMAGE_SYM_TYPE_LONG 5
+#define IMAGE_SYM_TYPE_FLOAT 6
+#define IMAGE_SYM_TYPE_DOUBLE 7
+#define IMAGE_SYM_TYPE_STRUCT 8
+#define IMAGE_SYM_TYPE_UNION 9
+#define IMAGE_SYM_TYPE_ENUM 10
+#define IMAGE_SYM_TYPE_MOE 11
+#define IMAGE_SYM_TYPE_BYTE 12
+#define IMAGE_SYM_TYPE_WORD 13
+#define IMAGE_SYM_TYPE_UINT 14
+#define IMAGE_SYM_TYPE_DWORD 15
+#define IMAGE_SYM_TYPE_PCODE 32768
+#define IMAGE_SYM_DTYPE_NULL 0
+#define IMAGE_SYM_DTYPE_POINTER 1
+#define IMAGE_SYM_DTYPE_FUNCTION 2
+#define IMAGE_SYM_DTYPE_ARRAY 3
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION	(-1)
+#define IMAGE_SYM_CLASS_NULL 0
+#define IMAGE_SYM_CLASS_AUTOMATIC 1
+#define IMAGE_SYM_CLASS_EXTERNAL 2
+#define IMAGE_SYM_CLASS_STATIC 3
+#define IMAGE_SYM_CLASS_REGISTER 4
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define IMAGE_SYM_CLASS_LABEL 6
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define IMAGE_SYM_CLASS_ARGUMENT 9
+#define IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define IMAGE_SYM_CLASS_UNION_TAG 12
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define IMAGE_SYM_CLASS_ENUM_TAG 15
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define IMAGE_SYM_CLASS_BIT_FIELD 18
+#define IMAGE_SYM_CLASS_FAR_EXTERNAL 68
+#define IMAGE_SYM_CLASS_BLOCK 100
+#define IMAGE_SYM_CLASS_FUNCTION 101
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define IMAGE_SYM_CLASS_FILE 103
+#define IMAGE_SYM_CLASS_SECTION 104
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+#define IMAGE_COMDAT_SELECT_LARGEST 6
+#define IMAGE_COMDAT_SELECT_NEWEST 7
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+#define IMAGE_REL_I386_ABSOLUTE 0
+#define IMAGE_REL_I386_DIR16 1
+#define IMAGE_REL_I386_REL16 2
+#define IMAGE_REL_I386_DIR32 6
+#define IMAGE_REL_I386_DIR32NB 7
+#define IMAGE_REL_I386_SEG12 9
+#define IMAGE_REL_I386_SECTION 10
+#define IMAGE_REL_I386_SECREL 11
+#define IMAGE_REL_I386_REL32 20
+#define IMAGE_REL_MIPS_ABSOLUTE 0
+#define IMAGE_REL_MIPS_REFHALF 1
+#define IMAGE_REL_MIPS_REFWORD 2
+#define IMAGE_REL_MIPS_JMPADDR 3
+#define IMAGE_REL_MIPS_REFHI 4
+#define IMAGE_REL_MIPS_REFLO 5
+#define IMAGE_REL_MIPS_GPREL 6
+#define IMAGE_REL_MIPS_LITERAL 7
+#define IMAGE_REL_MIPS_SECTION 10
+#define IMAGE_REL_MIPS_SECREL 11
+#define IMAGE_REL_MIPS_SECRELLO 12
+#define IMAGE_REL_MIPS_SECRELHI 13
+#define IMAGE_REL_MIPS_REFWORDNB 34
+#define IMAGE_REL_MIPS_PAIR 35
+#define IMAGE_REL_ALPHA_ABSOLUTE 0
+#define IMAGE_REL_ALPHA_REFLONG 1
+#define IMAGE_REL_ALPHA_REFQUAD 2
+#define IMAGE_REL_ALPHA_GPREL32 3
+#define IMAGE_REL_ALPHA_LITERAL 4
+#define IMAGE_REL_ALPHA_LITUSE 5
+#define IMAGE_REL_ALPHA_GPDISP 6
+#define IMAGE_REL_ALPHA_BRADDR 7
+#define IMAGE_REL_ALPHA_HINT 8
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 9
+#define IMAGE_REL_ALPHA_REFHI 10
+#define IMAGE_REL_ALPHA_REFLO 11
+#define IMAGE_REL_ALPHA_PAIR 12
+#define IMAGE_REL_ALPHA_MATCH 13
+#define IMAGE_REL_ALPHA_SECTION 14
+#define IMAGE_REL_ALPHA_SECREL 15
+#define IMAGE_REL_ALPHA_REFLONGNB 16
+#define IMAGE_REL_ALPHA_SECRELLO 17
+#define IMAGE_REL_ALPHA_SECRELHI 18
+#define IMAGE_REL_PPC_ABSOLUTE 0
+#define IMAGE_REL_PPC_ADDR64 1
+#define IMAGE_REL_PPC_ADDR32 2
+#define IMAGE_REL_PPC_ADDR24 3
+#define IMAGE_REL_PPC_ADDR16 4
+#define IMAGE_REL_PPC_ADDR14 5
+#define IMAGE_REL_PPC_REL24 6
+#define IMAGE_REL_PPC_REL14 7
+#define IMAGE_REL_PPC_TOCREL16 8
+#define IMAGE_REL_PPC_TOCREL14 9
+#define IMAGE_REL_PPC_ADDR32NB 10
+#define IMAGE_REL_PPC_SECREL 11
+#define IMAGE_REL_PPC_SECTION 12
+#define IMAGE_REL_PPC_IFGLUE 13
+#define IMAGE_REL_PPC_IMGLUE 14
+#define IMAGE_REL_PPC_SECREL16 15
+#define IMAGE_REL_PPC_REFHI 16
+#define IMAGE_REL_PPC_REFLO 17
+#define IMAGE_REL_PPC_PAIR 18
+#define IMAGE_REL_PPC_TYPEMASK 255
+#define IMAGE_REL_PPC_NEG 256
+#define IMAGE_REL_PPC_BRTAKEN 512
+#define IMAGE_REL_PPC_BRNTAKEN 1024
+#define IMAGE_REL_PPC_TOCDEFN 2048
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/               "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "//              "
+#define IMAGE_ORDINAL_FLAG 0x80000000
+#define IMAGE_SNAP_BY_ORDINAL(o) ((o&IMAGE_ORDINAL_FLAG)!=0)
+#define IMAGE_ORDINAL(o) (o&0xffff)
+#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
+#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
+#define IMAGE_DEBUG_TYPE_UNKNOWN 0
+#define IMAGE_DEBUG_TYPE_COFF 1
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+#define IMAGE_DEBUG_TYPE_FPO 3
+#define IMAGE_DEBUG_TYPE_MISC 4
+#define IMAGE_DEBUG_TYPE_EXCEPTION 5
+#define IMAGE_DEBUG_TYPE_FIXUP 6
+#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
+#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
+#define FRAME_FPO 0
+#define FRAME_TRAP 1
+#define FRAME_TSS 2
+#define FRAME_NONFPO 3
+#define IMAGE_DEBUG_MISC_EXENAME 1
+#define N_BTMASK 0x000F
+#define N_TMASK 0x0030
+#define N_TMASK1 0x00C0
+#define N_TMASK2 0x00F0
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+#define IS_TEXT_UNICODE_ASCII16 1
+#define IS_TEXT_UNICODE_REVERSE_ASCII16 16
+#define IS_TEXT_UNICODE_STATISTICS 2
+#define IS_TEXT_UNICODE_REVERSE_STATISTICS 32
+#define IS_TEXT_UNICODE_CONTROLS 4
+#define IS_TEXT_UNICODE_REVERSE_CONTROLS 64
+#define IS_TEXT_UNICODE_SIGNATURE 8
+#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 128
+#define IS_TEXT_UNICODE_ILLEGAL_CHARS 256
+#define IS_TEXT_UNICODE_ODD_LENGTH 512
+#define IS_TEXT_UNICODE_NULL_BYTES 4096
+#define IS_TEXT_UNICODE_UNICODE_MASK 15
+#define IS_TEXT_UNICODE_REVERSE_MASK 240
+#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 3840
+#define IS_TEXT_UNICODE_NOT_ASCII_MASK 61440
+#define SERVICE_KERNEL_DRIVER 1
+#define SERVICE_FILE_SYSTEM_DRIVER 2
+#define SERVICE_ADAPTER 4
+#define SERVICE_RECOGNIZER_DRIVER 8
+#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER|SERVICE_FILE_SYSTEM_DRIVER|SERVICE_RECOGNIZER_DRIVER)
+#define SERVICE_WIN32_OWN_PROCESS 16
+#define SERVICE_WIN32_SHARE_PROCESS 32
+#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS|SERVICE_WIN32_SHARE_PROCESS)
+#define SERVICE_INTERACTIVE_PROCESS 256
+#define SERVICE_TYPE_ALL (SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS)
+#define SERVICE_BOOT_START 0
+#define SERVICE_SYSTEM_START 1
+#define SERVICE_AUTO_START 2
+#define SERVICE_DEMAND_START 3
+#define SERVICE_DISABLED 4
+#define SERVICE_ERROR_IGNORE 0
+#define SERVICE_ERROR_NORMAL 1
+#define SERVICE_ERROR_SEVERE 2
+#define SERVICE_ERROR_CRITICAL 3
+#define SE_OWNER_DEFAULTED 1
+#define SE_GROUP_DEFAULTED 2
+#define SE_DACL_PRESENT 4
+#define SE_DACL_DEFAULTED 8
+#define SE_SACL_PRESENT 16
+#define SE_SACL_DEFAULTED 32
+#define SE_DACL_AUTO_INHERIT_REQ 256
+#define SE_SACL_AUTO_INHERIT_REQ 512
+#define SE_DACL_AUTO_INHERITED 1024
+#define SE_SACL_AUTO_INHERITED 2048
+#define SE_DACL_PROTECTED 4096
+#define SE_SACL_PROTECTED 8192
+#define SE_SELF_RELATIVE 0x8000
+#define SECURITY_DESCRIPTOR_MIN_LENGTH 20
+#define SECURITY_DESCRIPTOR_REVISION 1
+#define SECURITY_DESCRIPTOR_REVISION1 1
+#define SE_PRIVILEGE_ENABLED_BY_DEFAULT 1
+#define SE_PRIVILEGE_ENABLED 2
+#define SE_PRIVILEGE_USED_FOR_ACCESS 0x80000000
+#define PRIVILEGE_SET_ALL_NECESSARY 1
+#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
+#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
+#define SECURITY_DYNAMIC_TRACKING TRUE
+#define SECURITY_STATIC_TRACKING FALSE
+#define TOKEN_SOURCE_LENGTH 8
+#define TOKEN_ADJUST_DEFAULT	128
+#define TOKEN_ADJUST_GROUPS	64
+#define TOKEN_ADJUST_PRIVILEGES	32
+#define TOKEN_ALL_ACCESS	0xf00ff
+#define TOKEN_ASSIGN_PRIMARY	1
+#define TOKEN_DUPLICATE	2
+#define TOKEN_EXECUTE	0x20000
+#define TOKEN_IMPERSONATE	4
+#define TOKEN_QUERY	8
+#define TOKEN_QUERY_SOURCE	16
+#define TOKEN_READ	0x20008
+#define TOKEN_WRITE	0x200e0
+#define DLL_PROCESS_DETACH	0
+#define DLL_PROCESS_ATTACH	1
+#define DLL_THREAD_ATTACH	2
+#define DLL_THREAD_DETACH	3
+#define DBG_CONTINUE 0x10002
+#define DBG_TERMINATE_THREAD 0x40010003
+#define DBG_TERMINATE_PROCESS 0x40010004
+#define DBG_CONTROL_C 0x40010005
+#define DBG_CONTROL_BREAK 0x40010008
+#define DBG_EXCEPTION_NOT_HANDLED 0x80010001
+#define TAPE_ABSOLUTE_POSITION 0
+#define TAPE_LOGICAL_POSITION 1
+#define TAPE_PSEUDO_LOGICAL_POSITION 2
+#define TAPE_REWIND 0
+#define TAPE_ABSOLUTE_BLOCK 1
+#define TAPE_LOGICAL_BLOCK 2
+#define TAPE_PSEUDO_LOGICAL_BLOCK 3
+#define TAPE_SPACE_END_OF_DATA 4
+#define TAPE_SPACE_RELATIVE_BLOCKS 5
+#define TAPE_SPACE_FILEMARKS 6
+#define TAPE_SPACE_SEQUENTIAL_FMKS 7
+#define TAPE_SPACE_SETMARKS 8
+#define TAPE_SPACE_SEQUENTIAL_SMKS 9
+#define TAPE_DRIVE_FIXED 1
+#define TAPE_DRIVE_SELECT 2
+#define TAPE_DRIVE_INITIATOR 4
+#define TAPE_DRIVE_ERASE_SHORT 16
+#define TAPE_DRIVE_ERASE_LONG 32
+#define TAPE_DRIVE_ERASE_BOP_ONLY 64
+#define TAPE_DRIVE_ERASE_IMMEDIATE 128
+#define TAPE_DRIVE_TAPE_CAPACITY 256
+#define TAPE_DRIVE_TAPE_REMAINING 512
+#define TAPE_DRIVE_FIXED_BLOCK 1024
+#define TAPE_DRIVE_VARIABLE_BLOCK 2048
+#define TAPE_DRIVE_WRITE_PROTECT 4096
+#define TAPE_DRIVE_EOT_WZ_SIZE 8192
+#define TAPE_DRIVE_ECC 0x10000
+#define TAPE_DRIVE_COMPRESSION 0x20000
+#define TAPE_DRIVE_PADDING 0x40000
+#define TAPE_DRIVE_REPORT_SMKS 0x80000
+#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x100000
+#define TAPE_DRIVE_GET_LOGICAL_BLK 0x200000
+#define TAPE_DRIVE_SET_EOT_WZ_SIZE 0x400000
+#define TAPE_DRIVE_EJECT_MEDIA 0x1000000
+#define TAPE_DRIVE_CLEAN_REQUESTS 0x2000000
+#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x4000000
+#define TAPE_DRIVE_RESERVED_BIT 0x80000000
+#define TAPE_DRIVE_LOAD_UNLOAD 0x80000001
+#define TAPE_DRIVE_TENSION 0x80000002
+#define TAPE_DRIVE_LOCK_UNLOCK 0x80000004
+#define TAPE_DRIVE_REWIND_IMMEDIATE 0x80000008
+#define TAPE_DRIVE_SET_BLOCK_SIZE 0x80000010
+#define TAPE_DRIVE_LOAD_UNLD_IMMED 0x80000020
+#define TAPE_DRIVE_TENSION_IMMED 0x80000040
+#define TAPE_DRIVE_LOCK_UNLK_IMMED 0x80000080
+#define TAPE_DRIVE_SET_ECC 0x80000100
+#define TAPE_DRIVE_SET_COMPRESSION 0x80000200
+#define TAPE_DRIVE_SET_PADDING 0x80000400
+#define TAPE_DRIVE_SET_REPORT_SMKS 0x80000800
+#define TAPE_DRIVE_ABSOLUTE_BLK 0x80001000
+#define TAPE_DRIVE_ABS_BLK_IMMED 0x80002000
+#define TAPE_DRIVE_LOGICAL_BLK 0x80004000
+#define TAPE_DRIVE_LOG_BLK_IMMED 0x80008000
+#define TAPE_DRIVE_END_OF_DATA 0x80010000
+#define TAPE_DRIVE_RELATIVE_BLKS 0x80020000
+#define TAPE_DRIVE_FILEMARKS 0x80040000
+#define TAPE_DRIVE_SEQUENTIAL_FMKS 0x80080000
+#define TAPE_DRIVE_SETMARKS 0x80100000
+#define TAPE_DRIVE_SEQUENTIAL_SMKS 0x80200000
+#define TAPE_DRIVE_REVERSE_POSITION 0x80400000
+#define TAPE_DRIVE_SPACE_IMMEDIATE 0x80800000
+#define TAPE_DRIVE_WRITE_SETMARKS 0x81000000
+#define TAPE_DRIVE_WRITE_FILEMARKS 0x82000000
+#define TAPE_DRIVE_WRITE_SHORT_FMKS 0x84000000
+#define TAPE_DRIVE_WRITE_LONG_FMKS 0x88000000
+#define TAPE_DRIVE_WRITE_MARK_IMMED 0x90000000
+#define TAPE_DRIVE_FORMAT 0xA0000000
+#define TAPE_DRIVE_FORMAT_IMMEDIATE 0xC0000000
+#define TAPE_DRIVE_HIGH_FEATURES 0x80000000
+#define TAPE_FIXED_PARTITIONS	0
+#define TAPE_INITIATOR_PARTITIONS	2
+#define TAPE_SELECT_PARTITIONS	1
+#define TAPE_FILEMARKS	1
+#define TAPE_LONG_FILEMARKS	3
+#define TAPE_SETMARKS	0
+#define TAPE_SHORT_FILEMARKS	2
+#define TAPE_ERASE_LONG 1
+#define TAPE_ERASE_SHORT 0
+#define TAPE_LOAD 0
+#define TAPE_UNLOAD 1
+#define TAPE_TENSION 2
+#define TAPE_LOCK 3
+#define TAPE_UNLOCK 4
+#define TAPE_FORMAT 5
+#define VER_PLATFORM_WIN32s 0
+#define VER_PLATFORM_WIN32_WINDOWS 1
+#define VER_PLATFORM_WIN32_NT 2
+#define VER_NT_WORKSTATION 1
+#define VER_NT_DOMAIN_CONTROLLER 2
+#define VER_NT_SERVER 3
+#define VER_SUITE_SMALLBUSINESS 1
+#define VER_SUITE_ENTERPRISE 2
+#define VER_SUITE_BACKOFFICE 4
+#define VER_SUITE_TERMINAL 16
+#define VER_SUITE_SMALLBUSINESS_RESTRICTED 32
+#define VER_SUITE_DATACENTER 128
+#define VER_SUITE_PERSONAL 512
+#define BTYPE(x) ((x)&N_BTMASK)
+#define ISPTR(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT))
+#define ISFCN(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_FUNCTION<<N_BTSHFT))
+#define ISARY(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_ARRAY<<N_BTSHFT))
+#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG||(x)==IMAGE_SYM_CLASS_UNION_TAG||(x)==IMAGE_SYM_CLASS_ENUM_TAG)
+#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+#define TLS_MINIMUM_AVAILABLE 64
+#define REPARSE_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE   FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer)
+#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384
+#define IO_REPARSE_TAG_RESERVED_ZERO 0
+#define IO_REPARSE_TAG_RESERVED_ONE 1
+#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE
+#define IsReparseTagMicrosoft(x) ((x)&0x80000000)
+#define IsReparseTagHighLatency(x) ((x)&0x40000000)
+#define IsReparseTagNameSurrogate(x) ((x)&0x20000000)
+#define IO_REPARSE_TAG_VALID_VALUES 0xE000FFFF
+#define IsReparseTagValid(x) (!((x)&~IO_REPARSE_TAG_VALID_VALUES)&&((x)>IO_REPARSE_TAG_RESERVED_RANGE))
+#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO
+#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
+#ifndef RC_INVOKED
+typedef DWORD ACCESS_MASK, *PACCESS_MASK;
+#ifndef _GUID_DEFINED /* also defined in basetyps.h */
+#define _GUID_DEFINED
+typedef struct _GUID {
+	unsigned long  Data1;
+	unsigned short Data2;
+	unsigned short Data3;
+	unsigned char  Data4[8];
+} GUID, *REFGUID, *LPGUID;
+#define SYSTEM_LUID { QuadPart:999 }
+#endif /* _GUID_DEFINED */
+typedef struct _GENERIC_MAPPING {
+	ACCESS_MASK GenericRead;
+	ACCESS_MASK GenericWrite;
+	ACCESS_MASK GenericExecute;
+	ACCESS_MASK GenericAll;
+} GENERIC_MAPPING, *PGENERIC_MAPPING;
+typedef struct _ACE_HEADER {
+	BYTE AceType;
+	BYTE AceFlags;
+	WORD AceSize;
+} ACE_HEADER;
+typedef struct _ACCESS_ALLOWED_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD SidStart;
+} ACCESS_ALLOWED_ACE;
+typedef struct _ACCESS_DENIED_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD SidStart;
+} ACCESS_DENIED_ACE;
+typedef struct _SYSTEM_AUDIT_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD SidStart;
+} SYSTEM_AUDIT_ACE;
+typedef SYSTEM_AUDIT_ACE *PSYSTEM_AUDIT_ACE;
+typedef struct _SYSTEM_ALARM_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD SidStart;
+} SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE;
+typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD Flags;
+	GUID ObjectType;
+	GUID InheritedObjectType;
+	DWORD SidStart;
+} ACCESS_ALLOWED_OBJECT_ACE,*PACCESS_ALLOWED_OBJECT_ACE;
+typedef struct _ACCESS_DENIED_OBJECT_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD Flags;
+	GUID ObjectType;
+	GUID InheritedObjectType;
+	DWORD SidStart;
+} ACCESS_DENIED_OBJECT_ACE,*PACCESS_DENIED_OBJECT_ACE;
+typedef struct _SYSTEM_AUDIT_OBJECT_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD Flags;
+	GUID ObjectType;
+	GUID InheritedObjectType;
+	DWORD SidStart;
+} SYSTEM_AUDIT_OBJECT_ACE,*PSYSTEM_AUDIT_OBJECT_ACE;
+typedef struct _SYSTEM_ALARM_OBJECT_ACE {
+	ACE_HEADER Header;
+	ACCESS_MASK Mask;
+	DWORD Flags;
+	GUID ObjectType;
+	GUID InheritedObjectType;
+	DWORD SidStart;
+} SYSTEM_ALARM_OBJECT_ACE,*PSYSTEM_ALARM_OBJECT_ACE;
+typedef struct _ACL {
+	BYTE AclRevision;
+	BYTE Sbz1;
+	WORD AclSize;
+	WORD AceCount;
+	WORD Sbz2;
+} ACL,*PACL;
+typedef struct _ACL_REVISION_INFORMATION {
+	DWORD AclRevision;
+} ACL_REVISION_INFORMATION;
+typedef struct _ACL_SIZE_INFORMATION {
+	DWORD   AceCount;
+	DWORD   AclBytesInUse;
+	DWORD   AclBytesFree;
+} ACL_SIZE_INFORMATION;
+
+/* FIXME: add more machines */
+#ifdef _X86_
+#define SIZE_OF_80387_REGISTERS	80
+#define CONTEXT_i386	0x10000
+#define CONTEXT_i486	0x10000
+#define CONTEXT_CONTROL	(CONTEXT_i386|0x00000001L)
+#define CONTEXT_INTEGER	(CONTEXT_i386|0x00000002L)
+#define CONTEXT_SEGMENTS	(CONTEXT_i386|0x00000004L)
+#define CONTEXT_FLOATING_POINT	(CONTEXT_i386|0x00000008L)
+#define CONTEXT_DEBUG_REGISTERS	(CONTEXT_i386|0x00000010L)
+#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L)
+#define CONTEXT_FULL	(CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS)
+#define MAXIMUM_SUPPORTED_EXTENSION  512
+typedef struct _FLOATING_SAVE_AREA {
+	DWORD	ControlWord;
+	DWORD	StatusWord;
+	DWORD	TagWord;
+	DWORD	ErrorOffset;
+	DWORD	ErrorSelector;
+	DWORD	DataOffset;
+	DWORD	DataSelector;
+	BYTE	RegisterArea[80];
+	DWORD	Cr0NpxState;
+} FLOATING_SAVE_AREA;
+typedef struct _CONTEXT {
+	DWORD	ContextFlags;
+	DWORD	Dr0;
+	DWORD	Dr1;
+	DWORD	Dr2;
+	DWORD	Dr3;
+	DWORD	Dr6;
+	DWORD	Dr7;
+	FLOATING_SAVE_AREA FloatSave;
+	DWORD	SegGs;
+	DWORD	SegFs;
+	DWORD	SegEs;
+	DWORD	SegDs;
+	DWORD	Edi;
+	DWORD	Esi;
+	DWORD	Ebx;
+	DWORD	Edx;
+	DWORD	Ecx;
+	DWORD	Eax;
+	DWORD	Ebp;
+	DWORD	Eip;
+	DWORD	SegCs;
+	DWORD	EFlags;
+	DWORD	Esp;
+	DWORD	SegSs;
+	BYTE	ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
+} CONTEXT;
+#elif defined(_PPC_)
+#define CONTEXT_CONTROL	1L
+#define CONTEXT_FLOATING_POINT	2L
+#define CONTEXT_INTEGER	4L
+#define CONTEXT_DEBUG_REGISTERS	8L
+#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER)
+typedef struct {
+	double Fpr0;
+	double Fpr1;
+	double Fpr2;
+	double Fpr3;
+	double Fpr4;
+	double Fpr5;
+	double Fpr6;
+	double Fpr7;
+	double Fpr8;
+	double Fpr9;
+	double Fpr10;
+	double Fpr11;
+	double Fpr12;
+	double Fpr13;
+	double Fpr14;
+	double Fpr15;
+	double Fpr16;
+	double Fpr17;
+	double Fpr18;
+	double Fpr19;
+	double Fpr20;
+	double Fpr21;
+	double Fpr22;
+	double Fpr23;
+	double Fpr24;
+	double Fpr25;
+	double Fpr26;
+	double Fpr27;
+	double Fpr28;
+	double Fpr29;
+	double Fpr30;
+	double Fpr31;
+	double Fpscr;
+	DWORD Gpr0;
+	DWORD Gpr1;
+	DWORD Gpr2;
+	DWORD Gpr3;
+	DWORD Gpr4;
+	DWORD Gpr5;
+	DWORD Gpr6;
+	DWORD Gpr7;
+	DWORD Gpr8;
+	DWORD Gpr9;
+	DWORD Gpr10;
+	DWORD Gpr11;
+	DWORD Gpr12;
+	DWORD Gpr13;
+	DWORD Gpr14;
+	DWORD Gpr15;
+	DWORD Gpr16;
+	DWORD Gpr17;
+	DWORD Gpr18;
+	DWORD Gpr19;
+	DWORD Gpr20;
+	DWORD Gpr21;
+	DWORD Gpr22;
+	DWORD Gpr23;
+	DWORD Gpr24;
+	DWORD Gpr25;
+	DWORD Gpr26;
+	DWORD Gpr27;
+	DWORD Gpr28;
+	DWORD Gpr29;
+	DWORD Gpr30;
+	DWORD Gpr31;
+	DWORD Cr;
+	DWORD Xer;
+	DWORD Msr;
+	DWORD Iar;
+	DWORD Lr;
+	DWORD Ctr;
+	DWORD ContextFlags;
+	DWORD Fill[3];
+	DWORD Dr0;
+	DWORD Dr1;
+	DWORD Dr2;
+	DWORD Dr3;
+	DWORD Dr4;
+	DWORD Dr5;
+	DWORD Dr6;
+	DWORD Dr7;
+} CONTEXT;
+#elif defined(_ALPHA_)
+#define CONTEXT_ALPHA	0x20000
+#define CONTEXT_CONTROL	(CONTEXT_ALPHA|1L)
+#define CONTEXT_FLOATING_POINT	(CONTEXT_ALPHA|2L)
+#define CONTEXT_INTEGER	(CONTEXT_ALPHA|4L)
+#define CONTEXT_FULL	(CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER)
+typedef struct _CONTEXT {
+	ULONGLONG FltF0;
+	ULONGLONG FltF1;
+	ULONGLONG FltF2;
+	ULONGLONG FltF3;
+	ULONGLONG FltF4;
+	ULONGLONG FltF5;
+	ULONGLONG FltF6;
+	ULONGLONG FltF7;
+	ULONGLONG FltF8;
+	ULONGLONG FltF9;
+	ULONGLONG FltF10;
+	ULONGLONG FltF11;
+	ULONGLONG FltF12;
+	ULONGLONG FltF13;
+	ULONGLONG FltF14;
+	ULONGLONG FltF15;
+	ULONGLONG FltF16;
+	ULONGLONG FltF17;
+	ULONGLONG FltF18;
+	ULONGLONG FltF19;
+	ULONGLONG FltF20;
+	ULONGLONG FltF21;
+	ULONGLONG FltF22;
+	ULONGLONG FltF23;
+	ULONGLONG FltF24;
+	ULONGLONG FltF25;
+	ULONGLONG FltF26;
+	ULONGLONG FltF27;
+	ULONGLONG FltF28;
+	ULONGLONG FltF29;
+	ULONGLONG FltF30;
+	ULONGLONG FltF31;
+	ULONGLONG IntV0;
+	ULONGLONG IntT0;
+	ULONGLONG IntT1;
+	ULONGLONG IntT2;
+	ULONGLONG IntT3;
+	ULONGLONG IntT4;
+	ULONGLONG IntT5;
+	ULONGLONG IntT6;
+	ULONGLONG IntT7;
+	ULONGLONG IntS0;
+	ULONGLONG IntS1;
+	ULONGLONG IntS2;
+	ULONGLONG IntS3;
+	ULONGLONG IntS4;
+	ULONGLONG IntS5;
+	ULONGLONG IntFp;
+	ULONGLONG IntA0;
+	ULONGLONG IntA1;
+	ULONGLONG IntA2;
+	ULONGLONG IntA3;
+	ULONGLONG IntA4;
+	ULONGLONG IntA5;
+	ULONGLONG IntT8;
+	ULONGLONG IntT9;
+	ULONGLONG IntT10;
+	ULONGLONG IntT11;
+	ULONGLONG IntRa;
+	ULONGLONG IntT12;
+	ULONGLONG IntAt;
+	ULONGLONG IntGp;
+	ULONGLONG IntSp;
+	ULONGLONG IntZero;
+	ULONGLONG Fpcr;
+	ULONGLONG SoftFpcr;
+	ULONGLONG Fir;
+	DWORD Psr;
+	DWORD ContextFlags;
+	DWORD Fill[4];
+} CONTEXT;
+#elif defined(SHx)
+
+/* These are the debug or break registers on the SH3 */
+typedef struct _DEBUG_REGISTERS {
+	ULONG  BarA;
+	UCHAR  BasrA;
+	UCHAR  BamrA;
+	USHORT BbrA;
+	ULONG  BarB;
+	UCHAR  BasrB;
+	UCHAR  BamrB;
+	USHORT BbrB;
+	ULONG  BdrB;
+	ULONG  BdmrB;
+	USHORT Brcr;
+	USHORT Align;
+} DEBUG_REGISTERS, *PDEBUG_REGISTERS;
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_SH3		0x00000040
+#define CONTEXT_SH4		0x000000c0	/* CONTEXT_SH3 | 0x80 - must contain the SH3 bits */
+
+#ifdef SH3
+#define CONTEXT_CONTROL         (CONTEXT_SH3 | 0x00000001L)
+#define CONTEXT_INTEGER         (CONTEXT_SH3 | 0x00000002L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH3 | 0x00000008L)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS)
+#else	/* SH4 */
+#define CONTEXT_CONTROL         (CONTEXT_SH4 | 0x00000001L)
+#define CONTEXT_INTEGER         (CONTEXT_SH4 | 0x00000002L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH4 | 0x00000008L)
+#define CONTEXT_FLOATING_POINT  (CONTEXT_SH4 | 0x00000004L)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT)
+#endif
+
+/* Context Frame */
+
+/*  This frame is used to store a limited processor context into the */
+/* Thread structure for CPUs which have no floating point support. */
+
+typedef struct _CONTEXT {
+	/* The flags values within this flag control the contents of */
+	/* a CONTEXT record. */
+
+	/* If the context record is used as an input parameter, then */
+	/* for each portion of the context record controlled by a flag */
+	/* whose value is set, it is assumed that that portion of the */
+	/* context record contains valid context. If the context record */
+	/* is being used to modify a thread's context, then only that */
+	/* portion of the threads context will be modified. */
+
+	/* If the context record is used as an IN OUT parameter to capture */
+	/* the context of a thread, then only those portions of the thread's */
+	/* context corresponding to set flags will be returned. */
+
+	/* The context record is never used as an OUT only parameter. */
+
+
+	ULONG ContextFlags;
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_INTEGER. */
+
+	/* N.B. The registers RA and R15 are defined in this section, but are */
+	/*  considered part of the control context rather than part of the integer */
+	/*  context. */
+
+	ULONG PR;
+	ULONG MACH;
+	ULONG MACL;
+	ULONG GBR;
+	ULONG R0;
+	ULONG R1;
+	ULONG R2;
+	ULONG R3;
+	ULONG R4;
+	ULONG R5;
+	ULONG R6;
+	ULONG R7;
+	ULONG R8;
+	ULONG R9;
+	ULONG R10;
+	ULONG R11;
+	ULONG R12;
+	ULONG R13;
+	ULONG R14;
+	ULONG R15;
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_CONTROL. */
+
+	/* N.B. The registers r15 and ra are defined in the integer section, */
+	/*   but are considered part of the control context rather than part of */
+	/*   the integer context. */
+
+	ULONG Fir;
+	ULONG Psr;
+
+#if !defined(SH3e) && !defined(SH4)
+	ULONG	OldStuff[2];
+	DEBUG_REGISTERS DebugRegisters;
+#else
+	ULONG	Fpscr;
+	ULONG	Fpul;
+	ULONG	FRegs[16];
+#if defined(SH4)
+	ULONG	xFRegs[16];
+#endif
+#endif
+} CONTEXT;
+
+#elif defined(MIPS)
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_R4000   0x00010000    /* r4000 context */
+
+#define CONTEXT_CONTROL         (CONTEXT_R4000 | 0x00000001L)
+#define CONTEXT_FLOATING_POINT  (CONTEXT_R4000 | 0x00000002L)
+#define CONTEXT_INTEGER         (CONTEXT_R4000 | 0x00000004L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+/* Context Frame */
+
+/*  N.B. This frame must be exactly a multiple of 16 bytes in length. */
+
+/*  This frame has a several purposes: 1) it is used as an argument to */
+/*  NtContinue, 2) it is used to constuct a call frame for APC delivery, */
+/*  3) it is used to construct a call frame for exception dispatching */
+/*  in user mode, and 4) it is used in the user level thread creation */
+/*  routines. */
+
+/*  The layout of the record conforms to a standard call frame. */
+
+
+typedef struct _CONTEXT {
+
+	/* This section is always present and is used as an argument build */
+	/* area. */
+
+	DWORD Argument[4];
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_FLOATING_POINT. */
+
+	DWORD FltF0;
+	DWORD FltF1;
+	DWORD FltF2;
+	DWORD FltF3;
+	DWORD FltF4;
+	DWORD FltF5;
+	DWORD FltF6;
+	DWORD FltF7;
+	DWORD FltF8;
+	DWORD FltF9;
+	DWORD FltF10;
+	DWORD FltF11;
+	DWORD FltF12;
+	DWORD FltF13;
+	DWORD FltF14;
+	DWORD FltF15;
+	DWORD FltF16;
+	DWORD FltF17;
+	DWORD FltF18;
+	DWORD FltF19;
+	DWORD FltF20;
+	DWORD FltF21;
+	DWORD FltF22;
+	DWORD FltF23;
+	DWORD FltF24;
+	DWORD FltF25;
+	DWORD FltF26;
+	DWORD FltF27;
+	DWORD FltF28;
+	DWORD FltF29;
+	DWORD FltF30;
+	DWORD FltF31;
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_INTEGER. */
+
+	/* N.B. The registers gp, sp, and ra are defined in this section, but are */
+	/*  considered part of the control context rather than part of the integer */
+	/*  context. */
+
+	/* N.B. Register zero is not stored in the frame. */
+
+	DWORD IntZero;
+	DWORD IntAt;
+	DWORD IntV0;
+	DWORD IntV1;
+	DWORD IntA0;
+	DWORD IntA1;
+	DWORD IntA2;
+	DWORD IntA3;
+	DWORD IntT0;
+	DWORD IntT1;
+	DWORD IntT2;
+	DWORD IntT3;
+	DWORD IntT4;
+	DWORD IntT5;
+	DWORD IntT6;
+	DWORD IntT7;
+	DWORD IntS0;
+	DWORD IntS1;
+	DWORD IntS2;
+	DWORD IntS3;
+	DWORD IntS4;
+	DWORD IntS5;
+	DWORD IntS6;
+	DWORD IntS7;
+	DWORD IntT8;
+	DWORD IntT9;
+	DWORD IntK0;
+	DWORD IntK1;
+	DWORD IntGp;
+	DWORD IntSp;
+	DWORD IntS8;
+	DWORD IntRa;
+	DWORD IntLo;
+	DWORD IntHi;
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_FLOATING_POINT. */
+
+	DWORD Fsr;
+
+	/* This section is specified/returned if the ContextFlags word contains */
+	/* the flag CONTEXT_CONTROL. */
+
+	/* N.B. The registers gp, sp, and ra are defined in the integer section, */
+	/*   but are considered part of the control context rather than part of */
+	/*   the integer context. */
+
+	DWORD Fir;
+	DWORD Psr;
+
+	/* The flags values within this flag control the contents of */
+	/* a CONTEXT record. */
+
+	/* If the context record is used as an input parameter, then */
+	/* for each portion of the context record controlled by a flag */
+	/* whose value is set, it is assumed that that portion of the */
+	/* context record contains valid context. If the context record */
+	/* is being used to modify a thread's context, then only that */
+	/* portion of the threads context will be modified. */
+
+	/* If the context record is used as an IN OUT parameter to capture */
+	/* the context of a thread, then only those portions of the thread's */
+	/* context corresponding to set flags will be returned. */
+
+	/* The context record is never used as an OUT only parameter. */
+
+	DWORD ContextFlags;
+
+	DWORD Fill[2];
+
+} CONTEXT;
+#elif defined(ARM)
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_ARM    0x0000040
+#define CONTEXT_CONTROL         (CONTEXT_ARM | 0x00000001L)
+#define CONTEXT_INTEGER         (CONTEXT_ARM | 0x00000002L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER)
+
+typedef struct _CONTEXT {
+	/* The flags values within this flag control the contents of
+	   a CONTEXT record.
+	  
+	   If the context record is used as an input parameter, then
+	   for each portion of the context record controlled by a flag
+	   whose value is set, it is assumed that that portion of the
+	   context record contains valid context. If the context record
+	   is being used to modify a thread's context, then only that
+	   portion of the threads context will be modified.
+	  
+	   If the context record is used as an IN OUT parameter to capture
+	   the context of a thread, then only those portions of the thread's
+	   context corresponding to set flags will be returned.
+	  
+	   The context record is never used as an OUT only parameter. */
+
+	ULONG ContextFlags;
+
+	/* This section is specified/returned if the ContextFlags word contains
+	   the flag CONTEXT_INTEGER. */
+	ULONG R0;
+	ULONG R1;
+	ULONG R2;
+	ULONG R3;
+	ULONG R4;
+	ULONG R5;
+	ULONG R6;
+	ULONG R7;
+	ULONG R8;
+	ULONG R9;
+	ULONG R10;
+	ULONG R11;
+	ULONG R12;
+
+	ULONG Sp;
+	ULONG Lr;
+	ULONG Pc;
+	ULONG Psr;
+} CONTEXT;
+
+#else
+#error "undefined processor type"
+#endif
+typedef CONTEXT *PCONTEXT,*LPCONTEXT;
+typedef struct _EXCEPTION_RECORD {
+	DWORD ExceptionCode;
+	DWORD ExceptionFlags;
+	struct _EXCEPTION_RECORD *ExceptionRecord;
+	PVOID ExceptionAddress;
+	DWORD NumberParameters;
+	DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD,*PEXCEPTION_RECORD;
+typedef struct _EXCEPTION_POINTERS {
+	PEXCEPTION_RECORD ExceptionRecord;
+	PCONTEXT ContextRecord;
+} EXCEPTION_POINTERS,*PEXCEPTION_POINTERS,*LPEXCEPTION_POINTERS;
+typedef union _LARGE_INTEGER {
+  struct {
+    DWORD LowPart;
+    LONG  HighPart;
+  } u;
+#if ! defined(NONAMELESSUNION) || defined(__cplusplus)
+  _ANONYMOUS_STRUCT struct {
+    DWORD LowPart;
+    LONG  HighPart;
+  };
+#endif /* NONAMELESSUNION */
+  LONGLONG QuadPart;
+} LARGE_INTEGER, *PLARGE_INTEGER;
+typedef union _ULARGE_INTEGER {
+  struct {
+    DWORD LowPart;
+    DWORD HighPart;
+  } u;
+#if ! defined(NONAMELESSUNION) || defined(__cplusplus)
+  _ANONYMOUS_STRUCT struct {
+    DWORD LowPart;
+    DWORD HighPart;
+  };
+#endif /* NONAMELESSUNION */
+  ULONGLONG QuadPart;
+} ULARGE_INTEGER, *PULARGE_INTEGER;
+typedef LARGE_INTEGER LUID,*PLUID;
+#pragma pack(push,4)
+typedef struct _LUID_AND_ATTRIBUTES {
+	LUID   Luid;
+	DWORD  Attributes;
+} LUID_AND_ATTRIBUTES;
+#pragma pack(pop)
+typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;
+typedef struct _PRIVILEGE_SET {
+	DWORD PrivilegeCount;
+	DWORD Control;
+	LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
+} PRIVILEGE_SET,*PPRIVILEGE_SET;
+typedef struct _SECURITY_ATTRIBUTES {
+	DWORD nLength;
+	LPVOID lpSecurityDescriptor;
+	BOOL bInheritHandle;
+} SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES;
+typedef enum _SECURITY_IMPERSONATION_LEVEL {
+	SecurityAnonymous,
+	SecurityIdentification,
+	SecurityImpersonation,
+	SecurityDelegation
+} SECURITY_IMPERSONATION_LEVEL;
+typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,*PSECURITY_CONTEXT_TRACKING_MODE;
+typedef struct _SECURITY_QUALITY_OF_SERVICE {
+	DWORD Length;
+	SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+	SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
+	BOOLEAN EffectiveOnly;
+} SECURITY_QUALITY_OF_SERVICE,*PSECURITY_QUALITY_OF_SERVICE;
+typedef PVOID PACCESS_TOKEN;
+typedef struct _SE_IMPERSONATION_STATE {
+	PACCESS_TOKEN Token;
+	BOOLEAN CopyOnOpen;
+	BOOLEAN EffectiveOnly;
+	SECURITY_IMPERSONATION_LEVEL Level;
+} SE_IMPERSONATION_STATE,*PSE_IMPERSONATION_STATE;
+typedef struct _SID_IDENTIFIER_AUTHORITY {
+	BYTE Value[6];
+} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+typedef PVOID PSID;
+typedef struct _SID {
+   BYTE  Revision;
+   BYTE  SubAuthorityCount;
+   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+   DWORD SubAuthority[ANYSIZE_ARRAY];
+} SID, *PISID;
+typedef struct _SID_AND_ATTRIBUTES {
+	PSID Sid;
+	DWORD Attributes;
+} SID_AND_ATTRIBUTES;
+typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY;
+typedef struct _TOKEN_SOURCE {
+	CHAR SourceName[TOKEN_SOURCE_LENGTH];
+	LUID SourceIdentifier;
+} TOKEN_SOURCE,*PTOKEN_SOURCE;
+typedef struct _TOKEN_CONTROL {
+	LUID TokenId;
+	LUID AuthenticationId;
+	LUID ModifiedId;
+	TOKEN_SOURCE TokenSource;
+} TOKEN_CONTROL,*PTOKEN_CONTROL;
+typedef struct _TOKEN_DEFAULT_DACL {
+	PACL DefaultDacl;
+} TOKEN_DEFAULT_DACL,*PTOKEN_DEFAULT_DACL;
+typedef struct _TOKEN_GROUPS {
+	DWORD GroupCount;
+	SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
+} TOKEN_GROUPS,*PTOKEN_GROUPS,*LPTOKEN_GROUPS;
+typedef struct _TOKEN_OWNER {
+	PSID Owner;
+} TOKEN_OWNER,*PTOKEN_OWNER;
+typedef struct _TOKEN_PRIMARY_GROUP {
+	PSID PrimaryGroup;
+} TOKEN_PRIMARY_GROUP,*PTOKEN_PRIMARY_GROUP;
+typedef struct _TOKEN_PRIVILEGES {
+	DWORD PrivilegeCount;
+	LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
+} TOKEN_PRIVILEGES,*PTOKEN_PRIVILEGES,*LPTOKEN_PRIVILEGES;
+typedef enum tagTOKEN_TYPE { TokenPrimary=1,TokenImpersonation }TOKEN_TYPE;
+typedef struct _TOKEN_STATISTICS {
+	LUID TokenId;
+	LUID AuthenticationId;
+	LARGE_INTEGER ExpirationTime;
+	TOKEN_TYPE TokenType;
+	SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+	DWORD DynamicCharged;
+	DWORD DynamicAvailable;
+	DWORD GroupCount;
+	DWORD PrivilegeCount;
+	LUID ModifiedId;
+} TOKEN_STATISTICS;
+typedef struct _TOKEN_USER {
+	SID_AND_ATTRIBUTES User;
+} TOKEN_USER, *PTOKEN_USER;
+typedef DWORD SECURITY_INFORMATION,*PSECURITY_INFORMATION;
+typedef WORD SECURITY_DESCRIPTOR_CONTROL,*PSECURITY_DESCRIPTOR_CONTROL;
+typedef struct _SECURITY_DESCRIPTOR {
+	BYTE Revision;
+	BYTE Sbz1;
+	SECURITY_DESCRIPTOR_CONTROL Control;
+	PSID Owner;
+	PSID Group;
+	PACL Sacl;
+	PACL Dacl;
+} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
+typedef enum _TOKEN_INFORMATION_CLASS {
+	TokenUser=1,TokenGroups,TokenPrivileges,TokenOwner,
+	TokenPrimaryGroup,TokenDefaultDacl,TokenSource,TokenType,
+	TokenImpersonationLevel,TokenStatistics,TokenRestrictedSids,
+	TokenSessionId
+} TOKEN_INFORMATION_CLASS;
+typedef enum _SID_NAME_USE {
+	SidTypeUser=1,SidTypeGroup,SidTypeDomain,SidTypeAlias,SidTypeWellKnownGroup,
+	SidTypeDeletedAccount,SidTypeInvalid,SidTypeUnknown
+} SID_NAME_USE,*PSID_NAME_USE;
+typedef struct _QUOTA_LIMITS {
+	SIZE_T PagedPoolLimit;
+	SIZE_T NonPagedPoolLimit;
+	SIZE_T MinimumWorkingSetSize;
+	SIZE_T MaximumWorkingSetSize;
+	SIZE_T PagefileLimit;
+	LARGE_INTEGER TimeLimit;
+} QUOTA_LIMITS,*PQUOTA_LIMITS;
+typedef struct _IO_COUNTERS {
+	ULONGLONG  ReadOperationCount;
+	ULONGLONG  WriteOperationCount;
+	ULONGLONG  OtherOperationCount;
+	ULONGLONG ReadTransferCount;
+	ULONGLONG WriteTransferCount;
+	ULONGLONG OtherTransferCount;
+} IO_COUNTERS, *PIO_COUNTERS;
+typedef struct _FILE_NOTIFY_INFORMATION {
+	DWORD NextEntryOffset;
+	DWORD Action;
+	DWORD FileNameLength;
+	WCHAR FileName[1];
+} FILE_NOTIFY_INFORMATION,*PFILE_NOTIFY_INFORMATION;
+typedef struct _TAPE_ERASE {
+	DWORD Type;
+	BOOLEAN Immediate;
+} TAPE_ERASE,*PTAPE_ERASE;
+typedef struct _TAPE_GET_DRIVE_PARAMETERS {
+	BOOLEAN ECC;
+	BOOLEAN Compression;
+	BOOLEAN DataPadding;
+	BOOLEAN ReportSetmarks;
+ 	DWORD DefaultBlockSize;
+ 	DWORD MaximumBlockSize;
+ 	DWORD MinimumBlockSize;
+ 	DWORD MaximumPartitionCount;
+ 	DWORD FeaturesLow;
+ 	DWORD FeaturesHigh;
+ 	DWORD EOTWarningZoneSize;
+} TAPE_GET_DRIVE_PARAMETERS,*PTAPE_GET_DRIVE_PARAMETERS;
+typedef struct _TAPE_GET_MEDIA_PARAMETERS {
+	LARGE_INTEGER Capacity;
+	LARGE_INTEGER Remaining;
+	DWORD BlockSize;
+	DWORD PartitionCount;
+	BOOLEAN WriteProtected;
+} TAPE_GET_MEDIA_PARAMETERS,*PTAPE_GET_MEDIA_PARAMETERS;
+typedef struct _TAPE_GET_POSITION {
+	ULONG Type;
+	ULONG Partition;
+	ULONG OffsetLow;
+	ULONG OffsetHigh;
+} TAPE_GET_POSITION,*PTAPE_GET_POSITION;
+typedef struct _TAPE_PREPARE {
+	DWORD Operation;
+	BOOLEAN Immediate;
+} TAPE_PREPARE,*PTAPE_PREPARE;
+typedef struct _TAPE_SET_DRIVE_PARAMETERS {
+	BOOLEAN ECC;
+	BOOLEAN Compression;
+	BOOLEAN DataPadding;
+	BOOLEAN ReportSetmarks;
+	ULONG EOTWarningZoneSize;
+} TAPE_SET_DRIVE_PARAMETERS,*PTAPE_SET_DRIVE_PARAMETERS;
+typedef struct _TAPE_SET_MEDIA_PARAMETERS {
+	ULONG BlockSize;
+} TAPE_SET_MEDIA_PARAMETERS,*PTAPE_SET_MEDIA_PARAMETERS;
+typedef struct _TAPE_SET_POSITION {
+	DWORD Method;
+	DWORD Partition;
+	LARGE_INTEGER Offset;
+	BOOLEAN Immediate;
+} TAPE_SET_POSITION,*PTAPE_SET_POSITION;
+typedef struct _TAPE_WRITE_MARKS {
+	DWORD Type;
+	DWORD Count;
+	BOOLEAN Immediate;
+} TAPE_WRITE_MARKS,*PTAPE_WRITE_MARKS;
+typedef struct _TAPE_CREATE_PARTITION {
+	DWORD Method;
+	DWORD Count;
+	DWORD Size;
+} TAPE_CREATE_PARTITION,*PTAPE_CREATE_PARTITION;
+typedef struct _MEMORY_BASIC_INFORMATION {
+	PVOID BaseAddress;
+	PVOID AllocationBase;
+	DWORD AllocationProtect;
+	DWORD RegionSize;
+	DWORD State;
+	DWORD Protect;
+	DWORD Type;
+} MEMORY_BASIC_INFORMATION,*PMEMORY_BASIC_INFORMATION;
+typedef struct _MESSAGE_RESOURCE_ENTRY {
+	WORD Length;
+	WORD Flags;
+	BYTE Text[1];
+} MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY;
+typedef struct _MESSAGE_RESOURCE_BLOCK {
+	DWORD LowId;
+	DWORD HighId;
+	DWORD OffsetToEntries;
+} MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK;
+typedef struct _MESSAGE_RESOURCE_DATA {
+	DWORD NumberOfBlocks;
+	MESSAGE_RESOURCE_BLOCK Blocks[1];
+} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA;
+typedef struct _LIST_ENTRY {
+	struct _LIST_ENTRY *Flink;
+	struct _LIST_ENTRY *Blink;
+} LIST_ENTRY,*PLIST_ENTRY;
+typedef struct _RTL_CRITICAL_SECTION_DEBUG {
+	WORD Type;
+	WORD CreatorBackTraceIndex;
+	struct _RTL_CRITICAL_SECTION *CriticalSection;
+	LIST_ENTRY ProcessLocksList;
+	DWORD EntryCount;
+	DWORD ContentionCount;
+	DWORD Spare[2];
+} RTL_CRITICAL_SECTION_DEBUG,*PRTL_CRITICAL_SECTION_DEBUG;
+typedef struct _RTL_CRITICAL_SECTION {
+	PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
+	LONG LockCount;
+	LONG RecursionCount;
+	HANDLE OwningThread;
+	HANDLE LockSemaphore;
+	DWORD Reserved;
+} RTL_CRITICAL_SECTION,*PRTL_CRITICAL_SECTION;
+typedef struct _EVENTLOGRECORD {
+	DWORD Length;
+	DWORD Reserved;
+	DWORD RecordNumber;
+	DWORD TimeGenerated;
+	DWORD TimeWritten;
+	DWORD EventID;
+	WORD EventType;
+	WORD NumStrings;
+	WORD EventCategory;
+	WORD ReservedFlags;
+	DWORD ClosingRecordNumber;
+	DWORD StringOffset;
+	DWORD UserSidLength;
+	DWORD UserSidOffset;
+	DWORD DataLength;
+	DWORD DataOffset;
+} EVENTLOGRECORD,*PEVENTLOGRECORD;
+typedef struct _OSVERSIONINFOA {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	CHAR szCSDVersion[128];
+} OSVERSIONINFOA,*POSVERSIONINFOA,*LPOSVERSIONINFOA;
+typedef struct _OSVERSIONINFOW {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	WCHAR szCSDVersion[128];
+} OSVERSIONINFOW,*POSVERSIONINFOW,*LPOSVERSIONINFOW;
+typedef struct _OSVERSIONINFOEXA {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	CHAR szCSDVersion[128];
+	WORD wServicePackMajor;
+	WORD wServicePackMinor;
+	WORD wSuiteMask;
+	BYTE wProductType;
+	BYTE wReserved;
+} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
+typedef struct _OSVERSIONINFOEXW {
+	DWORD dwOSVersionInfoSize;
+	DWORD dwMajorVersion;
+	DWORD dwMinorVersion;
+	DWORD dwBuildNumber;
+	DWORD dwPlatformId;
+	WCHAR szCSDVersion[128];
+	WORD wServicePackMajor;
+	WORD wServicePackMinor;
+	WORD wSuiteMask;
+	BYTE wProductType;
+	BYTE wReserved;
+} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW;
+#pragma pack(push,2)
+typedef struct _IMAGE_VXD_HEADER {
+	WORD e32_magic;
+	BYTE e32_border;
+	BYTE e32_worder;
+	DWORD e32_level;
+	WORD e32_cpu;
+	WORD e32_os;
+	DWORD e32_ver;
+	DWORD e32_mflags;
+	DWORD e32_mpages;
+	DWORD e32_startobj;
+	DWORD e32_eip;
+	DWORD e32_stackobj;
+	DWORD e32_esp;
+	DWORD e32_pagesize;
+	DWORD e32_lastpagesize;
+	DWORD e32_fixupsize;
+	DWORD e32_fixupsum;
+	DWORD e32_ldrsize;
+	DWORD e32_ldrsum;
+	DWORD e32_objtab;
+	DWORD e32_objcnt;
+	DWORD e32_objmap;
+	DWORD e32_itermap;
+	DWORD e32_rsrctab;
+	DWORD e32_rsrccnt;
+	DWORD e32_restab;
+	DWORD e32_enttab;
+	DWORD e32_dirtab;
+	DWORD e32_dircnt;
+	DWORD e32_fpagetab;
+	DWORD e32_frectab;
+	DWORD e32_impmod;
+	DWORD e32_impmodcnt;
+	DWORD e32_impproc;
+	DWORD e32_pagesum;
+	DWORD e32_datapage;
+	DWORD e32_preload;
+	DWORD e32_nrestab;
+	DWORD e32_cbnrestab;
+	DWORD e32_nressum;
+	DWORD e32_autodata;
+	DWORD e32_debuginfo;
+	DWORD e32_debuglen;
+	DWORD e32_instpreload;
+	DWORD e32_instdemand;
+	DWORD e32_heapsize;
+	BYTE e32_res3[12];
+	DWORD e32_winresoff;
+	DWORD e32_winreslen;
+	WORD e32_devid;
+	WORD e32_ddkver;
+} IMAGE_VXD_HEADER,*PIMAGE_VXD_HEADER;
+#pragma pack(pop)
+#pragma pack(push,4)
+typedef struct _IMAGE_FILE_HEADER {
+	WORD Machine;
+	WORD NumberOfSections;
+	DWORD TimeDateStamp;
+	DWORD PointerToSymbolTable;
+	DWORD NumberOfSymbols;
+	WORD SizeOfOptionalHeader;
+	WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+typedef struct _IMAGE_DATA_DIRECTORY {
+	DWORD VirtualAddress;
+	DWORD Size;
+} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
+typedef struct _IMAGE_OPTIONAL_HEADER {
+	WORD Magic;
+	BYTE MajorLinkerVersion;
+	BYTE MinorLinkerVersion;
+	DWORD SizeOfCode;
+	DWORD SizeOfInitializedData;
+	DWORD SizeOfUninitializedData;
+	DWORD AddressOfEntryPoint;
+	DWORD BaseOfCode;
+	DWORD BaseOfData;
+	DWORD ImageBase;
+	DWORD SectionAlignment;
+	DWORD FileAlignment;
+	WORD MajorOperatingSystemVersion;
+	WORD MinorOperatingSystemVersion;
+	WORD MajorImageVersion;
+	WORD MinorImageVersion;
+	WORD MajorSubsystemVersion;
+	WORD MinorSubsystemVersion;
+	DWORD Reserved1;
+	DWORD SizeOfImage;
+	DWORD SizeOfHeaders;
+	DWORD CheckSum;
+	WORD Subsystem;
+	WORD DllCharacteristics;
+	DWORD SizeOfStackReserve;
+	DWORD SizeOfStackCommit;
+	DWORD SizeOfHeapReserve;
+	DWORD SizeOfHeapCommit;
+	DWORD LoaderFlags;
+	DWORD NumberOfRvaAndSizes;
+	IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER,*PIMAGE_OPTIONAL_HEADER;
+typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+	WORD Magic;
+	BYTE MajorLinkerVersion;
+	BYTE MinorLinkerVersion;
+	DWORD SizeOfCode;
+	DWORD SizeOfInitializedData;
+	DWORD SizeOfUninitializedData;
+	DWORD AddressOfEntryPoint;
+	DWORD BaseOfCode;
+	DWORD BaseOfData;
+	DWORD BaseOfBss;
+	DWORD GprMask;
+	DWORD CprMask[4];
+	DWORD GpValue;
+} IMAGE_ROM_OPTIONAL_HEADER,*PIMAGE_ROM_OPTIONAL_HEADER;
+#pragma pack(pop)
+#pragma pack(push,2)
+typedef struct _IMAGE_DOS_HEADER {
+	WORD e_magic;
+	WORD e_cblp;
+	WORD e_cp;
+	WORD e_crlc;
+	WORD e_cparhdr;
+	WORD e_minalloc;
+	WORD e_maxalloc;
+	WORD e_ss;
+	WORD e_sp;
+	WORD e_csum;
+	WORD e_ip;
+	WORD e_cs;
+	WORD e_lfarlc;
+	WORD e_ovno;
+	WORD e_res[4];
+	WORD e_oemid;
+	WORD e_oeminfo;
+	WORD e_res2[10];
+	LONG e_lfanew;
+} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
+typedef struct _IMAGE_OS2_HEADER {
+	WORD ne_magic;
+	CHAR ne_ver;
+	CHAR ne_rev;
+	WORD ne_enttab;
+	WORD ne_cbenttab;
+	LONG ne_crc;
+	WORD ne_flags;
+	WORD ne_autodata;
+	WORD ne_heap;
+	WORD ne_stack;
+	LONG ne_csip;
+	LONG ne_sssp;
+	WORD ne_cseg;
+	WORD ne_cmod;
+	WORD ne_cbnrestab;
+	WORD ne_segtab;
+	WORD ne_rsrctab;
+	WORD ne_restab;
+	WORD ne_modtab;
+	WORD ne_imptab;
+	LONG ne_nrestab;
+	WORD ne_cmovent;
+	WORD ne_align;
+	WORD ne_cres;
+	BYTE ne_exetyp;
+	BYTE ne_flagsothers;
+	WORD ne_pretthunks;
+	WORD ne_psegrefbytes;
+	WORD ne_swaparea;
+	WORD ne_expver;
+} IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER;
+#pragma pack(pop)
+#pragma pack(push,4)
+typedef struct _IMAGE_NT_HEADERS {
+	DWORD Signature;
+	IMAGE_FILE_HEADER FileHeader;
+	IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS;
+typedef struct _IMAGE_ROM_HEADERS {
+	IMAGE_FILE_HEADER FileHeader;
+	IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_ROM_HEADERS,*PIMAGE_ROM_HEADERS;
+typedef struct _IMAGE_SECTION_HEADER {
+	BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+	union {
+		DWORD PhysicalAddress;
+		DWORD VirtualSize;
+	} Misc;
+	DWORD VirtualAddress;
+	DWORD SizeOfRawData;
+	DWORD PointerToRawData;
+	DWORD PointerToRelocations;
+	DWORD PointerToLinenumbers;
+	WORD NumberOfRelocations;
+	WORD NumberOfLinenumbers;
+	DWORD Characteristics;
+} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
+#pragma pack(pop)
+#pragma pack(push,2)
+typedef struct _IMAGE_SYMBOL {
+	union {
+		BYTE ShortName[8];
+		struct {
+			DWORD Short;
+			DWORD Long;
+		} Name;
+		PBYTE LongName[2];
+	} N;
+	DWORD Value;
+	SHORT SectionNumber;
+	WORD Type;
+	BYTE StorageClass;
+	BYTE NumberOfAuxSymbols;
+} IMAGE_SYMBOL,*PIMAGE_SYMBOL;
+typedef union _IMAGE_AUX_SYMBOL {
+	struct {
+		DWORD TagIndex;
+		union {
+			struct {
+				WORD Linenumber;
+				WORD Size;
+			} LnSz;
+			DWORD TotalSize;
+		} Misc;
+		union {
+			struct {
+				DWORD PointerToLinenumber;
+				DWORD PointerToNextFunction;
+			} Function;
+			struct {
+				WORD Dimension[4];
+			} Array;
+		} FcnAry;
+		WORD TvIndex;
+	} Sym;
+	struct {
+		BYTE Name[IMAGE_SIZEOF_SYMBOL];
+	} File;
+	struct {
+		DWORD Length;
+		WORD NumberOfRelocations;
+		WORD NumberOfLinenumbers;
+		DWORD CheckSum;
+		SHORT Number;
+		BYTE Selection;
+	} Section;
+} IMAGE_AUX_SYMBOL,*PIMAGE_AUX_SYMBOL;
+typedef struct _IMAGE_COFF_SYMBOLS_HEADER {
+	DWORD NumberOfSymbols;
+	DWORD LvaToFirstSymbol;
+	DWORD NumberOfLinenumbers;
+	DWORD LvaToFirstLinenumber;
+	DWORD RvaToFirstByteOfCode;
+	DWORD RvaToLastByteOfCode;
+	DWORD RvaToFirstByteOfData;
+	DWORD RvaToLastByteOfData;
+} IMAGE_COFF_SYMBOLS_HEADER,*PIMAGE_COFF_SYMBOLS_HEADER;
+typedef struct _IMAGE_RELOCATION {
+	_ANONYMOUS_UNION union {
+		DWORD VirtualAddress;
+		DWORD RelocCount;
+	} DUMMYUNIONNAME;
+	DWORD SymbolTableIndex;
+	WORD Type;
+} IMAGE_RELOCATION,*PIMAGE_RELOCATION;
+#pragma pack(pop)
+#pragma pack(push,4)
+typedef struct _IMAGE_BASE_RELOCATION {
+	DWORD VirtualAddress;
+	DWORD SizeOfBlock;
+} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
+#pragma pack(pop)
+#pragma pack(push,2)
+typedef struct _IMAGE_LINENUMBER {
+	union {
+		DWORD SymbolTableIndex;
+		DWORD VirtualAddress;
+	} Type;
+	WORD Linenumber;
+} IMAGE_LINENUMBER,*PIMAGE_LINENUMBER;
+#pragma pack(pop)
+#pragma pack(push,4)
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+	BYTE Name[16];
+	BYTE Date[12];
+	BYTE UserID[6];
+	BYTE GroupID[6];
+	BYTE Mode[8];
+	BYTE Size[10];
+	BYTE EndHeader[2];
+} IMAGE_ARCHIVE_MEMBER_HEADER,*PIMAGE_ARCHIVE_MEMBER_HEADER;
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+	DWORD Characteristics;
+	DWORD TimeDateStamp;
+	WORD MajorVersion;
+	WORD MinorVersion;
+	DWORD Name;
+	DWORD Base;
+	DWORD NumberOfFunctions;
+	DWORD NumberOfNames;
+	PDWORD *AddressOfFunctions;
+	PDWORD *AddressOfNames;
+	PWORD *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+typedef struct _IMAGE_IMPORT_BY_NAME {
+	WORD Hint;
+	BYTE Name[1];
+} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
+typedef struct _IMAGE_THUNK_DATA {
+	union {
+		PBYTE ForwarderString;
+		PDWORD Function;
+		DWORD Ordinal;
+		PIMAGE_IMPORT_BY_NAME AddressOfData;
+	} u1;
+} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+	_ANONYMOUS_UNION union {
+		DWORD Characteristics;
+		PIMAGE_THUNK_DATA OriginalFirstThunk;
+	} DUMMYUNIONNAME;
+	DWORD TimeDateStamp;
+	DWORD ForwarderChain;
+	DWORD Name;
+	PIMAGE_THUNK_DATA FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
+typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
+	DWORD TimeDateStamp;
+	WORD OffsetModuleName;
+	WORD NumberOfModuleForwarderRefs;
+} IMAGE_BOUND_IMPORT_DESCRIPTOR,*PIMAGE_BOUND_IMPORT_DESCRIPTOR;
+typedef struct _IMAGE_BOUND_FORWARDER_REF {
+	DWORD TimeDateStamp;
+	WORD OffsetModuleName;
+	WORD Reserved;
+} IMAGE_BOUND_FORWARDER_REF,*PIMAGE_BOUND_FORWARDER_REF;
+typedef void(NTAPI *PIMAGE_TLS_CALLBACK)(PVOID,DWORD,PVOID);
+typedef struct _IMAGE_TLS_DIRECTORY {
+	DWORD StartAddressOfRawData;
+	DWORD EndAddressOfRawData;
+	PDWORD AddressOfIndex;
+	PIMAGE_TLS_CALLBACK *AddressOfCallBacks;
+	DWORD SizeOfZeroFill;
+	DWORD Characteristics;
+} IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY;
+typedef struct _IMAGE_RESOURCE_DIRECTORY {
+	DWORD Characteristics;
+	DWORD TimeDateStamp;
+	WORD MajorVersion;
+	WORD MinorVersion;
+	WORD NumberOfNamedEntries;
+	WORD NumberOfIdEntries;
+} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
+_ANONYMOUS_STRUCT typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
+	_ANONYMOUS_UNION union {
+		_ANONYMOUS_STRUCT struct {
+			DWORD NameOffset:31;
+			DWORD NameIsString:1;
+		}DUMMYSTRUCTNAME;
+		DWORD Name;
+		WORD Id;
+	} DUMMYUNIONNAME;
+	_ANONYMOUS_UNION union {
+		DWORD OffsetToData;
+		_ANONYMOUS_STRUCT struct {
+			DWORD OffsetToDirectory:31;
+			DWORD DataIsDirectory:1;
+		} DUMMYSTRUCTNAME2;
+	} DUMMYUNIONNAME2;
+} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
+typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
+	WORD Length;
+	CHAR NameString[1];
+} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
+typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
+	WORD Length;
+	WCHAR NameString[1];
+} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U;
+typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+	DWORD OffsetToData;
+	DWORD Size;
+	DWORD CodePage;
+	DWORD Reserved;
+} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
+	DWORD Characteristics;
+	DWORD TimeDateStamp;
+	WORD MajorVersion;
+	WORD MinorVersion;
+	DWORD GlobalFlagsClear;
+	DWORD GlobalFlagsSet;
+	DWORD CriticalSectionDefaultTimeout;
+	DWORD DeCommitFreeBlockThreshold;
+	DWORD DeCommitTotalFreeThreshold;
+	PVOID LockPrefixTable;
+	DWORD MaximumAllocationSize;
+	DWORD VirtualMemoryThreshold;
+	DWORD ProcessHeapFlags;
+	DWORD Reserved[4];
+} IMAGE_LOAD_CONFIG_DIRECTORY,*PIMAGE_LOAD_CONFIG_DIRECTORY;
+typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY {
+	DWORD BeginAddress;
+	DWORD EndAddress;
+	PVOID ExceptionHandler;
+	PVOID HandlerData;
+	DWORD PrologEndAddress;
+} IMAGE_RUNTIME_FUNCTION_ENTRY,*PIMAGE_RUNTIME_FUNCTION_ENTRY;
+typedef struct _IMAGE_DEBUG_DIRECTORY {
+	DWORD Characteristics;
+	DWORD TimeDateStamp;
+	WORD MajorVersion;
+	WORD MinorVersion;
+	DWORD Type;
+	DWORD SizeOfData;
+	DWORD AddressOfRawData;
+	DWORD PointerToRawData;
+} IMAGE_DEBUG_DIRECTORY,*PIMAGE_DEBUG_DIRECTORY;
+typedef struct _FPO_DATA {
+	DWORD ulOffStart;
+	DWORD cbProcSize;
+	DWORD cdwLocals;
+	WORD cdwParams;
+	WORD cbProlog:8;
+	WORD cbRegs:3;
+	WORD fHasSEH:1;
+	WORD fUseBP:1;
+	WORD reserved:1;
+	WORD cbFrame:2;
+} FPO_DATA,*PFPO_DATA;
+typedef struct _IMAGE_DEBUG_MISC {
+	DWORD DataType;
+	DWORD Length;
+	BOOLEAN Unicode;
+	BYTE Reserved[3];
+	BYTE Data[1];
+} IMAGE_DEBUG_MISC,*PIMAGE_DEBUG_MISC;
+typedef struct _IMAGE_FUNCTION_ENTRY {
+	DWORD StartingAddress;
+	DWORD EndingAddress;
+	DWORD EndOfPrologue;
+} IMAGE_FUNCTION_ENTRY,*PIMAGE_FUNCTION_ENTRY;
+typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
+	WORD Signature;
+	WORD Flags;
+	WORD Machine;
+	WORD Characteristics;
+	DWORD TimeDateStamp;
+	DWORD CheckSum;
+	DWORD ImageBase;
+	DWORD SizeOfImage;
+	DWORD NumberOfSections;
+	DWORD ExportedNamesSize;
+	DWORD DebugDirectorySize;
+	DWORD Reserved[3];
+} IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER;
+#pragma pack(pop)
+typedef enum _CM_SERVICE_NODE_TYPE {
+	DriverType=SERVICE_KERNEL_DRIVER,
+	FileSystemType=SERVICE_FILE_SYSTEM_DRIVER,
+	Win32ServiceOwnProcess=SERVICE_WIN32_OWN_PROCESS,
+	Win32ServiceShareProcess=SERVICE_WIN32_SHARE_PROCESS,
+	AdapterType=SERVICE_ADAPTER,
+	RecognizerType=SERVICE_RECOGNIZER_DRIVER
+} SERVICE_NODE_TYPE;
+typedef enum _CM_SERVICE_LOAD_TYPE {
+	BootLoad=SERVICE_BOOT_START,
+	SystemLoad=SERVICE_SYSTEM_START,
+	AutoLoad=SERVICE_AUTO_START,
+	DemandLoad=SERVICE_DEMAND_START,
+	DisableLoad=SERVICE_DISABLED
+} SERVICE_LOAD_TYPE;
+typedef enum _CM_ERROR_CONTROL_TYPE {
+	IgnoreError=SERVICE_ERROR_IGNORE,
+	NormalError=SERVICE_ERROR_NORMAL,
+	SevereError=SERVICE_ERROR_SEVERE,
+	CriticalError=SERVICE_ERROR_CRITICAL
+} SERVICE_ERROR_TYPE;
+typedef struct _NT_TIB {
+	struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+	PVOID StackBase;
+	PVOID StackLimit;
+	PVOID SubSystemTib;
+	_ANONYMOUS_UNION union {
+		PVOID FiberData;
+		DWORD Version;
+	} DUMMYUNIONNAME;
+	PVOID ArbitraryUserPointer;
+	struct _NT_TIB *Self;
+} NT_TIB,*PNT_TIB;
+typedef struct _REPARSE_DATA_BUFFER {
+	DWORD  ReparseTag;
+	WORD   ReparseDataLength;
+	WORD   Reserved;
+	_ANONYMOUS_UNION union {
+		struct {
+			WORD   SubstituteNameOffset;
+			WORD   SubstituteNameLength;
+			WORD   PrintNameOffset;
+			WORD   PrintNameLength;
+			WCHAR PathBuffer[1];
+		} SymbolicLinkReparseBuffer;
+		struct {
+			WORD   SubstituteNameOffset;
+			WORD   SubstituteNameLength;
+			WORD   PrintNameOffset;
+			WORD   PrintNameLength;
+			WCHAR PathBuffer[1];
+		} MountPointReparseBuffer;
+		struct {
+			BYTE   DataBuffer[1];
+		} GenericReparseBuffer;
+	} DUMMYUNIONNAME;
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+typedef struct _REPARSE_GUID_DATA_BUFFER {
+	DWORD  ReparseTag;
+	WORD   ReparseDataLength;
+	WORD   Reserved;
+	GUID   ReparseGuid;
+	struct {
+		BYTE   DataBuffer[1];
+	} GenericReparseBuffer;
+} REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;
+typedef struct _REPARSE_POINT_INFORMATION {
+	WORD   ReparseDataLength;
+	WORD   UnparsedNameLength;
+} REPARSE_POINT_INFORMATION, *PREPARSE_POINT_INFORMATION;
+
+#ifdef UNICODE
+typedef OSVERSIONINFOW OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO;
+typedef OSVERSIONINFOEXW OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX;
+#else
+typedef OSVERSIONINFOA OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO;
+typedef OSVERSIONINFOEXA OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX;
+#endif
+
+#if defined(__GNUC__)
+
+PVOID GetCurrentFiber(void);
+PVOID GetFiberData(void);
+
+PVOID GetCurrentFiber(void);
+extern __inline__ PVOID GetCurrentFiber(void)
+{
+    void* ret;
+    __asm__ volatile (
+	      "movl	%%fs:0x10,%0"
+	        : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */
+	        :
+		);
+    return ret;
+}
+
+PVOID GetFiberData(void);
+extern __inline__ PVOID GetFiberData(void)
+{
+    void* ret;
+    __asm__ volatile (
+	      "movl	%%fs:0x10,%0\n"
+	      "movl	(%0),%0"
+	       : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */
+	       :
+	      );
+    return ret;
+}
+
+#else
+
+extern PVOID GetCurrentFiber(void);
+#pragma aux GetCurrentFiber = \
+        "mov	eax, dword ptr fs:0x10" \
+        value [eax] \
+        modify [eax];
+
+extern PVOID GetFiberData(void);
+#pragma aux GetFiberData = \
+	"mov	eax, dword ptr fs:0x10" \
+	"mov	eax, [eax]" \
+        value [eax] \
+        modify [eax];
+        
+#endif /* __GNUC__ */
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/tinyc/win32/include/winapi/winreg.h b/tinyc/win32/include/winapi/winreg.h
new file mode 100755
index 000000000..21020b833
--- /dev/null
+++ b/tinyc/win32/include/winapi/winreg.h
@@ -0,0 +1,159 @@
+#ifndef _WINREG_H
+#define _WINREG_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define HKEY_CLASSES_ROOT	((HKEY)0x80000000)
+#define HKEY_CURRENT_USER	((HKEY)0x80000001)
+#define HKEY_LOCAL_MACHINE	((HKEY)0x80000002)
+#define HKEY_USERS	((HKEY)0x80000003)
+#define HKEY_PERFORMANCE_DATA	((HKEY)0x80000004)
+#define HKEY_CURRENT_CONFIG	((HKEY)0x80000005)
+#define HKEY_DYN_DATA	((HKEY)0x80000006)
+#define REG_OPTION_VOLATILE 1
+#define REG_OPTION_NON_VOLATILE 0
+#define REG_CREATED_NEW_KEY 1
+#define REG_OPENED_EXISTING_KEY 2
+#define REG_NONE 0
+#define REG_SZ 1
+#define REG_EXPAND_SZ 2
+#define REG_BINARY 3
+#define REG_DWORD 4
+#define REG_DWORD_BIG_ENDIAN 5
+#define REG_DWORD_LITTLE_ENDIAN 4
+#define REG_LINK 6
+#define REG_MULTI_SZ 7
+#define REG_RESOURCE_LIST 8
+#define REG_FULL_RESOURCE_DESCRIPTOR 9
+#define REG_RESOURCE_REQUIREMENTS_LIST 10
+#define REG_NOTIFY_CHANGE_NAME 1
+#define REG_NOTIFY_CHANGE_ATTRIBUTES 2
+#define REG_NOTIFY_CHANGE_LAST_SET 4
+#define REG_NOTIFY_CHANGE_SECURITY 8
+
+#ifndef RC_INVOKED
+typedef ACCESS_MASK REGSAM;
+typedef struct value_entA {
+	LPSTR ve_valuename;
+	DWORD ve_valuelen;
+	DWORD ve_valueptr;
+	DWORD ve_type;
+} VALENTA,*PVALENTA;
+typedef struct value_entW {
+	LPWSTR ve_valuename;
+	DWORD ve_valuelen;
+	DWORD ve_valueptr;
+	DWORD ve_type;
+} VALENTW,*PVALENTW;
+BOOL WINAPI AbortSystemShutdownA(LPCSTR);
+BOOL WINAPI AbortSystemShutdownW(LPCWSTR);
+BOOL WINAPI InitiateSystemShutdownA(LPSTR,LPSTR,DWORD,BOOL,BOOL);
+BOOL WINAPI InitiateSystemShutdownW(LPWSTR,LPWSTR,DWORD,BOOL,BOOL);
+LONG WINAPI RegCloseKey(HKEY);
+LONG WINAPI RegConnectRegistryA(LPSTR,HKEY,PHKEY);
+LONG WINAPI RegConnectRegistryW(LPWSTR,HKEY,PHKEY);
+LONG WINAPI RegCreateKeyA(HKEY,LPCSTR,PHKEY);
+LONG WINAPI RegCreateKeyExA(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,LPSECURITY_ATTRIBUTES,PHKEY,PDWORD);
+LONG WINAPI RegCreateKeyExW(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,LPSECURITY_ATTRIBUTES,PHKEY,PDWORD);
+LONG WINAPI RegCreateKeyW(HKEY,LPCWSTR,PHKEY);
+LONG WINAPI RegDeleteKeyA(HKEY,LPCSTR);
+LONG WINAPI RegDeleteKeyW(HKEY,LPCWSTR);
+LONG WINAPI RegDeleteValueA (HKEY,LPCSTR);
+LONG WINAPI RegDeleteValueW(HKEY,LPCWSTR);
+LONG WINAPI RegEnumKeyA (HKEY,DWORD,LPSTR,DWORD);
+LONG WINAPI RegEnumKeyW(HKEY,DWORD,LPWSTR,DWORD);
+LONG WINAPI RegEnumKeyExA(HKEY,DWORD,LPSTR,PDWORD,PDWORD,LPSTR,PDWORD,PFILETIME);
+LONG WINAPI RegEnumKeyExW(HKEY,DWORD,LPWSTR,PDWORD,PDWORD,LPWSTR,PDWORD,PFILETIME);
+LONG WINAPI RegEnumValueA(HKEY,DWORD,LPSTR,PDWORD,PDWORD,PDWORD,LPBYTE,PDWORD);
+LONG WINAPI RegEnumValueW(HKEY,DWORD,LPWSTR,PDWORD,PDWORD,PDWORD,LPBYTE,PDWORD);
+LONG WINAPI RegFlushKey(HKEY);
+LONG WINAPI RegGetKeySecurity(HKEY,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,PDWORD);
+LONG WINAPI RegLoadKeyA(HKEY,LPCSTR,LPCSTR);
+LONG WINAPI RegLoadKeyW(HKEY,LPCWSTR,LPCWSTR);
+LONG WINAPI RegNotifyChangeKeyValue(HKEY,BOOL,DWORD,HANDLE,BOOL);
+LONG WINAPI RegOpenKeyA(HKEY,LPCSTR,PHKEY);
+LONG WINAPI RegOpenKeyExA(HKEY,LPCSTR,DWORD,REGSAM,PHKEY);
+LONG WINAPI RegOpenKeyExW(HKEY,LPCWSTR,DWORD,REGSAM,PHKEY);
+LONG WINAPI RegOpenKeyW(HKEY,LPCWSTR,PHKEY);
+LONG WINAPI RegQueryInfoKeyA(HKEY,LPSTR,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PFILETIME);
+LONG WINAPI RegQueryInfoKeyW(HKEY,LPWSTR,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PDWORD,PFILETIME);
+LONG WINAPI RegQueryMultipleValuesA(HKEY,PVALENTA,DWORD,LPSTR,PDWORD);
+LONG WINAPI RegQueryMultipleValuesW(HKEY,PVALENTW,DWORD,LPWSTR,PDWORD);
+LONG WINAPI RegQueryValueA(HKEY,LPCSTR,LPSTR,PLONG);
+LONG WINAPI RegQueryValueExA (HKEY,LPCSTR,PDWORD,PDWORD,LPBYTE,PDWORD);
+LONG WINAPI RegQueryValueExW(HKEY,LPCWSTR,PDWORD,PDWORD,LPBYTE,PDWORD);
+LONG WINAPI RegQueryValueW(HKEY,LPCWSTR,LPWSTR,PLONG);
+LONG WINAPI RegReplaceKeyA(HKEY,LPCSTR,LPCSTR,LPCSTR);
+LONG WINAPI RegReplaceKeyW(HKEY,LPCWSTR,LPCWSTR,LPCWSTR);
+LONG WINAPI RegRestoreKeyA (HKEY,LPCSTR,DWORD);
+LONG WINAPI RegRestoreKeyW(HKEY,LPCWSTR,DWORD);
+LONG WINAPI RegSaveKeyA(HKEY,LPCSTR,LPSECURITY_ATTRIBUTES);
+LONG WINAPI RegSaveKeyW(HKEY,LPCWSTR,LPSECURITY_ATTRIBUTES);
+LONG WINAPI RegSetKeySecurity(HKEY,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+LONG WINAPI RegSetValueA(HKEY,LPCSTR,DWORD,LPCSTR,DWORD);
+LONG WINAPI RegSetValueExA(HKEY,LPCSTR,DWORD,DWORD,const BYTE*,DWORD);
+LONG WINAPI RegSetValueExW(HKEY,LPCWSTR,DWORD,DWORD,const BYTE*,DWORD);
+LONG WINAPI RegSetValueW(HKEY,LPCWSTR,DWORD,LPCWSTR,DWORD);
+LONG WINAPI RegUnLoadKeyA(HKEY,LPCSTR);
+LONG WINAPI RegUnLoadKeyW(HKEY,LPCWSTR);
+
+#ifdef UNICODE
+typedef VALENTW VALENT,*PVALENT;
+#define AbortSystemShutdown AbortSystemShutdownW
+#define InitiateSystemShutdown InitiateSystemShutdownW
+#define RegConnectRegistry RegConnectRegistryW
+#define RegCreateKey RegCreateKeyW
+#define RegCreateKeyEx RegCreateKeyExW
+#define RegDeleteKey RegDeleteKeyW
+#define RegDeleteValue RegDeleteValueW
+#define RegEnumKey RegEnumKeyW
+#define RegEnumKeyEx RegEnumKeyExW
+#define RegEnumValue RegEnumValueW
+#define RegLoadKey RegLoadKeyW
+#define RegOpenKey RegOpenKeyW
+#define RegOpenKeyEx RegOpenKeyExW
+#define RegQueryInfoKey RegQueryInfoKeyW
+#define RegQueryMultipleValues RegQueryMultipleValuesW
+#define RegQueryValue RegQueryValueW
+#define RegQueryValueEx RegQueryValueExW
+#define RegReplaceKey RegReplaceKeyW
+#define RegRestoreKey RegRestoreKeyW
+#define RegSaveKey RegSaveKeyW
+#define RegSetValue RegSetValueW
+#define RegSetValueEx RegSetValueExW
+#define RegUnLoadKey RegUnLoadKeyW
+#else
+typedef VALENTA VALENT,*PVALENT;
+#define AbortSystemShutdown AbortSystemShutdownA
+#define InitiateSystemShutdown InitiateSystemShutdownA
+#define RegConnectRegistry RegConnectRegistryA
+#define RegCreateKey RegCreateKeyA
+#define RegCreateKeyEx RegCreateKeyExA
+#define RegDeleteKey RegDeleteKeyA
+#define RegDeleteValue RegDeleteValueA
+#define RegEnumKey RegEnumKeyA
+#define RegEnumKeyEx RegEnumKeyExA
+#define RegEnumValue RegEnumValueA
+#define RegLoadKey RegLoadKeyA
+#define RegOpenKey RegOpenKeyA
+#define RegOpenKeyEx RegOpenKeyExA
+#define RegQueryInfoKey RegQueryInfoKeyA
+#define RegQueryMultipleValues RegQueryMultipleValuesA
+#define RegQueryValue RegQueryValueA
+#define RegQueryValueEx RegQueryValueExA
+#define RegReplaceKey RegReplaceKeyA
+#define RegRestoreKey RegRestoreKeyA
+#define RegSaveKey RegSaveKeyA
+#define RegSetValue RegSetValueA
+#define RegSetValueEx RegSetValueExA
+#define RegUnLoadKey RegUnLoadKeyA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/include/winapi/winsvc.h b/tinyc/win32/include/winapi/winsvc.h
new file mode 100755
index 000000000..ae60d46a2
--- /dev/null
+++ b/tinyc/win32/include/winapi/winsvc.h
@@ -0,0 +1,309 @@
+#ifndef _WINSVC_H
+#define _WINSVC_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define SERVICES_ACTIVE_DATABASEA "ServicesActive"
+#define SERVICES_ACTIVE_DATABASEW L"ServicesActive"
+#define SERVICES_FAILED_DATABASEA "ServicesFailed"
+#define SERVICES_FAILED_DATABASEW L"ServicesFailed"
+#define SC_GROUP_IDENTIFIERA '+'
+#define SC_GROUP_IDENTIFIERW L'+'
+#define SC_MANAGER_ALL_ACCESS	0xf003f
+#define SC_MANAGER_CONNECT	1
+#define SC_MANAGER_CREATE_SERVICE	2
+#define SC_MANAGER_ENUMERATE_SERVICE	4
+#define SC_MANAGER_LOCK	8
+#define SC_MANAGER_QUERY_LOCK_STATUS	16
+#define SC_MANAGER_MODIFY_BOOT_CONFIG	32
+#define SERVICE_NO_CHANGE	(-1)
+#define SERVICE_STOPPED	1
+#define SERVICE_START_PENDING	2
+#define SERVICE_STOP_PENDING	3
+#define SERVICE_RUNNING	4
+#define SERVICE_CONTINUE_PENDING	5
+#define SERVICE_PAUSE_PENDING	6
+#define SERVICE_PAUSED	7
+#define SERVICE_ACCEPT_STOP	1
+#define SERVICE_ACCEPT_PAUSE_CONTINUE	2
+#define SERVICE_ACCEPT_SHUTDOWN 4
+#define SERVICE_ACCEPT_PARAMCHANGE    8
+#define SERVICE_ACCEPT_NETBINDCHANGE  16
+#define SERVICE_ACCEPT_HARDWAREPROFILECHANGE   32
+#define SERVICE_ACCEPT_POWEREVENT              64
+#define SERVICE_ACCEPT_SESSIONCHANGE           128
+#define SERVICE_CONTROL_STOP	1
+#define SERVICE_CONTROL_PAUSE	2
+#define SERVICE_CONTROL_CONTINUE	3
+#define SERVICE_CONTROL_INTERROGATE	4
+#define SERVICE_CONTROL_SHUTDOWN	5
+#define SERVICE_CONTROL_PARAMCHANGE     6
+#define SERVICE_CONTROL_NETBINDADD      7
+#define SERVICE_CONTROL_NETBINDREMOVE   8
+#define SERVICE_CONTROL_NETBINDENABLE   9
+#define SERVICE_CONTROL_NETBINDDISABLE  10
+#define SERVICE_CONTROL_DEVICEEVENT     11
+#define SERVICE_CONTROL_HARDWAREPROFILECHANGE 12
+#define SERVICE_CONTROL_POWEREVENT            13
+#define SERVICE_CONTROL_SESSIONCHANGE         14
+#define SERVICE_ACTIVE 1
+#define SERVICE_INACTIVE 2
+#define SERVICE_STATE_ALL 3
+#define SERVICE_QUERY_CONFIG 1
+#define SERVICE_CHANGE_CONFIG 2
+#define SERVICE_QUERY_STATUS 4
+#define SERVICE_ENUMERATE_DEPENDENTS 8
+#define SERVICE_START 16
+#define SERVICE_STOP 32
+#define SERVICE_PAUSE_CONTINUE 64
+#define SERVICE_INTERROGATE 128
+#define SERVICE_USER_DEFINED_CONTROL 256
+#define SERVICE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SERVICE_QUERY_CONFIG|SERVICE_CHANGE_CONFIG|SERVICE_QUERY_STATUS|SERVICE_ENUMERATE_DEPENDENTS|SERVICE_START|SERVICE_STOP|SERVICE_PAUSE_CONTINUE|SERVICE_INTERROGATE|SERVICE_USER_DEFINED_CONTROL)
+#define SERVICE_RUNS_IN_SYSTEM_PROCESS 1
+#define SERVICE_CONFIG_DESCRIPTION     1
+#define SERVICE_CONFIG_FAILURE_ACTIONS 2
+
+typedef struct _SERVICE_STATUS {
+	DWORD dwServiceType;
+	DWORD dwCurrentState;
+	DWORD dwControlsAccepted;
+	DWORD dwWin32ExitCode;
+	DWORD dwServiceSpecificExitCode;
+	DWORD dwCheckPoint;
+	DWORD dwWaitHint;
+} SERVICE_STATUS,*LPSERVICE_STATUS;
+typedef struct _SERVICE_STATUS_PROCESS {
+	DWORD dwServiceType;
+	DWORD dwCurrentState;
+	DWORD dwControlsAccepted;
+	DWORD dwWin32ExitCode;
+	DWORD dwServiceSpecificExitCode;
+	DWORD dwCheckPoint;
+	DWORD dwWaitHint;
+	DWORD dwProcessId;
+	DWORD dwServiceFlags;
+} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;
+typedef enum _SC_STATUS_TYPE {
+	SC_STATUS_PROCESS_INFO = 0
+} SC_STATUS_TYPE;
+typedef enum _SC_ENUM_TYPE {
+        SC_ENUM_PROCESS_INFO = 0
+} SC_ENUM_TYPE;
+typedef struct _ENUM_SERVICE_STATUSA {
+	LPSTR lpServiceName;
+	LPSTR lpDisplayName;
+	SERVICE_STATUS ServiceStatus;
+} ENUM_SERVICE_STATUSA,*LPENUM_SERVICE_STATUSA;
+typedef struct _ENUM_SERVICE_STATUSW {
+	LPWSTR lpServiceName;
+	LPWSTR lpDisplayName;
+	SERVICE_STATUS ServiceStatus;
+} ENUM_SERVICE_STATUSW,*LPENUM_SERVICE_STATUSW;
+typedef struct _ENUM_SERVICE_STATUS_PROCESSA {
+	LPSTR lpServiceName;
+	LPSTR lpDisplayName;
+	SERVICE_STATUS_PROCESS ServiceStatusProcess;
+} ENUM_SERVICE_STATUS_PROCESSA,*LPENUM_SERVICE_STATUS_PROCESSA;
+typedef struct _ENUM_SERVICE_STATUS_PROCESSW {
+	LPWSTR lpServiceName;
+	LPWSTR lpDisplayName;
+	SERVICE_STATUS_PROCESS ServiceStatusProcess;
+} ENUM_SERVICE_STATUS_PROCESSW,*LPENUM_SERVICE_STATUS_PROCESSW;
+typedef struct _QUERY_SERVICE_CONFIGA {
+	DWORD dwServiceType;
+	DWORD dwStartType;
+	DWORD dwErrorControl;
+	LPSTR lpBinaryPathName;
+	LPSTR lpLoadOrderGroup;
+	DWORD dwTagId;
+	LPSTR lpDependencies;
+	LPSTR lpServiceStartName;
+	LPSTR lpDisplayName;
+} QUERY_SERVICE_CONFIGA,*LPQUERY_SERVICE_CONFIGA;
+typedef struct _QUERY_SERVICE_CONFIGW {
+	DWORD dwServiceType;
+	DWORD dwStartType;
+	DWORD dwErrorControl;
+	LPWSTR lpBinaryPathName;
+	LPWSTR lpLoadOrderGroup;
+	DWORD dwTagId;
+	LPWSTR lpDependencies;
+	LPWSTR lpServiceStartName;
+	LPWSTR lpDisplayName;
+} QUERY_SERVICE_CONFIGW,*LPQUERY_SERVICE_CONFIGW;
+typedef struct _QUERY_SERVICE_LOCK_STATUSA {
+	DWORD fIsLocked;
+	LPSTR lpLockOwner;
+	DWORD dwLockDuration;
+} QUERY_SERVICE_LOCK_STATUSA,*LPQUERY_SERVICE_LOCK_STATUSA;
+typedef struct _QUERY_SERVICE_LOCK_STATUSW {
+	DWORD fIsLocked;
+	LPWSTR lpLockOwner;
+	DWORD dwLockDuration;
+} QUERY_SERVICE_LOCK_STATUSW,*LPQUERY_SERVICE_LOCK_STATUSW;
+typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONA)(DWORD,LPSTR*);
+typedef void (WINAPI *LPSERVICE_MAIN_FUNCTIONW)(DWORD,LPWSTR*);
+typedef struct _SERVICE_TABLE_ENTRYA {
+	LPSTR lpServiceName;
+	LPSERVICE_MAIN_FUNCTIONA lpServiceProc;
+} SERVICE_TABLE_ENTRYA,*LPSERVICE_TABLE_ENTRYA;
+typedef struct _SERVICE_TABLE_ENTRYW {
+	LPWSTR lpServiceName;
+	LPSERVICE_MAIN_FUNCTIONW lpServiceProc;
+} SERVICE_TABLE_ENTRYW,*LPSERVICE_TABLE_ENTRYW;
+DECLARE_HANDLE(SC_HANDLE);
+typedef SC_HANDLE *LPSC_HANDLE;
+typedef PVOID SC_LOCK;
+typedef DWORD SERVICE_STATUS_HANDLE;
+typedef VOID(WINAPI *LPHANDLER_FUNCTION)(DWORD);
+typedef DWORD (WINAPI *LPHANDLER_FUNCTION_EX)(DWORD,DWORD,LPVOID,LPVOID);
+typedef struct _SERVICE_DESCRIPTIONA {
+	LPSTR lpDescription;
+} SERVICE_DESCRIPTIONA,*LPSERVICE_DESCRIPTIONA;
+typedef struct _SERVICE_DESCRIPTIONW {
+	LPWSTR lpDescription;
+} SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW;
+typedef enum _SC_ACTION_TYPE {
+        SC_ACTION_NONE          = 0,
+        SC_ACTION_RESTART       = 1,
+        SC_ACTION_REBOOT        = 2,
+        SC_ACTION_RUN_COMMAND   = 3
+} SC_ACTION_TYPE;
+typedef struct _SC_ACTION {
+	SC_ACTION_TYPE	Type;
+	DWORD		Delay;
+} SC_ACTION,*LPSC_ACTION;
+typedef struct _SERVICE_FAILURE_ACTIONSA {
+	DWORD	dwResetPeriod;
+	LPSTR	lpRebootMsg;
+	LPSTR	lpCommand;
+	DWORD	cActions;
+	SC_ACTION * lpsaActions;
+} SERVICE_FAILURE_ACTIONSA,*LPSERVICE_FAILURE_ACTIONSA;
+typedef struct _SERVICE_FAILURE_ACTIONSW {
+	DWORD	dwResetPeriod;
+	LPWSTR	lpRebootMsg;
+	LPWSTR	lpCommand;
+	DWORD	cActions;
+	SC_ACTION * lpsaActions;
+} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW;
+
+BOOL WINAPI ChangeServiceConfigA(SC_HANDLE,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,LPDWORD,LPCSTR,LPCSTR,LPCSTR,LPCSTR);
+BOOL WINAPI ChangeServiceConfigW(SC_HANDLE,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);
+BOOL WINAPI ChangeServiceConfig2A(SC_HANDLE,DWORD,LPVOID);
+BOOL WINAPI ChangeServiceConfig2W(SC_HANDLE,DWORD,LPVOID);
+BOOL WINAPI CloseServiceHandle(SC_HANDLE);
+BOOL WINAPI ControlService(SC_HANDLE,DWORD,LPSERVICE_STATUS);
+SC_HANDLE WINAPI CreateServiceA(SC_HANDLE,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,PDWORD,LPCSTR,LPCSTR,LPCSTR);
+SC_HANDLE WINAPI CreateServiceW(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,PDWORD,LPCWSTR,LPCWSTR,LPCWSTR);
+BOOL WINAPI DeleteService(SC_HANDLE);
+BOOL WINAPI EnumDependentServicesA(SC_HANDLE,DWORD,LPENUM_SERVICE_STATUSA,DWORD,PDWORD,PDWORD);
+BOOL WINAPI EnumDependentServicesW(SC_HANDLE,DWORD,LPENUM_SERVICE_STATUSW,DWORD,PDWORD,PDWORD);
+BOOL WINAPI EnumServicesStatusA(SC_HANDLE,DWORD,DWORD,LPENUM_SERVICE_STATUSA,DWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI EnumServicesStatusW(SC_HANDLE,DWORD,DWORD,LPENUM_SERVICE_STATUSW,DWORD,PDWORD,PDWORD,PDWORD);
+BOOL WINAPI EnumServicesStatusExA(SC_HANDLE,SC_ENUM_TYPE,DWORD,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD,LPDWORD,LPCSTR);
+BOOL WINAPI EnumServicesStatusExW(SC_HANDLE,SC_ENUM_TYPE,DWORD,DWORD,LPBYTE,DWORD,LPDWORD,LPDWORD,LPDWORD,LPCWSTR);
+BOOL WINAPI GetServiceDisplayNameA(SC_HANDLE,LPCSTR,LPSTR,PDWORD);
+BOOL WINAPI GetServiceDisplayNameW(SC_HANDLE,LPCWSTR,LPWSTR,PDWORD);
+BOOL WINAPI GetServiceKeyNameA(SC_HANDLE,LPCSTR,LPSTR,PDWORD);
+BOOL WINAPI GetServiceKeyNameW(SC_HANDLE,LPCWSTR,LPWSTR,PDWORD);
+SC_LOCK WINAPI LockServiceDatabase(SC_HANDLE);
+BOOL WINAPI NotifyBootConfigStatus(BOOL);
+SC_HANDLE WINAPI OpenSCManagerA(LPCSTR,LPCSTR,DWORD);
+SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR,LPCWSTR,DWORD);
+SC_HANDLE WINAPI OpenServiceA(SC_HANDLE,LPCSTR,DWORD);
+SC_HANDLE WINAPI OpenServiceW(SC_HANDLE,LPCWSTR,DWORD);
+BOOL WINAPI QueryServiceConfigA(SC_HANDLE,LPQUERY_SERVICE_CONFIGA,DWORD,PDWORD);
+BOOL WINAPI QueryServiceConfigW(SC_HANDLE,LPQUERY_SERVICE_CONFIGW,DWORD,PDWORD);
+BOOL WINAPI QueryServiceConfig2A(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
+BOOL WINAPI QueryServiceConfig2W(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
+BOOL WINAPI QueryServiceLockStatusA(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSA,DWORD,PDWORD);
+BOOL WINAPI QueryServiceLockStatusW(SC_HANDLE,LPQUERY_SERVICE_LOCK_STATUSW,DWORD,PDWORD);
+BOOL WINAPI QueryServiceObjectSecurity(SC_HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
+BOOL WINAPI QueryServiceStatus(SC_HANDLE,LPSERVICE_STATUS);
+BOOL WINAPI QueryServiceStatusEx(SC_HANDLE,SC_STATUS_TYPE,LPBYTE,DWORD,LPDWORD);
+SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerA(LPCSTR,LPHANDLER_FUNCTION);
+SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerW(LPCWSTR,LPHANDLER_FUNCTION);
+SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExA(LPCSTR,LPHANDLER_FUNCTION_EX,LPVOID);
+SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR,LPHANDLER_FUNCTION_EX,LPVOID);
+BOOL WINAPI SetServiceObjectSecurity(SC_HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS);
+BOOL WINAPI StartServiceA(SC_HANDLE,DWORD,LPCSTR*);
+BOOL WINAPI StartServiceCtrlDispatcherA(LPSERVICE_TABLE_ENTRYA);
+BOOL WINAPI StartServiceCtrlDispatcherW(LPSERVICE_TABLE_ENTRYW);
+BOOL WINAPI StartServiceW(SC_HANDLE,DWORD,LPCWSTR);
+BOOL WINAPI UnlockServiceDatabase(SC_LOCK);
+
+#ifdef UNICODE
+typedef ENUM_SERVICE_STATUSW ENUM_SERVICE_STATUS,*LPENUM_SERVICE_STATUS;
+typedef ENUM_SERVICE_STATUS_PROCESSW ENUM_SERVICE_STATUS_PROCESS;
+typedef LPENUM_SERVICE_STATUS_PROCESSW LPENUM_SERVICE_STATUS_PROCESS;
+typedef QUERY_SERVICE_CONFIGW QUERY_SERVICE_CONFIG,*LPQUERY_SERVICE_CONFIG;
+typedef QUERY_SERVICE_LOCK_STATUSW QUERY_SERVICE_LOCK_STATUS,*LPQUERY_SERVICE_LOCK_STATUS;
+typedef SERVICE_TABLE_ENTRYW SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
+typedef LPSERVICE_MAIN_FUNCTIONW LPSERVICE_MAIN_FUNCTION;
+typedef SERVICE_DESCRIPTIONW SERVICE_DESCRIPTION;
+typedef LPSERVICE_DESCRIPTIONW LPSERVICE_DESCRIPTION;
+typedef SERVICE_FAILURE_ACTIONSW SERVICE_FAILURE_ACTIONS;
+typedef LPSERVICE_FAILURE_ACTIONSW LPSERVICE_FAILURE_ACTIONS;
+#define SERVICES_ACTIVE_DATABASE SERVICES_ACTIVE_DATABASEW
+#define SERVICES_FAILED_DATABASE SERVICES_FAILED_DATABASEW
+#define SC_GROUP_IDENTIFIER SC_GROUP_IDENTIFIERW
+#define ChangeServiceConfig ChangeServiceConfigW
+#define ChangeServiceConfig2 ChangeServiceConfig2W
+#define CreateService CreateServiceW
+#define EnumDependentServices EnumDependentServicesW
+#define EnumServicesStatus EnumServicesStatusW
+#define EnumServicesStatusEx  EnumServicesStatusExW
+#define GetServiceDisplayName GetServiceDisplayNameW
+#define GetServiceKeyName GetServiceKeyNameW
+#define OpenSCManager OpenSCManagerW
+#define OpenService OpenServiceW
+#define QueryServiceConfig QueryServiceConfigW
+#define QueryServiceConfig2 QueryServiceConfig2W
+#define QueryServiceLockStatus QueryServiceLockStatusW
+#define RegisterServiceCtrlHandler RegisterServiceCtrlHandlerW
+#define RegisterServiceCtrlHandlerEx RegisterServiceCtrlHandlerExW
+#define StartService StartServiceW
+#define StartServiceCtrlDispatcher StartServiceCtrlDispatcherW
+#else
+typedef ENUM_SERVICE_STATUSA ENUM_SERVICE_STATUS,*LPENUM_SERVICE_STATUS;
+typedef ENUM_SERVICE_STATUS_PROCESSA ENUM_SERVICE_STATUS_PROCESS;
+typedef LPENUM_SERVICE_STATUS_PROCESSA LPENUM_SERVICE_STATUS_PROCESS;
+typedef QUERY_SERVICE_CONFIGA QUERY_SERVICE_CONFIG,*LPQUERY_SERVICE_CONFIG;
+typedef QUERY_SERVICE_LOCK_STATUSA QUERY_SERVICE_LOCK_STATUS,*LPQUERY_SERVICE_LOCK_STATUS;
+typedef SERVICE_TABLE_ENTRYA SERVICE_TABLE_ENTRY,*LPSERVICE_TABLE_ENTRY;
+typedef LPSERVICE_MAIN_FUNCTIONA LPSERVICE_MAIN_FUNCTION;
+typedef SERVICE_DESCRIPTIONA SERVICE_DESCRIPTION;
+typedef LPSERVICE_DESCRIPTIONA LPSERVICE_DESCRIPTION;
+typedef SERVICE_FAILURE_ACTIONSA SERVICE_FAILURE_ACTIONS;
+typedef LPSERVICE_FAILURE_ACTIONSA LPSERVICE_FAILURE_ACTIONS;
+#define SERVICES_ACTIVE_DATABASE SERVICES_ACTIVE_DATABASEA
+#define SERVICES_FAILED_DATABASE SERVICES_FAILED_DATABASEA
+#define SC_GROUP_IDENTIFIER SC_GROUP_IDENTIFIERA
+#define ChangeServiceConfig ChangeServiceConfigA
+#define ChangeServiceConfig2 ChangeServiceConfig2A
+#define CreateService CreateServiceA
+#define EnumDependentServices EnumDependentServicesA
+#define EnumServicesStatus EnumServicesStatusA
+#define EnumServicesStatusEx  EnumServicesStatusExA
+#define GetServiceDisplayName GetServiceDisplayNameA
+#define GetServiceKeyName GetServiceKeyNameA
+#define OpenSCManager OpenSCManagerA
+#define OpenService OpenServiceA
+#define QueryServiceConfig QueryServiceConfigA
+#define QueryServiceConfig2 QueryServiceConfig2A
+#define QueryServiceLockStatus QueryServiceLockStatusA
+#define RegisterServiceCtrlHandler RegisterServiceCtrlHandlerA
+#define RegisterServiceCtrlHandlerEx RegisterServiceCtrlHandlerExA
+#define StartService StartServiceA
+#define StartServiceCtrlDispatcher StartServiceCtrlDispatcherA
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _WINSVC_H */
diff --git a/tinyc/win32/include/winapi/winuser.h b/tinyc/win32/include/winapi/winuser.h
new file mode 100755
index 000000000..8929c6be6
--- /dev/null
+++ b/tinyc/win32/include/winapi/winuser.h
@@ -0,0 +1,3472 @@
+#ifndef _WINUSER_H
+#define _WINUSER_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define WC_DIALOG MAKEINTATOM(0x8002)
+#define FALT	16
+#define FCONTROL	8
+#define FNOINVERT	2
+#define FSHIFT	4
+#define FVIRTKEY	1
+#define ATF_TIMEOUTON	1
+#define ATF_ONOFFFEEDBACK	2
+#define ATF_AVAILABLE	4 /* May be obsolete. Not in recent MS docs. */
+#define WH_MIN	(-1)
+#define WH_MSGFILTER	(-1)
+#define WH_JOURNALRECORD	0
+#define WH_JOURNALPLAYBACK	1
+#define WH_KEYBOARD	2
+#define WH_GETMESSAGE	3
+#define WH_CALLWNDPROC	4
+#define WH_CBT	5
+#define WH_SYSMSGFILTER	6
+#define WH_MOUSE	7
+#define WH_HARDWARE	8
+#define WH_DEBUG	9
+#define WH_SHELL	10
+#define WH_FOREGROUNDIDLE	11
+#define WH_CALLWNDPROCRET	12
+#define WH_KEYBOARD_LL	13
+#define WH_MOUSE_LL	14
+#define WH_MAX		14
+#define WH_MINHOOK	WH_MIN
+#define WH_MAXHOOK	WH_MAX
+#define HC_ACTION	0
+#define HC_GETNEXT	1
+#define HC_SKIP	2
+#define HC_NOREMOVE	3
+#define HC_NOREM	3
+#define HC_SYSMODALON	4
+#define HC_SYSMODALOFF	5
+#define HCBT_MOVESIZE	0
+#define HCBT_MINMAX	1
+#define HCBT_QS	2
+#define HCBT_CREATEWND	3
+#define HCBT_DESTROYWND	4
+#define HCBT_ACTIVATE	5
+#define HCBT_CLICKSKIPPED	6
+#define HCBT_KEYSKIPPED	7
+#define HCBT_SYSCOMMAND	8
+#define HCBT_SETFOCUS	9
+#define CF_TEXT	1
+#define CF_BITMAP	2
+#define CF_METAFILEPICT	3
+#define CF_SYLK	4
+#define CF_DIF	5
+#define CF_TIFF	6
+#define CF_OEMTEXT	7
+#define CF_DIB	8
+#define CF_PALETTE	9
+#define CF_PENDATA	10
+#define CF_RIFF	11
+#define CF_WAVE	12
+#define CF_UNICODETEXT	13
+#define CF_ENHMETAFILE	14
+#define CF_HDROP	15
+#define CF_LOCALE	16
+#define CF_MAX	17
+#define CF_OWNERDISPLAY	128
+#define CF_DSPTEXT	129
+#define CF_DSPBITMAP	130
+#define CF_DSPMETAFILEPICT	131
+#define CF_DSPENHMETAFILE	142
+#define CF_PRIVATEFIRST	512
+#define CF_PRIVATELAST	767
+#define CF_GDIOBJFIRST	768
+#define CF_GDIOBJLAST	1023
+#define HKL_NEXT	1
+#define HKL_PREV	0
+#define KLF_ACTIVATE	1
+#define KLF_SUBSTITUTE_OK	2
+#define KLF_UNLOADPREVIOUS	4
+#define KLF_REORDER	8
+#define KLF_REPLACELANG	16
+#define KLF_NOTELLSHELL	128
+#define KLF_SETFORPROCESS	256
+#define KL_NAMELENGTH 9
+#define MF_ENABLED	0
+#define MF_GRAYED	1
+#define MF_DISABLED	2
+#define MF_BITMAP	4
+#define MF_CHECKED	8
+#define MF_MENUBARBREAK 32
+#define MF_MENUBREAK	64
+#define MF_OWNERDRAW	256
+#define MF_POPUP	16
+#define MF_SEPARATOR	0x800
+#define MF_STRING	0
+#define MF_UNCHECKED	0
+#define MF_DEFAULT	4096
+#define MF_SYSMENU	0x2000
+#define MF_HELP	0x4000
+#define MF_END	128
+#define MF_RIGHTJUSTIFY	0x4000
+#define MF_MOUSESELECT	0x8000
+#define MF_INSERT 0
+#define MF_CHANGE 128
+#define MF_APPEND 256
+#define MF_DELETE 512
+#define MF_REMOVE 4096
+#define MF_USECHECKBITMAPS 512
+#define MF_UNHILITE 0
+#define MF_HILITE 128
+#define BSF_IGNORECURRENTTASK	2
+#define BSF_QUERY	1
+#define BSF_FLUSHDISK	4
+#define BSF_NOHANG	8
+#define BSF_POSTMESSAGE 16
+#define BSF_FORCEIFHUNG	32
+#define BSF_NOTIMEOUTIFNOTHUNG 64
+#define BSM_ALLCOMPONENTS	0
+#define BSM_APPLICATIONS	8
+#define BSM_ALLDESKTOPS		16
+#define BSM_INSTALLABLEDRIVERS	4
+#define BSM_NETDRIVER	2
+#define BSM_VXDS	1
+#define BROADCAST_QUERY_DENY	1112363332
+#define ENUM_CURRENT_SETTINGS	((DWORD)-1)
+#define ENUM_REGISTRY_SETTINGS	((DWORD)-2)
+#define DM_BITSPERPEL	0x40000
+#define DM_PELSWIDTH	0x80000
+#define DM_PELSHEIGHT	0x100000
+#define DM_DISPLAYFLAGS 0x200000
+#define DM_DISPLAYFREQUENCY 0x400000
+#define CDS_UPDATEREGISTRY	1
+#define CDS_TEST	2
+#define CDS_FULLSCREEN	4 
+#define CDS_GLOBAL	8 
+#define CDS_SET_PRIMARY	16
+#define CDS_RESET	0x40000000 
+#define CDS_SETRECT	0x20000000 
+#define CDS_NORESET	0x10000000 
+#define DISP_CHANGE_SUCCESSFUL	0
+#define DISP_CHANGE_RESTART	1
+#define DISP_CHANGE_BADFLAGS	(-4)
+#define DISP_CHANGE_BADPARAM	(-5)
+#define DISP_CHANGE_FAILED	(-1)
+#define DISP_CHANGE_BADMODE	(-2)
+#define DISP_CHANGE_NOTUPDATED	(-3)
+#define BST_CHECKED	1
+#define BST_INDETERMINATE	2
+#define BST_UNCHECKED	0
+#define BST_FOCUS	8
+#define BST_PUSHED	4
+#define MF_BYCOMMAND	0
+#define MF_BYPOSITION	1024
+#define MF_UNCHECKED	0
+#define MF_HILITE	128
+#define MF_UNHILITE	0
+#define CWP_ALL 0
+#define CWP_SKIPINVISIBLE	1
+#define CWP_SKIPDISABLED	2
+#define CWP_SKIPTRANSPARENT	4
+#define IMAGE_BITMAP	0
+#define IMAGE_ICON	1
+#define IMAGE_CURSOR	2
+#define IMAGE_ENHMETAFILE	3
+#define DF_ALLOWOTHERACCOUNTHOOK	1
+#define DESKTOP_CREATEMENU	4
+#define DESKTOP_CREATEWINDOW	2
+#define DESKTOP_ENUMERATE	64
+#define DESKTOP_HOOKCONTROL	8
+#define DESKTOP_JOURNALPLAYBACK	32
+#define DESKTOP_JOURNALRECORD	16
+#define DESKTOP_READOBJECTS	1
+#define DESKTOP_SWITCHDESKTOP	256
+#define DESKTOP_WRITEOBJECTS	128
+#define CW_USEDEFAULT	0x80000000
+#define WS_BORDER	0x800000
+#define WS_CAPTION	0xc00000
+#define WS_CHILD	0x40000000
+#define WS_CHILDWINDOW	0x40000000
+#define WS_CLIPCHILDREN 0x2000000
+#define WS_CLIPSIBLINGS 0x4000000
+#define WS_DISABLED	0x8000000
+#define WS_DLGFRAME	0x400000
+#define WS_GROUP	0x20000
+#define WS_HSCROLL	0x100000
+#define WS_ICONIC	0x20000000
+#define WS_MAXIMIZE	0x1000000
+#define WS_MAXIMIZEBOX	0x10000
+#define WS_MINIMIZE	0x20000000
+#define WS_MINIMIZEBOX	0x20000
+#define WS_OVERLAPPED	0
+#define WS_OVERLAPPEDWINDOW	0xcf0000
+#define WS_POPUP	0x80000000
+#define WS_POPUPWINDOW	0x80880000
+#define WS_SIZEBOX	0x40000
+#define WS_SYSMENU	0x80000
+#define WS_TABSTOP	0x10000
+#define WS_THICKFRAME	0x40000
+#define WS_TILED	0
+#define WS_TILEDWINDOW	0xcf0000
+#define WS_VISIBLE	0x10000000
+#define WS_VSCROLL	0x200000
+#define MDIS_ALLCHILDSTYLES	1
+#define BS_3STATE	5
+#define BS_AUTO3STATE	6
+#define BS_AUTOCHECKBOX	3
+#define BS_AUTORADIOBUTTON	9
+#define BS_BITMAP	128
+#define BS_BOTTOM	0x800
+#define BS_CENTER	0x300
+#define BS_CHECKBOX	2
+#define BS_DEFPUSHBUTTON	1
+#define BS_GROUPBOX	7
+#define BS_ICON	64
+#define BS_LEFT	256
+#define BS_LEFTTEXT	32
+#define BS_MULTILINE	0x2000
+#define BS_NOTIFY	0x4000
+#define BS_OWNERDRAW	0xb
+#define BS_PUSHBUTTON	0
+#define BS_PUSHLIKE	4096
+#define BS_RADIOBUTTON 4
+#define BS_RIGHT	512
+#define BS_RIGHTBUTTON	32
+#define BS_TEXT	0
+#define BS_TOP	0x400
+#define BS_USERBUTTON	8
+#define BS_VCENTER	0xc00
+#define BS_FLAT	0x8000
+#define CBS_AUTOHSCROLL	64
+#define CBS_DISABLENOSCROLL	0x800
+#define CBS_DROPDOWN	2
+#define CBS_DROPDOWNLIST	3
+#define CBS_HASSTRINGS	512
+#define CBS_LOWERCASE	0x4000
+#define CBS_NOINTEGRALHEIGHT	0x400
+#define CBS_OEMCONVERT	128
+#define CBS_OWNERDRAWFIXED	16
+#define CBS_OWNERDRAWVARIABLE	32
+#define CBS_SIMPLE	1
+#define CBS_SORT	256
+#define CBS_UPPERCASE	0x2000
+#define ES_AUTOHSCROLL	128
+#define ES_AUTOVSCROLL	64
+#define ES_CENTER	1
+#define ES_LEFT	0
+#define ES_LOWERCASE 16
+#define ES_MULTILINE 4
+#define ES_NOHIDESEL 256
+#define ES_NUMBER 0x2000
+#define ES_OEMCONVERT 0x400
+#define ES_PASSWORD 32
+#define ES_READONLY 0x800
+#define ES_RIGHT 2
+#define ES_UPPERCASE 8
+#define ES_WANTRETURN 4096
+#define LBS_DISABLENOSCROLL 4096
+#define LBS_EXTENDEDSEL 0x800
+#define LBS_HASSTRINGS 64
+#define LBS_MULTICOLUMN 512
+#define LBS_MULTIPLESEL 8
+#define LBS_NODATA	0x2000
+#define LBS_NOINTEGRALHEIGHT 256
+#define LBS_NOREDRAW 4
+#define LBS_NOSEL 0x4000
+#define LBS_NOTIFY 1
+#define LBS_OWNERDRAWFIXED 16
+#define LBS_OWNERDRAWVARIABLE 32
+#define LBS_SORT 2
+#define LBS_STANDARD 0xa00003
+#define LBS_USETABSTOPS 128
+#define LBS_WANTKEYBOARDINPUT 0x400
+#define SBS_BOTTOMALIGN 4
+#define SBS_HORZ 0
+#define SBS_LEFTALIGN 2
+#define SBS_RIGHTALIGN 4
+#define SBS_SIZEBOX 8
+#define SBS_SIZEBOXBOTTOMRIGHTALIGN 4
+#define SBS_SIZEBOXTOPLEFTALIGN 2
+#define SBS_SIZEGRIP 16
+#define SBS_TOPALIGN 2
+#define SBS_VERT 1
+#define SS_BITMAP 14
+#define SS_BLACKFRAME 7
+#define SS_BLACKRECT 4
+#define SS_CENTER 1
+#define SS_CENTERIMAGE 512
+#define SS_ENHMETAFILE 15
+#define SS_ETCHEDFRAME 18
+#define SS_ETCHEDHORZ 16
+#define SS_ETCHEDVERT 17
+#define SS_GRAYFRAME 8
+#define SS_GRAYRECT 5
+#define SS_ICON 3
+#define SS_LEFT 0
+#define SS_LEFTNOWORDWRAP 0xc
+#define SS_NOPREFIX 128
+#define SS_NOTIFY 256
+#define SS_OWNERDRAW 0xd
+#define SS_REALSIZEIMAGE 0x800
+#define SS_RIGHT 2
+#define SS_RIGHTJUST 0x400
+#define SS_SIMPLE 11
+#define SS_SUNKEN 4096
+#define SS_WHITEFRAME 9
+#define SS_WHITERECT	6
+#define SS_USERITEM	10
+#define SS_TYPEMASK	0x0000001FL
+#define SS_ENDELLIPSIS	0x00004000L
+#define SS_PATHELLIPSIS	0x00008000L
+#define SS_WORDELLIPSIS	0x0000C000L
+#define SS_ELLIPSISMASK 0x0000C000L
+#define DS_3DLOOK 4
+#define DS_ABSALIGN 1
+#define DS_CENTER 0x800
+#define DS_CENTERMOUSE 4096
+#define DS_CONTEXTHELP 0x2000
+#define DS_CONTROL 0x400
+#define DS_FIXEDSYS 8
+#define DS_LOCALEDIT 32
+#define DS_MODALFRAME 128
+#define DS_NOFAILCREATE 16
+#define DS_NOIDLEMSG	256
+#define DS_SETFONT 64
+#define DS_SETFOREGROUND 512
+#define DS_SYSMODAL 2
+#define WS_EX_ACCEPTFILES 16
+#define WS_EX_APPWINDOW	0x40000
+#define WS_EX_CLIENTEDGE 512
+#define WS_EX_COMPOSITED 0x2000000 /* XP */
+#define WS_EX_CONTEXTHELP 0x400
+#define WS_EX_CONTROLPARENT 0x10000
+#define WS_EX_DLGMODALFRAME 1
+#define WS_EX_LAYERED 0x80000   /* w2k */
+#define WS_EX_LAYOUTRTL 0x400000 /* w98, w2k */
+#define WS_EX_LEFT	0
+#define WS_EX_LEFTSCROLLBAR	0x4000
+#define WS_EX_LTRREADING	0
+#define WS_EX_MDICHILD	64
+#define WS_EX_NOACTIVATE 0x8000000 /* w2k */
+#define WS_EX_NOINHERITLAYOUT 0x100000 /* w2k */
+#define WS_EX_NOPARENTNOTIFY	4
+#define WS_EX_OVERLAPPEDWINDOW	0x300
+#define WS_EX_PALETTEWINDOW	0x188
+#define WS_EX_RIGHT	0x1000
+#define WS_EX_RIGHTSCROLLBAR	0
+#define WS_EX_RTLREADING	0x2000
+#define WS_EX_STATICEDGE	0x20000
+#define WS_EX_TOOLWINDOW	128
+#define WS_EX_TOPMOST	8
+#define WS_EX_TRANSPARENT	32
+#define WS_EX_WINDOWEDGE	256
+#define WINSTA_ACCESSCLIPBOARD	4
+#define WINSTA_ACCESSGLOBALATOMS	32
+#define WINSTA_CREATEDESKTOP	8
+#define WINSTA_ENUMDESKTOPS	1
+#define WINSTA_ENUMERATE	256
+#define WINSTA_EXITWINDOWS	64
+#define WINSTA_READATTRIBUTES	2
+#define WINSTA_READSCREEN	512
+#define WINSTA_WRITEATTRIBUTES	16
+#define DDL_READWRITE	0
+#define DDL_READONLY	1
+#define DDL_HIDDEN	2
+#define DDL_SYSTEM	4
+#define DDL_DIRECTORY	16
+#define DDL_ARCHIVE	32
+#define DDL_POSTMSGS	8192
+#define DDL_DRIVES	16384
+#define DDL_EXCLUSIVE	32768
+#define DC_ACTIVE	1
+#define DC_SMALLCAP	2
+#define DC_ICON	4
+#define DC_TEXT	8
+#define DC_INBUTTON	16
+#define DC_CAPTION	(DC_ICON|DC_TEXT|DC_BUTTONS)
+#define DC_NC	(DC_CAPTION|DC_FRAME)
+#define BDR_RAISEDOUTER	1
+#define BDR_SUNKENOUTER	2
+#define BDR_RAISEDINNER	4
+#define BDR_SUNKENINNER	8
+#define BDR_OUTER	3
+#define BDR_INNER	0xc
+#define BDR_RAISED	5
+#define BDR_SUNKEN	10
+#define EDGE_RAISED	(BDR_RAISEDOUTER|BDR_RAISEDINNER)
+#define EDGE_SUNKEN	(BDR_SUNKENOUTER|BDR_SUNKENINNER)
+#define EDGE_ETCHED	(BDR_SUNKENOUTER|BDR_RAISEDINNER)
+#define EDGE_BUMP	(BDR_RAISEDOUTER|BDR_SUNKENINNER)
+#define BF_LEFT	1
+#define BF_TOP	2
+#define BF_RIGHT	4
+#define BF_BOTTOM	8
+#define BF_TOPLEFT	(BF_TOP|BF_LEFT)
+#define BF_TOPRIGHT	(BF_TOP|BF_RIGHT)
+#define BF_BOTTOMLEFT	(BF_BOTTOM|BF_LEFT)
+#define BF_BOTTOMRIGHT	(BF_BOTTOM|BF_RIGHT)
+#define BF_RECT	(BF_LEFT|BF_TOP|BF_RIGHT|BF_BOTTOM)
+#define BF_DIAGONAL	16
+#define BF_DIAGONAL_ENDTOPRIGHT	(BF_DIAGONAL|BF_TOP|BF_RIGHT)
+#define BF_DIAGONAL_ENDTOPLEFT	(BF_DIAGONAL|BF_TOP|BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMLEFT	(BF_DIAGONAL|BF_BOTTOM|BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMRIGHT	(BF_DIAGONAL|BF_BOTTOM|BF_RIGHT)
+#define BF_MIDDLE	0x800
+#define BF_SOFT	0x1000
+#define BF_ADJUST	0x2000
+#define BF_FLAT	0x4000
+#define BF_MONO	0x8000
+#define DFC_CAPTION	1
+#define DFC_MENU	2
+#define DFC_SCROLL	3
+#define DFC_BUTTON	4
+#define DFCS_CAPTIONCLOSE	0
+#define DFCS_CAPTIONMIN	1
+#define DFCS_CAPTIONMAX	2
+#define DFCS_CAPTIONRESTORE	3
+#define DFCS_CAPTIONHELP	4
+#define DFCS_MENUARROW	0
+#define DFCS_MENUCHECK	1
+#define DFCS_MENUBULLET	2
+#define DFCS_MENUARROWRIGHT	4
+#define DFCS_SCROLLUP	0
+#define DFCS_SCROLLDOWN	1
+#define DFCS_SCROLLLEFT	2
+#define DFCS_SCROLLRIGHT	3
+#define DFCS_SCROLLCOMBOBOX	5
+#define DFCS_SCROLLSIZEGRIP	8
+#define DFCS_SCROLLSIZEGRIPRIGHT	16
+#define DFCS_BUTTONCHECK	0
+#define DFCS_BUTTONRADIOIMAGE	1
+#define DFCS_BUTTONRADIOMASK	2
+#define DFCS_BUTTONRADIO	4
+#define DFCS_BUTTON3STATE	8
+#define DFCS_BUTTONPUSH	16
+#define DFCS_INACTIVE	256
+#define DFCS_PUSHED	512
+#define DFCS_CHECKED	1024
+#define DFCS_ADJUSTRECT	0x2000
+#define DFCS_FLAT	0x4000
+#define DFCS_MONO	0x8000
+#define DST_COMPLEX	0
+#define DST_TEXT	1
+#define DST_PREFIXTEXT	2
+#define DST_ICON	3
+#define DST_BITMAP	4
+#define DSS_NORMAL	0
+#define DSS_UNION	16
+#define DSS_DISABLED	32
+#define DSS_MONO	128
+#define DSS_RIGHT	0x8000
+#define DT_BOTTOM	8
+#define DT_CALCRECT	1024
+#define DT_CENTER	1
+#define DT_EDITCONTROL	8192
+#define DT_END_ELLIPSIS	32768
+#define DT_PATH_ELLIPSIS	16384
+#define DT_WORD_ELLIPSIS 0x40000
+#define DT_EXPANDTABS	64
+#define DT_EXTERNALLEADING	512
+#define DT_LEFT	0
+#define DT_MODIFYSTRING	65536
+#define DT_NOCLIP	256
+#define DT_NOPREFIX	2048
+#define DT_RIGHT	2
+#define DT_RTLREADING	131072
+#define DT_SINGLELINE	32
+#define DT_TABSTOP	128
+#define DT_TOP	0
+#define DT_VCENTER	4
+#define DT_WORDBREAK	16
+#define DT_INTERNAL	4096
+#define WB_ISDELIMITER	2
+#define WB_LEFT	0
+#define WB_RIGHT	1
+#define SB_HORZ	0
+#define SB_VERT	1
+#define SB_CTL	2
+#define SB_BOTH	3
+#define ESB_DISABLE_BOTH	3
+#define ESB_DISABLE_DOWN	2
+#define ESB_DISABLE_LEFT	1
+#define ESB_DISABLE_LTUP	1
+#define ESB_DISABLE_RIGHT	2
+#define ESB_DISABLE_RTDN	2
+#define ESB_DISABLE_UP	1
+#define ESB_ENABLE_BOTH	0
+#define SB_LINEUP	0
+#define SB_LINEDOWN	1
+#define SB_LINELEFT	0
+#define SB_LINERIGHT	1
+#define SB_PAGEUP	2
+#define SB_PAGEDOWN	3
+#define SB_PAGELEFT	2
+#define SB_PAGERIGHT	3
+#define SB_THUMBPOSITION	4
+#define SB_THUMBTRACK	5
+#define SB_ENDSCROLL	8
+#define SB_LEFT	6
+#define SB_RIGHT	7
+#define SB_BOTTOM	7
+#define SB_TOP	6
+#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))
+#ifndef XFree86Server
+# define RT_CURSOR MAKEINTRESOURCE(1)
+# define RT_FONT MAKEINTRESOURCE(8)
+#endif /* ndef XFree86Server */
+#define RT_BITMAP MAKEINTRESOURCE(2)
+#define RT_ICON MAKEINTRESOURCE(3)
+#define RT_MENU MAKEINTRESOURCE(4)
+#define RT_DIALOG MAKEINTRESOURCE(5)
+#define RT_STRING MAKEINTRESOURCE(6)
+#define RT_FONTDIR MAKEINTRESOURCE(7)
+#define RT_ACCELERATOR MAKEINTRESOURCE(9)
+#define RT_RCDATA MAKEINTRESOURCE(10)
+#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
+#define DIFFERENCE 11
+#define RT_GROUP_CURSOR MAKEINTRESOURCE((DWORD)RT_CURSOR+DIFFERENCE)
+#define RT_GROUP_ICON MAKEINTRESOURCE((DWORD)RT_ICON+DIFFERENCE)
+#define RT_VERSION MAKEINTRESOURCE(16)
+#define RT_DLGINCLUDE MAKEINTRESOURCE(17)
+#define RT_PLUGPLAY MAKEINTRESOURCE(19)
+#define RT_VXD MAKEINTRESOURCE(20)
+#define RT_ANICURSOR MAKEINTRESOURCE(21)
+#define RT_ANIICON MAKEINTRESOURCE(22)
+#define RT_HTML MAKEINTRESOURCE(23)
+#define EWX_FORCE 4
+#define EWX_LOGOFF 0
+#define EWX_POWEROFF 8
+#define EWX_REBOOT 2
+#define EWX_SHUTDOWN 1
+#define CS_BYTEALIGNCLIENT 4096
+#define CS_BYTEALIGNWINDOW 8192
+#define CS_KEYCVTWINDOW 4
+#define CS_NOKEYCVT 256
+#define CS_CLASSDC 64
+#define CS_DBLCLKS 8
+#define CS_GLOBALCLASS 16384
+#define CS_HREDRAW 2
+#define CS_NOCLOSE 512
+#define CS_OWNDC 32
+#define CS_PARENTDC 128
+#define CS_SAVEBITS 2048
+#define CS_VREDRAW 1
+#define CS_IME 0x10000
+#define GCW_ATOM (-32)
+#define GCL_CBCLSEXTRA (-20)
+#define GCL_CBWNDEXTRA (-18)
+#define GCL_HBRBACKGROUND (-10)
+#define GCL_HCURSOR (-12)
+#define GCL_HICON (-14)
+#define GCL_HICONSM (-34)
+#define GCL_HMODULE (-16)
+#define GCL_MENUNAME (-8)
+#define GCL_STYLE (-26)
+#define GCL_WNDPROC (-24)
+#if 0
+    /* This is supposed to be defined by the program using it not defined
+       in the win32api headers.  I've left it here for documentation purposes.
+    */
+#ifndef IDC_STATIC  /* May be predefined by resource compiler.  */
+#define IDC_STATIC (-1)
+#endif
+#endif
+#define IDC_ARROW MAKEINTRESOURCE(32512)
+#define IDC_IBEAM MAKEINTRESOURCE(32513)
+#define IDC_WAIT MAKEINTRESOURCE(32514)
+#define IDC_CROSS MAKEINTRESOURCE(32515)
+#define IDC_UPARROW MAKEINTRESOURCE(32516)
+#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
+#define IDC_SIZENESW MAKEINTRESOURCE(32643)
+#define IDC_SIZEWE MAKEINTRESOURCE(32644)
+#define IDC_SIZENS MAKEINTRESOURCE(32645)
+#define IDC_SIZEALL MAKEINTRESOURCE(32646)
+#define IDC_NO MAKEINTRESOURCE(32648)
+#define IDC_HAND MAKEINTRESOURCE(32649)
+#define IDC_APPSTARTING MAKEINTRESOURCE(32650)
+#define IDC_HELP MAKEINTRESOURCE(32651)
+#define IDC_ICON MAKEINTRESOURCE(32641)
+#define IDC_SIZE MAKEINTRESOURCE(32640)
+#ifndef RC_INVOKED
+#define IDI_APPLICATION MAKEINTRESOURCE(32512)
+#define IDI_HAND MAKEINTRESOURCE(32513)
+#define IDI_QUESTION MAKEINTRESOURCE(32514)
+#define IDI_EXCLAMATION MAKEINTRESOURCE(32515)
+#define IDI_ASTERISK MAKEINTRESOURCE(32516)
+#define IDI_WINLOGO MAKEINTRESOURCE(32517)
+#else
+#define IDI_APPLICATION 32512
+#define IDI_HAND 32513
+#define IDI_QUESTION 32514
+#define IDI_EXCLAMATION 32515
+#define IDI_ASTERISK 32516
+#define IDI_WINLOGO 32517
+#endif
+#define IDI_WARNING IDI_EXCLAMATION
+#define IDI_ERROR IDI_HAND
+#define IDI_INFORMATION IDI_ASTERISK
+#define MIIM_STATE 1
+#define MIIM_ID 2
+#define MIIM_SUBMENU 4
+#define MIIM_CHECKMARKS 8
+#define MIIM_TYPE 16
+#define MIIM_DATA 32
+#define MIIM_STRING 64
+#define MIIM_BITMAP 128
+#define MIIM_FTYPE 256
+#define MFT_BITMAP 4
+#define MFT_MENUBARBREAK 32
+#define MFT_MENUBREAK 64
+#define MFT_OWNERDRAW 256
+#define MFT_RADIOCHECK 512
+#define MFT_RIGHTJUSTIFY 0x4000
+#define MFT_SEPARATOR 0x800
+#define MFT_RIGHTORDER 0x2000L
+#define MFT_STRING 0
+#define MFS_CHECKED 8
+#define MFS_DEFAULT 4096
+#define MFS_DISABLED 3
+#define MFS_ENABLED 0
+#define MFS_GRAYED 3
+#define MFS_HILITE 128
+#define MFS_UNCHECKED 0
+#define MFS_UNHILITE 0
+#define GW_HWNDNEXT 2
+#define GW_HWNDPREV 3
+#define GW_CHILD 5
+#define GW_HWNDFIRST 0
+#define GW_HWNDLAST 1
+#define GW_OWNER 4
+#define SW_HIDE 0
+#define SW_NORMAL 1
+#define SW_SHOWNORMAL 1
+#define SW_SHOWMINIMIZED 2
+#define SW_MAXIMIZE 3
+#define SW_SHOWMAXIMIZED 3
+#define SW_SHOWNOACTIVATE 4
+#define SW_SHOW 5
+#define SW_MINIMIZE 6
+#define SW_SHOWMINNOACTIVE 7
+#define SW_SHOWNA 8
+#define SW_RESTORE 9
+#define SW_SHOWDEFAULT 10
+#define SW_FORCEMINIMIZE 11
+#define SW_MAX  11
+#define MB_USERICON 128
+#define MB_ICONASTERISK 64
+#define MB_ICONEXCLAMATION 0x30
+#define MB_ICONWARNING 0x30
+#define MB_ICONERROR 16
+#define MB_ICONHAND 16
+#define MB_ICONQUESTION 32
+#define MB_OK 0
+#define MB_ABORTRETRYIGNORE 2
+#define MB_APPLMODAL 0
+#define MB_DEFAULT_DESKTOP_ONLY 0x20000
+#define MB_HELP 0x4000
+#define MB_RIGHT 0x80000
+#define MB_RTLREADING 0x100000
+#define MB_TOPMOST 0x40000
+#define MB_DEFBUTTON1 0
+#define MB_DEFBUTTON2 256
+#define MB_DEFBUTTON3 512
+#define MB_DEFBUTTON4 0x300
+#define MB_ICONINFORMATION 64
+#define MB_ICONSTOP 16
+#define MB_OKCANCEL 1
+#define MB_RETRYCANCEL 5
+#ifdef _WIN32_WINNT
+#if (_WIN32_WINNT >= 0x0400)
+#define MB_SERVICE_NOTIFICATION  0x00200000
+#else
+#define MB_SERVICE_NOTIFICATION  0x00040000
+#endif
+#define MB_SERVICE_NOTIFICATION_NT3X  0x00040000
+#endif
+#define MB_SETFOREGROUND 0x10000
+#define MB_SYSTEMMODAL 4096
+#define MB_TASKMODAL 0x2000
+#define MB_YESNO 4
+#define MB_YESNOCANCEL 3
+#define MB_ICONMASK 240
+#define MB_DEFMASK 3840
+#define MB_MODEMASK 0x00003000
+#define MB_MISCMASK 0x0000C000
+#define MB_NOFOCUS 0x00008000
+#define MB_TYPEMASK 15
+#define MB_TOPMOST 0x40000
+#define IDABORT 3
+#define IDCANCEL 2
+#define IDCLOSE 8
+#define IDHELP 9
+#define IDIGNORE 5
+#define IDNO 7
+#define IDOK 1
+#define IDRETRY 4
+#define IDYES 6
+#define GWL_EXSTYLE (-20)
+#define GWL_STYLE (-16)
+#define GWL_WNDPROC (-4)
+#define GWLP_WNDPROC (-4)
+#define GWL_HINSTANCE (-6)
+#define GWLP_HINSTANCE (-6)
+#define GWL_HWNDPARENT (-8)
+#define GWLP_HWNDPARENT (-8)
+#define GWL_ID (-12)
+#define GWLP_ID (-12)
+#define GWL_USERDATA (-21)
+#define GWLP_USERDATA (-21)
+#define DWL_DLGPROC 4
+#define DWLP_DLGPROC 4
+#define DWL_MSGRESULT 0
+#define DWLP_MSGRESULT 0
+#define DWL_USER 8
+#define DWLP_USER 8
+#define QS_ALLEVENTS 191
+#define QS_ALLINPUT 255
+#define QS_HOTKEY 128
+#define QS_INPUT 7
+#define QS_KEY 1
+#define QS_MOUSE 6
+#define QS_MOUSEBUTTON 4
+#define QS_MOUSEMOVE 2
+#define QS_PAINT 32
+#define QS_POSTMESSAGE 8
+#define QS_SENDMESSAGE 64
+#define QS_TIMER 16
+#define COLOR_3DDKSHADOW 21
+#define COLOR_3DFACE 15
+#define COLOR_3DHILIGHT 20
+#define COLOR_3DHIGHLIGHT 20
+#define COLOR_3DLIGHT 22
+#define COLOR_BTNHILIGHT 20
+#define COLOR_3DSHADOW 16
+#define COLOR_ACTIVEBORDER 10
+#define COLOR_ACTIVECAPTION 2
+#define COLOR_APPWORKSPACE 12
+#define COLOR_BACKGROUND 1
+#define COLOR_DESKTOP 1
+#define COLOR_BTNFACE 15
+#define COLOR_BTNHIGHLIGHT 20
+#define COLOR_BTNSHADOW 16
+#define COLOR_BTNTEXT 18
+#define COLOR_CAPTIONTEXT 9
+#define COLOR_GRAYTEXT 17
+#define COLOR_HIGHLIGHT 13
+#define COLOR_HIGHLIGHTTEXT 14
+#define COLOR_INACTIVEBORDER 11
+#define COLOR_INACTIVECAPTION 3
+#define COLOR_INACTIVECAPTIONTEXT 19
+#define COLOR_INFOBK 24
+#define COLOR_INFOTEXT 23
+#define COLOR_MENU 4
+#define COLOR_MENUTEXT 7
+#define COLOR_SCROLLBAR 0
+#define COLOR_WINDOW 5
+#define COLOR_WINDOWFRAME 6
+#define COLOR_WINDOWTEXT 8
+#define CTLCOLOR_MSGBOX 0
+#define CTLCOLOR_EDIT 1
+#define CTLCOLOR_LISTBOX 2
+#define CTLCOLOR_BTN 3
+#define CTLCOLOR_DLG 4
+#define CTLCOLOR_SCROLLBAR 5
+#define CTLCOLOR_STATIC 6
+#define CTLCOLOR_MAX 7
+#define SM_CXSCREEN 0
+#define SM_CYSCREEN 1
+#define SM_CXVSCROLL 2
+#define SM_CYHSCROLL 3
+#define SM_CYCAPTION 4
+#define SM_CXBORDER 5
+#define SM_CYBORDER 6
+#define SM_CXDLGFRAME 7
+#define SM_CXFIXEDFRAME 7
+#define SM_CYDLGFRAME 8
+#define SM_CYFIXEDFRAME 8
+#define SM_CYVTHUMB 9
+#define SM_CXHTHUMB 10
+#define SM_CXICON 11
+#define SM_CYICON 12
+#define SM_CXCURSOR 13
+#define SM_CYCURSOR 14
+#define SM_CYMENU 15
+#define SM_CXFULLSCREEN 16
+#define SM_CYFULLSCREEN 17
+#define SM_CYKANJIWINDOW 18
+#define SM_MOUSEPRESENT 19
+#define SM_CYVSCROLL 20
+#define SM_CXHSCROLL 21
+#define SM_DEBUG 22
+#define SM_SWAPBUTTON 23
+#define SM_RESERVED1 24
+#define SM_RESERVED2 25
+#define SM_RESERVED3 26
+#define SM_RESERVED4 27
+#define SM_CXMIN 28
+#define SM_CYMIN 29
+#define SM_CXSIZE 30
+#define SM_CYSIZE 31
+#define SM_CXSIZEFRAME 32
+#define SM_CXFRAME 32
+#define SM_CYSIZEFRAME 33
+#define SM_CYFRAME 33
+#define SM_CXMINTRACK 34
+#define SM_CYMINTRACK 35
+#define SM_CXDOUBLECLK 36
+#define SM_CYDOUBLECLK 37
+#define SM_CXICONSPACING 38
+#define SM_CYICONSPACING 39
+#define SM_MENUDROPALIGNMENT 40
+#define SM_PENWINDOWS 41
+#define SM_DBCSENABLED 42
+#define SM_CMOUSEBUTTONS 43
+#define SM_SECURE 44
+#define SM_CXEDGE 45
+#define SM_CYEDGE 46
+#define SM_CXMINSPACING 47
+#define SM_CYMINSPACING 48
+#define SM_CXSMICON 49
+#define SM_CYSMICON 50
+#define SM_CYSMCAPTION 51
+#define SM_CXSMSIZE 52
+#define SM_CYSMSIZE 53
+#define SM_CXMENUSIZE 54
+#define SM_CYMENUSIZE 55
+#define SM_ARRANGE 56
+#define SM_CXMINIMIZED 57
+#define SM_CYMINIMIZED 58
+#define SM_CXMAXTRACK 59
+#define SM_CYMAXTRACK 60
+#define SM_CXMAXIMIZED 61
+#define SM_CYMAXIMIZED 62
+#define SM_NETWORK 63
+#define LR_DEFAULTSIZE 64
+#define SM_CLEANBOOT 67
+#define SM_CXDRAG 68
+#define SM_CYDRAG 69
+#define SM_SHOWSOUNDS 70
+#define SM_CXMENUCHECK 71
+#define SM_CYMENUCHECK 72
+#define SM_SLOWMACHINE 73
+#define SM_MIDEASTENABLED 74
+#define SM_MOUSEWHEELPRESENT 75
+#define SM_XVIRTUALSCREEN 76
+#define SM_YVIRTUALSCREEN 77
+#define SM_CXVIRTUALSCREEN 78
+#define SM_CYVIRTUALSCREEN 79
+#define SM_CMONITORS 80
+#define SM_SAMEDISPLAYFORMAT 81
+#if (_WIN32_WINNT < 0x0400)
+#define SM_CMETRICS 76
+#else
+#define SM_CMETRICS 83
+#endif
+#define ARW_BOTTOMLEFT 0
+#define ARW_BOTTOMRIGHT 1
+#define ARW_HIDE 8
+#define ARW_TOPLEFT 2
+#define ARW_TOPRIGHT 3
+#define ARW_DOWN 4
+#define ARW_LEFT 0
+#define ARW_RIGHT 0
+#define ARW_UP 4
+#define UOI_FLAGS 1
+#define UOI_NAME 2
+#define UOI_TYPE 3
+#define UOI_USER_SID 4
+#define LR_DEFAULTCOLOR 0
+#define LR_MONOCHROME 1
+#define LR_COLOR 2
+#define LR_COPYRETURNORG 4
+#define LR_COPYDELETEORG 8
+#define LR_LOADFROMFILE 16
+#define LR_LOADTRANSPARENT 32
+#define LR_LOADREALSIZE 128
+#define LR_LOADMAP3DCOLORS 4096
+#define LR_CREATEDIBSECTION 8192
+#define LR_COPYFROMRESOURCE 0x4000
+#define LR_SHARED 32768
+#define KEYEVENTF_EXTENDEDKEY 1
+#define KEYEVENTF_KEYUP 2
+#define OBM_BTNCORNERS 32758
+#define OBM_BTSIZE 32761
+#define OBM_CHECK 32760
+#define OBM_CHECKBOXES 32759
+#define OBM_CLOSE 32754
+#define OBM_COMBO 32738
+#define OBM_DNARROW 32752
+#define OBM_DNARROWD 32742
+#define OBM_DNARROWI 32736
+#define OBM_LFARROW 32750
+#define OBM_LFARROWI 32734
+#define OBM_LFARROWD 32740
+#define OBM_MNARROW 32739
+#define OBM_OLD_CLOSE 32767
+#define OBM_OLD_DNARROW 32764
+#define OBM_OLD_LFARROW 32762
+#define OBM_OLD_REDUCE 32757
+#define OBM_OLD_RESTORE 32755
+#define OBM_OLD_RGARROW 32763
+#define OBM_OLD_UPARROW 32765
+#define OBM_OLD_ZOOM 32756
+#define OBM_REDUCE 32749
+#define OBM_REDUCED 32746
+#define OBM_RESTORE 32747
+#define OBM_RESTORED 32744
+#define OBM_RGARROW 32751
+#define OBM_RGARROWD 32741
+#define OBM_RGARROWI 32735
+#define OBM_SIZE 32766
+#define OBM_UPARROW 32753
+#define OBM_UPARROWD 32743
+#define OBM_UPARROWI 32737
+#define OBM_ZOOM 32748
+#define OBM_ZOOMD 32745
+#define OCR_NORMAL 32512
+#define OCR_IBEAM 32513
+#define OCR_WAIT 32514
+#define OCR_CROSS 32515
+#define OCR_UP 32516
+#define OCR_SIZE 32640
+#define OCR_ICON 32641
+#define OCR_SIZENWSE 32642
+#define OCR_SIZENESW 32643
+#define OCR_SIZEWE 32644
+#define OCR_SIZENS 32645
+#define OCR_SIZEALL 32646
+#define OCR_NO 32648
+#define OCR_APPSTARTING 32650
+#define OIC_SAMPLE 32512
+#define OIC_HAND 32513
+#define OIC_QUES 32514
+#define OIC_BANG 32515
+#define OIC_NOTE 32516
+#define OIC_WINLOGO 32517
+#define OIC_WARNING OIC_BANG
+#define OIC_ERROR OIC_HAND
+#define OIC_INFORMATION OIC_NOTE
+#define HELPINFO_MENUITEM 2
+#define HELPINFO_WINDOW 1
+#define MSGF_DIALOGBOX 0
+#define MSGF_MESSAGEBOX 1
+#define MSGF_MENU 2
+#define MSGF_MOVE 3
+#define MSGF_SIZE 4
+#define MSGF_SCROLLBAR 5
+#define MSGF_NEXTWINDOW 6
+#define MSGF_MAINLOOP 8
+#define MSGF_USER 4096
+#define MOUSEEVENTF_MOVE 1
+#define MOUSEEVENTF_LEFTDOWN 2
+#define MOUSEEVENTF_LEFTUP 4
+#define MOUSEEVENTF_RIGHTDOWN 8
+#define MOUSEEVENTF_RIGHTUP 16
+#define MOUSEEVENTF_MIDDLEDOWN 32
+#define MOUSEEVENTF_MIDDLEUP 64
+#define MOUSEEVENTF_WHEEL 0x0800 
+#define MOUSEEVENTF_ABSOLUTE 32768
+#define PM_NOREMOVE 0
+#define PM_REMOVE 1
+#define PM_NOYIELD 2
+#define HWND_BROADCAST  ((HWND)0xffff)
+#define HWND_BOTTOM ((HWND)1)
+#define HWND_NOTOPMOST ((HWND)(-2))
+#define HWND_TOP ((HWND)0)
+#define HWND_TOPMOST ((HWND)(-1))
+#define HWND_DESKTOP (HWND)0
+#define HWND_MESSAGE ((HWND)(-3)) /* w2k */
+#define RDW_ERASE 4
+#define RDW_FRAME 1024
+#define RDW_INTERNALPAINT 2
+#define RDW_INVALIDATE 1
+#define RDW_NOERASE 32
+#define RDW_NOFRAME 2048
+#define RDW_NOINTERNALPAINT 16
+#define RDW_VALIDATE 8
+#define RDW_ERASENOW 512
+#define RDW_UPDATENOW 256
+#define RDW_ALLCHILDREN 128
+#define RDW_NOCHILDREN 64
+#define SMTO_ABORTIFHUNG 2
+#define SMTO_BLOCK 1
+#define SMTO_NORMAL 0
+#define SIF_ALL 23
+#define SIF_PAGE 2
+#define SIF_POS 4
+#define SIF_RANGE 1
+#define SIF_DISABLENOSCROLL 8
+#define SIF_TRACKPOS   16
+#define SWP_DRAWFRAME 32
+#define SWP_FRAMECHANGED 32
+#define SWP_HIDEWINDOW 128
+#define SWP_NOACTIVATE 16
+#define SWP_NOCOPYBITS 256
+#define SWP_NOMOVE 2
+#define SWP_NOSIZE 1
+#define SWP_NOREDRAW 8
+#define SWP_NOZORDER 4
+#define SWP_SHOWWINDOW 64
+#define SWP_NOOWNERZORDER 512
+#define SWP_NOREPOSITION 512
+#define SWP_NOSENDCHANGING 1024
+#define SWP_DEFERERASE 8192
+#define SWP_ASYNCWINDOWPOS  16384
+#define HSHELL_ACTIVATESHELLWINDOW 3
+#define HSHELL_GETMINRECT 5
+#define HSHELL_LANGUAGE 8
+#define HSHELL_REDRAW 6
+#define HSHELL_TASKMAN 7
+#define HSHELL_WINDOWACTIVATED 4
+#define HSHELL_WINDOWCREATED 1
+#define HSHELL_WINDOWDESTROYED 2
+#define SPI_GETACCESSTIMEOUT 60
+#define SPI_GETANIMATION 72
+#define SPI_GETBEEP 1
+#define SPI_GETBORDER 5
+#define SPI_GETDEFAULTINPUTLANG 89
+#define SPI_GETDRAGFULLWINDOWS 38
+#define SPI_GETFASTTASKSWITCH 35
+#define SPI_GETFILTERKEYS 50
+#define SPI_GETFONTSMOOTHING 74
+#define SPI_GETGRIDGRANULARITY 18
+#define SPI_GETHIGHCONTRAST 66
+#define SPI_GETICONMETRICS 45
+#define SPI_GETICONTITLELOGFONT 31
+#define SPI_GETICONTITLEWRAP 25
+#define SPI_GETKEYBOARDDELAY 22
+#define SPI_GETKEYBOARDPREF 68
+#define SPI_GETKEYBOARDSPEED 10
+#define SPI_GETLOWPOWERACTIVE 83
+#define SPI_GETLOWPOWERTIMEOUT 79
+#define SPI_GETMENUDROPALIGNMENT 27
+#define SPI_GETMINIMIZEDMETRICS 43
+#define SPI_GETMOUSE 3
+#define SPI_GETMOUSEKEYS 54
+#define SPI_GETMOUSETRAILS 94
+#define SPI_GETNONCLIENTMETRICS 41
+#define SPI_GETPOWEROFFACTIVE 84
+#define SPI_GETPOWEROFFTIMEOUT 80
+#define SPI_GETSCREENREADER 70
+#define SPI_GETSCREENSAVEACTIVE 16
+#define SPI_GETSCREENSAVETIMEOUT 14
+#define SPI_GETSERIALKEYS 62
+#define SPI_GETSHOWSOUNDS 56
+#define SPI_GETSOUNDSENTRY 64
+#define SPI_GETSTICKYKEYS 58
+#define SPI_GETTOGGLEKEYS 52
+#define SPI_GETWINDOWSEXTENSION 92
+#define SPI_GETWORKAREA 48
+#define SPI_ICONHORIZONTALSPACING 13
+#define SPI_ICONVERTICALSPACING 24
+#define SPI_LANGDRIVER 12
+#define SPI_SCREENSAVERRUNNING 97
+#define SPI_SETACCESSTIMEOUT 61
+#define SPI_SETANIMATION 73
+#define SPI_SETBEEP 2
+#define SPI_SETBORDER 6
+#define SPI_SETDEFAULTINPUTLANG 90
+#define SPI_SETDESKPATTERN 21
+#define SPI_SETDESKWALLPAPER 20
+#define SPI_SETDOUBLECLICKTIME 32
+#define SPI_SETDOUBLECLKHEIGHT 30
+#define SPI_SETDOUBLECLKWIDTH 29
+#define SPI_SETDRAGFULLWINDOWS 37
+#define SPI_SETDRAGHEIGHT 77
+#define SPI_SETDRAGWIDTH 76
+#define SPI_SETFASTTASKSWITCH 36
+#define SPI_SETFILTERKEYS 51
+#define SPI_SETFONTSMOOTHING 75
+#define SPI_SETGRIDGRANULARITY 19
+#define SPI_SETHANDHELD 78
+#define SPI_SETHIGHCONTRAST 67
+#define SPI_SETICONMETRICS 46
+#define SPI_SETICONTITLELOGFONT 34
+#define SPI_SETICONTITLEWRAP 26
+#define SPI_SETKEYBOARDDELAY 23
+#define SPI_SETKEYBOARDPREF 69
+#define SPI_SETKEYBOARDSPEED 11
+#define SPI_SETLANGTOGGLE 91
+#define SPI_SETLOWPOWERACTIVE 85
+#define SPI_SETLOWPOWERTIMEOUT 81
+#define SPI_SETMENUDROPALIGNMENT 28
+#define SPI_SETMINIMIZEDMETRICS 44
+#define SPI_SETMOUSE 4
+#define SPI_SETMOUSEBUTTONSWAP 33
+#define SPI_SETMOUSEKEYS 55
+#define SPI_SETMOUSETRAILS 93
+#define SPI_SETNONCLIENTMETRICS 42
+#define SPI_SETPENWINDOWS 49
+#define SPI_SETPOWEROFFACTIVE 86
+#define SPI_SETPOWEROFFTIMEOUT 82
+#define SPI_SETSCREENREADER 71
+#define SPI_SETSCREENSAVEACTIVE 17
+#define SPI_SETSCREENSAVERRUNNING 97
+#define SPI_SETSCREENSAVETIMEOUT 15
+#define SPI_SETSERIALKEYS 63
+#define SPI_SETSHOWSOUNDS 57
+#define SPI_SETSOUNDSENTRY 65
+#define SPI_SETSTICKYKEYS 59
+#define SPI_SETTOGGLEKEYS 53
+#define SPI_SETWORKAREA 47
+#define SPIF_UPDATEINIFILE 1
+#define SPIF_SENDWININICHANGE 2
+#define SPIF_SENDCHANGE 2
+#define ATF_ONOFFFEEDBACK 2
+#define ATF_TIMEOUTON 1
+#define WM_APP 32768
+#define WM_ACTIVATE 6
+#define WM_ACTIVATEAPP 28
+/* FIXME/CHECK: Are WM_AFX{FIRST,LAST} valid for WINVER < 0x400? */
+#define WM_AFXFIRST 864
+#define WM_AFXLAST 895
+#define WM_ASKCBFORMATNAME 780
+#define WM_CANCELJOURNAL 75
+#define WM_CANCELMODE 31
+#define WM_CAPTURECHANGED 533
+#define WM_CHANGECBCHAIN 781
+#define WM_CHAR 258
+#define WM_CHARTOITEM 47
+#define WM_CHILDACTIVATE 34
+#define WM_CLEAR 771
+#define WM_CLOSE 16
+#define WM_COMMAND 273
+#define WM_COMMNOTIFY 68		/* obsolete */
+#define WM_COMPACTING 65
+#define WM_COMPAREITEM 57
+#define WM_CONTEXTMENU 123
+#define WM_COPY 769
+#define WM_COPYDATA 74
+#define WM_CREATE 1
+#define WM_CTLCOLORBTN 309
+#define WM_CTLCOLORDLG 310
+#define WM_CTLCOLOREDIT 307
+#define WM_CTLCOLORLISTBOX 308
+#define WM_CTLCOLORMSGBOX 306
+#define WM_CTLCOLORSCROLLBAR 311
+#define WM_CTLCOLORSTATIC 312
+#define WM_CUT 768
+#define WM_DEADCHAR 259
+#define WM_DELETEITEM 45
+#define WM_DESTROY 2
+#define WM_DESTROYCLIPBOARD 775
+#define WM_DEVICECHANGE 537
+#define WM_DEVMODECHANGE 27
+#define WM_DISPLAYCHANGE 126
+#define WM_DRAWCLIPBOARD 776
+#define WM_DRAWITEM 43
+#define WM_DROPFILES 563
+#define WM_ENABLE 10
+#define WM_ENDSESSION 22
+#define WM_ENTERIDLE 289
+#define WM_ENTERMENULOOP 529
+#define WM_ENTERSIZEMOVE 561
+#define WM_ERASEBKGND 20
+#define WM_EXITMENULOOP 530
+#define WM_EXITSIZEMOVE 562
+#define WM_FONTCHANGE 29
+#define WM_GETDLGCODE 135
+#define WM_GETFONT 49
+#define WM_GETHOTKEY 51
+#define WM_GETICON 127
+#define WM_GETMINMAXINFO 36
+#define WM_GETTEXT 13
+#define WM_GETTEXTLENGTH 14
+/* FIXME/CHECK: Are WM_HANDHEL{FIRST,LAST} valid for WINVER < 0x400? */
+#define WM_HANDHELDFIRST 856
+#define WM_HANDHELDLAST 863
+#define WM_HELP 83
+#define WM_HOTKEY 786
+#define WM_HSCROLL 276
+#define WM_HSCROLLCLIPBOARD 782
+#define WM_ICONERASEBKGND 39
+#define WM_INITDIALOG 272
+#define WM_INITMENU 278
+#define WM_INITMENUPOPUP 279
+#define WM_INPUTLANGCHANGE 81
+#define WM_INPUTLANGCHANGEREQUEST 80
+#define WM_KEYDOWN 256
+#define WM_KEYUP 257
+#define WM_KILLFOCUS 8
+#define WM_MDIACTIVATE 546
+#define WM_MDICASCADE 551
+#define WM_MDICREATE 544
+#define WM_MDIDESTROY 545
+#define WM_MDIGETACTIVE 553
+#define WM_MDIICONARRANGE 552
+#define WM_MDIMAXIMIZE 549
+#define WM_MDINEXT 548
+#define WM_MDIREFRESHMENU 564
+#define WM_MDIRESTORE 547
+#define WM_MDISETMENU 560
+#define WM_MDITILE 550
+#define WM_MEASUREITEM 44
+#define WM_MENUCHAR 288
+#define WM_MENUSELECT 287
+#define WM_NEXTMENU 531
+#define WM_MOVE 3
+#define WM_MOVING 534
+#define WM_NCACTIVATE 134
+#define WM_NCCALCSIZE 131
+#define WM_NCCREATE 129
+#define WM_NCDESTROY 130
+#define WM_NCHITTEST 132
+#define WM_NCLBUTTONDBLCLK 163
+#define WM_NCLBUTTONDOWN 161
+#define WM_NCLBUTTONUP 162
+#define WM_NCMBUTTONDBLCLK 169
+#define WM_NCMBUTTONDOWN 167
+#define WM_NCMBUTTONUP 168
+#define WM_NCMOUSEMOVE 160
+#define WM_NCPAINT 133
+#define WM_NCRBUTTONDBLCLK 166
+#define WM_NCRBUTTONDOWN 164
+#define WM_NCRBUTTONUP 165
+#define WM_NEXTDLGCTL 40
+#define WM_NEXTMENU 531
+#define WM_NOTIFY 78
+#define WM_NOTIFYFORMAT 85
+#define WM_NULL 0
+#define WM_PAINT 15
+#define WM_PAINTCLIPBOARD 777
+#define WM_PAINTICON 38
+#define WM_PALETTECHANGED 785
+#define WM_PALETTEISCHANGING 784
+#define WM_PARENTNOTIFY 528
+#define WM_PASTE 770
+#define WM_PENWINFIRST 896
+#define WM_PENWINLAST 911
+#define WM_POWER 72
+#define WM_POWERBROADCAST 536
+#define WM_PRINT 791
+#define WM_PRINTCLIENT 792
+#define WM_QUERYDRAGICON 55
+#define WM_QUERYENDSESSION 17
+#define WM_QUERYNEWPALETTE 783
+#define WM_QUERYOPEN 19
+#define WM_QUEUESYNC 35
+#define WM_QUIT 18
+#define WM_RENDERALLFORMATS 774
+#define WM_RENDERFORMAT 773
+#define WM_SETCURSOR 32
+#define WM_SETFOCUS 7
+#define WM_SETFONT 48
+#define WM_SETHOTKEY 50
+#define WM_SETICON 128
+#define WM_SETREDRAW 11
+#define WM_SETTEXT 12
+#define WM_SETTINGCHANGE 26
+#define WM_SHOWWINDOW 24
+#define WM_SIZE 5
+#define WM_SIZECLIPBOARD 779
+#define WM_SIZING 532
+#define WM_SPOOLERSTATUS 42
+#define WM_STYLECHANGED 125
+#define WM_STYLECHANGING 124
+#define WM_SYSCHAR 262
+#define WM_SYSCOLORCHANGE 21
+#define WM_SYSCOMMAND 274
+#define WM_SYSDEADCHAR 263
+#define WM_SYSKEYDOWN 260
+#define WM_SYSKEYUP 261
+#define WM_TCARD 82
+#define WM_TIMECHANGE 30
+#define WM_TIMER 275
+#define WM_UNDO 772
+#define WM_USER 1024
+#define WM_USERCHANGED 84
+#define WM_VKEYTOITEM 46
+#define WM_VSCROLL 277
+#define WM_VSCROLLCLIPBOARD 778
+#define WM_WINDOWPOSCHANGED 71
+#define WM_WINDOWPOSCHANGING 70
+#define WM_WININICHANGE 26
+#define WM_KEYFIRST 256
+#define WM_KEYLAST 264
+#define WM_SYNCPAINT  136
+#define WM_MOUSEACTIVATE 33
+#define WM_MOUSEMOVE 512
+#define WM_LBUTTONDOWN 513
+#define WM_LBUTTONUP 514
+#define WM_LBUTTONDBLCLK 515
+#define WM_RBUTTONDOWN 516
+#define WM_RBUTTONUP 517
+#define WM_RBUTTONDBLCLK 518
+#define WM_MBUTTONDOWN 519
+#define WM_MBUTTONUP 520
+#define WM_MBUTTONDBLCLK 521
+#define WM_MOUSEWHEEL 522
+#define WM_MOUSEFIRST 512
+#define WM_MOUSELAST 522
+#define WM_MOUSEHOVER	0x2A1
+#define WM_MOUSELEAVE	0x2A3
+#if(_WIN32_WINNT >= 0x0400)
+#define WHEEL_DELTA 120
+#define GET_WHEEL_DELTA_WPARAM(wparam) ((short)HIWORD (wparam))
+#endif
+#define BM_CLICK 245
+#define BM_GETCHECK 240
+#define BM_GETIMAGE 246
+#define BM_GETSTATE 242
+#define BM_SETCHECK 241
+#define BM_SETIMAGE 247
+#define BM_SETSTATE 243
+#define BM_SETSTYLE 244
+#define BN_CLICKED 0
+#define BN_DBLCLK 5
+#define BN_DISABLE 4
+#define BN_DOUBLECLICKED 5
+#define BN_HILITE 2
+#define BN_KILLFOCUS 7
+#define BN_PAINT 1
+#define BN_PUSHED 2
+#define BN_SETFOCUS 6
+#define BN_UNHILITE 3
+#define BN_UNPUSHED 3
+#define CB_ADDSTRING 323
+#define CB_DELETESTRING 324
+#define CB_DIR 325
+#define CB_FINDSTRING 332
+#define CB_FINDSTRINGEXACT 344
+#define CB_GETCOUNT 326
+#define CB_GETCURSEL 327
+#define CB_GETDROPPEDCONTROLRECT 338
+#define CB_GETDROPPEDSTATE 343
+#define CB_GETDROPPEDWIDTH 351
+#define CB_GETEDITSEL 320
+#define CB_GETEXTENDEDUI 342
+#define CB_GETHORIZONTALEXTENT 349
+#define CB_GETITEMDATA 336
+#define CB_GETITEMHEIGHT 340
+#define CB_GETLBTEXT 328
+#define CB_GETLBTEXTLEN 329
+#define CB_GETLOCALE 346
+#define CB_GETTOPINDEX 347
+#define CB_INITSTORAGE 353
+#define CB_INSERTSTRING 330
+#define CB_LIMITTEXT 321
+#define CB_RESETCONTENT 331
+#define CB_SELECTSTRING 333
+#define CB_SETCURSEL 334
+#define CB_SETDROPPEDWIDTH 352
+#define CB_SETEDITSEL 322
+#define CB_SETEXTENDEDUI 341
+#define CB_SETHORIZONTALEXTENT 350
+#define CB_SETITEMDATA 337
+#define CB_SETITEMHEIGHT 339
+#define CB_SETLOCALE 345
+#define CB_SETTOPINDEX 348
+#define CB_SHOWDROPDOWN 335
+#define CBN_CLOSEUP 8
+#define CBN_DBLCLK 2
+#define CBN_DROPDOWN 7
+#define CBN_EDITCHANGE 5
+#define CBN_EDITUPDATE 6
+#define CBN_ERRSPACE (-1)
+#define CBN_KILLFOCUS 4
+#define CBN_SELCHANGE 1
+#define CBN_SELENDCANCEL 10
+#define CBN_SELENDOK 9
+#define CBN_SETFOCUS 3
+#define EM_CANUNDO 198
+#define EM_CHARFROMPOS 215
+#define EM_EMPTYUNDOBUFFER 205
+#define EM_FMTLINES 200
+#define EM_GETFIRSTVISIBLELINE 206
+#define EM_GETHANDLE 189
+#define EM_GETLIMITTEXT 213
+#define EM_GETLINE 196
+#define EM_GETLINECOUNT 186
+#define EM_GETMARGINS 212
+#define EM_GETMODIFY 184
+#define EM_GETPASSWORDCHAR 210
+#define EM_GETRECT 178
+#define EM_GETSEL 176
+#define EM_GETTHUMB 190
+#define EM_GETWORDBREAKPROC 209
+#define EM_LIMITTEXT 197
+#define EM_LINEFROMCHAR 201
+#define EM_LINEINDEX 187
+#define EM_LINELENGTH 193
+#define EM_LINESCROLL 182
+#define EM_POSFROMCHAR 214
+#define EM_REPLACESEL 194
+#define EM_SCROLL 181
+#define EM_SCROLLCARET 183
+#define EM_SETHANDLE 188
+#define EM_SETLIMITTEXT 197
+#define EM_SETMARGINS 211
+#define EM_SETMODIFY 185
+#define EM_SETPASSWORDCHAR 204
+#define EM_SETREADONLY 207
+#define EM_SETRECT 179
+#define EM_SETRECTNP 180
+#define EM_SETSEL 177
+#define EM_SETTABSTOPS 203
+#define EM_SETWORDBREAKPROC 208
+#define EM_UNDO 199
+#define EN_CHANGE 768
+#define EN_ERRSPACE 1280
+#define EN_HSCROLL 1537
+#define EN_KILLFOCUS 512
+#define EN_MAXTEXT 1281
+#define EN_SETFOCUS 256
+#define EN_UPDATE 1024
+#define EN_VSCROLL 1538
+#define LB_ADDFILE 406
+#define LB_ADDSTRING 384
+#define LB_DELETESTRING 386
+#define LB_DIR 397
+#define LB_FINDSTRING 399
+#define LB_FINDSTRINGEXACT 418
+#define LB_GETANCHORINDEX 413
+#define LB_GETCARETINDEX 415
+#define LB_GETCOUNT 395
+#define LB_GETCURSEL 392
+#define LB_GETHORIZONTALEXTENT 403
+#define LB_GETITEMDATA 409
+#define LB_GETITEMHEIGHT 417
+#define LB_GETITEMRECT 408
+#define LB_GETLOCALE 422
+#define LB_GETSEL 391
+#define LB_GETSELCOUNT 400
+#define LB_GETSELITEMS 401
+#define LB_GETTEXT 393
+#define LB_GETTEXTLEN 394
+#define LB_GETTOPINDEX 398
+#define LB_INITSTORAGE 424
+#define LB_INSERTSTRING 385
+#define LB_ITEMFROMPOINT 425
+#define LB_RESETCONTENT 388
+#define LB_SELECTSTRING 396
+#define LB_SELITEMRANGE 411
+#define LB_SELITEMRANGEEX 387
+#define LB_SETANCHORINDEX 412
+#define LB_SETCARETINDEX 414
+#define LB_SETCOLUMNWIDTH 405
+#define LB_SETCOUNT 423
+#define LB_SETCURSEL 390
+#define LB_SETHORIZONTALEXTENT 404
+#define LB_SETITEMDATA 410
+#define LB_SETITEMHEIGHT 416
+#define LB_SETLOCALE 421
+#define LB_SETSEL 389
+#define LB_SETTABSTOPS 402
+#define LB_SETTOPINDEX 407
+#define LBN_DBLCLK 2
+#define LBN_ERRSPACE (-2)
+#define LBN_KILLFOCUS 5
+#define LBN_SELCANCEL 3
+#define LBN_SELCHANGE 1
+#define LBN_SETFOCUS 4
+#define SBM_ENABLE_ARROWS 228
+#define SBM_GETPOS 225
+#define SBM_GETRANGE 227
+#define SBM_GETSCROLLINFO 234
+#define SBM_SETPOS 224
+#define SBM_SETRANGE 226
+#define SBM_SETRANGEREDRAW 230
+#define SBM_SETSCROLLINFO 233
+#define STM_GETICON 369
+#define STM_GETIMAGE 371
+#define STM_SETICON 368
+#define STM_SETIMAGE 370
+#define STN_CLICKED 0
+#define STN_DBLCLK 1
+#define STN_DISABLE 3
+#define STN_ENABLE 2
+#define DM_GETDEFID WM_USER
+#define DM_SETDEFID (WM_USER+1)
+#define DM_REPOSITION (WM_USER+2)
+#define PSM_PAGEINFO (WM_USER+100)
+#define PSM_SHEETINFO (WM_USER+101)
+#define PSI_SETACTIVE 1
+#define PSI_KILLACTIVE 2
+#define PSI_APPLY 3
+#define PSI_RESET 4
+#define PSI_HASHELP 5
+#define PSI_HELP 6
+#define PSI_CHANGED 1
+#define PSI_GUISTART 2
+#define PSI_REBOOT 3
+#define PSI_GETSIBLINGS 4
+#define DCX_WINDOW 1
+#define DCX_CACHE 2
+#define DCX_PARENTCLIP 32
+#define DCX_CLIPSIBLINGS 16
+#define DCX_CLIPCHILDREN 8
+#define DCX_NORESETATTRS 4
+#define DCX_LOCKWINDOWUPDATE 0x400
+#define DCX_EXCLUDERGN 64
+#define DCX_INTERSECTRGN 128
+#define DCX_VALIDATE 0x200000
+#define GMDI_GOINTOPOPUPS 2
+#define GMDI_USEDISABLED 1
+#define FKF_AVAILABLE 2
+#define FKF_CLICKON 64
+#define FKF_FILTERKEYSON 1
+#define FKF_HOTKEYACTIVE 4
+#define FKF_HOTKEYSOUND 16
+#define FKF_CONFIRMHOTKEY 8
+#define FKF_INDICATOR 32
+#define HCF_HIGHCONTRASTON 1
+#define HCF_AVAILABLE 2
+#define HCF_HOTKEYACTIVE 4
+#define HCF_CONFIRMHOTKEY 8
+#define HCF_HOTKEYSOUND 16
+#define HCF_INDICATOR 32
+#define HCF_HOTKEYAVAILABLE 64
+#define MKF_AVAILABLE 2
+#define MKF_CONFIRMHOTKEY 8
+#define MKF_HOTKEYACTIVE 4
+#define MKF_HOTKEYSOUND 16
+#define MKF_INDICATOR 32
+#define MKF_MOUSEKEYSON 1
+#define MKF_MODIFIERS 64
+#define MKF_REPLACENUMBERS 128
+#define SERKF_ACTIVE 8 /* May be obsolete. Not in recent MS docs. */
+#define SERKF_AVAILABLE 2
+#define SERKF_INDICATOR 4
+#define SERKF_SERIALKEYSON 1
+#define SSF_AVAILABLE 2
+#define SSF_SOUNDSENTRYON 1
+#define SSTF_BORDER 2
+#define SSTF_CHARS 1
+#define SSTF_DISPLAY 3
+#define SSTF_NONE 0
+#define SSGF_DISPLAY 3
+#define SSGF_NONE 0
+#define SSWF_CUSTOM 4
+#define SSWF_DISPLAY 3
+#define SSWF_NONE 0
+#define SSWF_TITLE 1
+#define SSWF_WINDOW 2
+#define SKF_AUDIBLEFEEDBACK 64
+#define SKF_AVAILABLE 2
+#define SKF_CONFIRMHOTKEY 8
+#define SKF_HOTKEYACTIVE 4
+#define SKF_HOTKEYSOUND 16
+#define SKF_INDICATOR 32
+#define SKF_STICKYKEYSON 1
+#define SKF_TRISTATE 128
+#define SKF_TWOKEYSOFF 256
+#define TKF_AVAILABLE 2
+#define TKF_CONFIRMHOTKEY 8
+#define TKF_HOTKEYACTIVE 4
+#define TKF_HOTKEYSOUND 16
+#define TKF_TOGGLEKEYSON 1
+#define MDITILE_SKIPDISABLED 2
+#define MDITILE_HORIZONTAL 1
+#define MDITILE_VERTICAL 0
+#define VK_LBUTTON	1
+#define VK_RBUTTON	2
+#define VK_CANCEL	3
+#define VK_MBUTTON	4
+#define VK_BACK	8
+#define VK_TAB	9
+#define VK_CLEAR	12
+#define VK_RETURN	13
+#define VK_KANA		15
+#define VK_SHIFT	16
+#define VK_CONTROL	17
+#define VK_MENU	18
+#define VK_PAUSE	19
+#define VK_CAPITAL	20
+#define VK_ESCAPE	0x1B
+#define VK_SPACE	32
+#define VK_PRIOR	33
+#define VK_NEXT	34
+#define VK_END	35
+#define VK_HOME	36
+#define VK_LEFT	37
+#define VK_UP	38
+#define VK_RIGHT	39
+#define VK_DOWN	40
+#define VK_SELECT	41
+#define VK_PRINT	42
+#define VK_EXECUTE	43
+#define VK_SNAPSHOT	44
+#define VK_INSERT	45
+#define VK_DELETE	46
+#define VK_HELP	47
+#define VK_LWIN	0x5B
+#define VK_RWIN	0x5C
+#define VK_APPS	0x5D
+#define VK_NUMPAD0	0x60
+#define VK_NUMPAD1	0x61
+#define VK_NUMPAD2	0x62
+#define VK_NUMPAD3	0x63
+#define VK_NUMPAD4	0x64
+#define VK_NUMPAD5	0x65
+#define VK_NUMPAD6	0x66
+#define VK_NUMPAD7	0x67
+#define VK_NUMPAD8	0x68
+#define VK_NUMPAD9	0x69
+#define VK_MULTIPLY	0x6A
+#define VK_ADD	0x6B
+#define VK_SEPARATOR	0x6C
+#define VK_SUBTRACT	0x6D
+#define VK_DECIMAL	0x6E
+#define VK_DIVIDE	0x6F
+#define VK_F1	0x70
+#define VK_F2	0x71
+#define VK_F3	0x72
+#define VK_F4	0x73
+#define VK_F5	0x74
+#define VK_F6	0x75
+#define VK_F7	0x76
+#define VK_F8	0x77
+#define VK_F9	0x78
+#define VK_F10	0x79
+#define VK_F11	0x7A
+#define VK_F12	0x7B
+#define VK_F13	0x7C
+#define VK_F14	0x7D
+#define VK_F15	0x7E
+#define VK_F16	0x7F
+#define VK_F17	0x80
+#define VK_F18	0x81
+#define VK_F19	0x82
+#define VK_F20	0x83
+#define VK_F21	0x84
+#define VK_F22	0x85
+#define VK_F23	0x86
+#define VK_F24	0x87
+#define VK_NUMLOCK	0x90
+#define VK_SCROLL	0x91
+#define VK_LSHIFT	0xA0
+#define VK_RSHIFT	0xA1
+#define VK_LCONTROL	0xA2
+#define VK_RCONTROL	0xA3
+#define VK_LMENU	0xA4
+#define VK_RMENU	0xA5
+#define VK_PROCESSKEY	0xE5
+#define VK_ATTN	0xF6
+#define VK_CRSEL	0xF7
+#define VK_EXSEL	0xF8
+#define VK_EREOF	0xF9
+#define VK_PLAY	0xFA
+#define VK_ZOOM	0xFB
+#define VK_NONAME	0xFC
+#define VK_PA1	0xFD
+#define VK_OEM_CLEAR	0xFE
+#define TME_HOVER	1
+#define TME_LEAVE	2
+#define TME_QUERY	0x40000000
+#define TME_CANCEL	0x80000000
+#define HOVER_DEFAULT	0xFFFFFFFF
+#define MK_LBUTTON	1
+#define MK_RBUTTON	2
+#define MK_SHIFT	4
+#define MK_CONTROL	8
+#define MK_MBUTTON	16
+#define TPM_CENTERALIGN 4
+#define TPM_LEFTALIGN 0
+#define TPM_RIGHTALIGN 8
+#define TPM_LEFTBUTTON 0
+#define TPM_RIGHTBUTTON 2
+#define TPM_HORIZONTAL 0
+#define TPM_VERTICAL 64
+#define TPM_TOPALIGN 0
+#define TPM_VCENTERALIGN 16
+#define TPM_BOTTOMALIGN 32
+#define TPM_NONOTIFY 128
+#define TPM_RETURNCMD 256
+#define HELP_COMMAND 0x102
+#define HELP_CONTENTS 3
+#define HELP_CONTEXT 1
+#define HELP_CONTEXTPOPUP 8
+#define HELP_FORCEFILE 9
+#define HELP_HELPONHELP 4
+#define HELP_INDEX 3
+#define HELP_KEY 0x101
+#define HELP_MULTIKEY 0x201
+#define HELP_PARTIALKEY 0x105
+#define HELP_QUIT 2
+#define HELP_SETCONTENTS 5
+#define HELP_SETINDEX 5
+#define HELP_CONTEXTMENU 0xa
+#define HELP_FINDER 0xb
+#define HELP_WM_HELP 0xc
+#define HELP_TCARD 0x8000
+#define HELP_TCARD_DATA 16
+#define HELP_TCARD_OTHER_CALLER 0x11
+#define IDH_NO_HELP	28440
+#define IDH_MISSING_CONTEXT	28441
+#define IDH_GENERIC_HELP_BUTTON	28442
+#define IDH_OK	28443
+#define IDH_CANCEL	28444
+#define IDH_HELP	28445
+#define LB_CTLCODE 0
+#define LB_OKAY 0
+#define LB_ERR (-1)
+#define LB_ERRSPACE (-2)
+#define CB_OKAY 0
+#define CB_ERR (-1)
+#define CB_ERRSPACE (-2)
+#define HIDE_WINDOW 0
+#define SHOW_OPENWINDOW 1
+#define SHOW_ICONWINDOW 2
+#define SHOW_FULLSCREEN 3
+#define SHOW_OPENNOACTIVATE 4
+#define SW_PARENTCLOSING 1
+#define SW_OTHERZOOM 2
+#define SW_PARENTOPENING 3
+#define SW_OTHERUNZOOM 4
+#define KF_EXTENDED 256
+#define KF_DLGMODE 2048
+#define KF_MENUMODE 4096
+#define KF_ALTDOWN 8192
+#define KF_REPEAT 16384
+#define KF_UP 32768
+#define WSF_VISIBLE 1
+#define PWR_OK 1
+#define PWR_FAIL (-1)
+#define PWR_SUSPENDREQUEST 1
+#define PWR_SUSPENDRESUME 2
+#define PWR_CRITICALRESUME 3
+#define NFR_ANSI 1
+#define NFR_UNICODE 2
+#define NF_QUERY 3
+#define NF_REQUERY 4
+#define MENULOOP_WINDOW 0
+#define MENULOOP_POPUP 1
+#define WMSZ_LEFT 1
+#define WMSZ_RIGHT 2
+#define WMSZ_TOP 3
+#define WMSZ_TOPLEFT 4
+#define WMSZ_TOPRIGHT 5
+#define WMSZ_BOTTOM 6
+#define WMSZ_BOTTOMLEFT 7
+#define WMSZ_BOTTOMRIGHT 8
+#define HTERROR (-2)
+#define HTTRANSPARENT (-1)
+#define HTNOWHERE 0
+#define HTCLIENT 1
+#define HTCAPTION 2
+#define HTSYSMENU 3
+#define HTGROWBOX 4
+#define HTSIZE 4
+#define HTMENU 5
+#define HTHSCROLL 6
+#define HTVSCROLL 7
+#define HTMINBUTTON 8
+#define HTMAXBUTTON 9
+#define HTREDUCE 8
+#define HTZOOM 9
+#define HTLEFT 10
+#define HTSIZEFIRST 10
+#define HTRIGHT 11
+#define HTTOP 12
+#define HTTOPLEFT 13
+#define HTTOPRIGHT 14
+#define HTBOTTOM 15
+#define HTBOTTOMLEFT 16
+#define HTBOTTOMRIGHT 17
+#define HTSIZELAST 17
+#define HTBORDER 18
+#define HTOBJECT 19
+#define HTCLOSE 20
+#define HTHELP 21
+#define MA_ACTIVATE 1
+#define MA_ACTIVATEANDEAT 2
+#define MA_NOACTIVATE 3
+#define MA_NOACTIVATEANDEAT 4
+#define SIZE_RESTORED 0
+#define SIZE_MINIMIZED 1
+#define SIZE_MAXIMIZED 2
+#define SIZE_MAXSHOW 3
+#define SIZE_MAXHIDE 4
+#define SIZENORMAL 0
+#define SIZEICONIC 1
+#define SIZEFULLSCREEN 2
+#define SIZEZOOMSHOW 3
+#define SIZEZOOMHIDE 4
+#define WVR_ALIGNTOP 16
+#define WVR_ALIGNLEFT 32
+#define WVR_ALIGNBOTTOM 64
+#define WVR_ALIGNRIGHT 128
+#define WVR_HREDRAW 256
+#define WVR_VREDRAW 512
+#define WVR_REDRAW (WVR_HREDRAW|WVR_VREDRAW)
+#define WVR_VALIDRECTS 1024
+#define PRF_CHECKVISIBLE 1
+#define PRF_NONCLIENT 2
+#define PRF_CLIENT 4
+#define PRF_ERASEBKGND 8
+#define PRF_CHILDREN 16
+#define PRF_OWNED 32
+#define IDANI_OPEN 1
+#define IDANI_CLOSE 2
+#define IDANI_CAPTION 3
+#define WPF_RESTORETOMAXIMIZED 2
+#define WPF_SETMINPOSITION 1
+#define ODT_MENU 1
+#define ODT_LISTBOX 2
+#define ODT_COMBOBOX 3
+#define ODT_BUTTON 4
+#define ODT_STATIC 5
+#define ODA_DRAWENTIRE 1
+#define ODA_SELECT 2
+#define ODA_FOCUS 4
+#define ODS_SELECTED 1
+#define ODS_GRAYED 2
+#define ODS_DISABLED 4
+#define ODS_CHECKED 8
+#define ODS_FOCUS 16
+#define ODS_DEFAULT 32
+#define ODS_COMBOBOXEDIT 4096
+#define IDHOT_SNAPWINDOW (-1)
+#define IDHOT_SNAPDESKTOP (-2)
+#define DBWF_LPARAMPOINTER 0x8000
+#define DLGWINDOWEXTRA 30
+#define MNC_IGNORE 0
+#define MNC_CLOSE 1
+#define MNC_EXECUTE 2
+#define MNC_SELECT 3
+#define DOF_EXECUTABLE 0x8001
+#define DOF_DOCUMENT 0x8002
+#define DOF_DIRECTORY 0x8003
+#define DOF_MULTIPLE 0x8004
+#define DOF_PROGMAN 1
+#define DOF_SHELLDATA 2
+#define DO_DROPFILE 0x454C4946
+#define DO_PRINTFILE 0x544E5250
+#define SW_SCROLLCHILDREN 1
+#define SW_INVALIDATE 2
+#define SW_ERASE 4
+#define SC_SIZE 0xF000
+#define SC_MOVE 0xF010
+#define SC_MINIMIZE 0xF020
+#define SC_ICON 0xf020
+#define SC_MAXIMIZE 0xF030
+#define SC_ZOOM 0xF030
+#define SC_NEXTWINDOW 0xF040
+#define SC_PREVWINDOW 0xF050
+#define SC_CLOSE 0xF060
+#define SC_VSCROLL 0xF070
+#define SC_HSCROLL 0xF080
+#define SC_MOUSEMENU 0xF090
+#define SC_KEYMENU 0xF100
+#define SC_ARRANGE 0xF110
+#define SC_RESTORE 0xF120
+#define SC_TASKLIST 0xF130
+#define SC_SCREENSAVE 0xF140
+#define SC_HOTKEY 0xF150
+#define SC_DEFAULT 0xF160
+#define SC_MONITORPOWER 0xF170
+#define SC_CONTEXTHELP 0xF180
+#define SC_SEPARATOR 0xF00F
+#define EC_LEFTMARGIN 1
+#define EC_RIGHTMARGIN 2
+#define EC_USEFONTINFO 0xffff
+#define DC_HASDEFID 0x534B
+#define DLGC_WANTARROWS 1
+#define DLGC_WANTTAB 2
+#define DLGC_WANTALLKEYS 4
+#define DLGC_WANTMESSAGE 4
+#define DLGC_HASSETSEL 8
+#define DLGC_DEFPUSHBUTTON 16
+#define DLGC_UNDEFPUSHBUTTON 32
+#define DLGC_RADIOBUTTON 64
+#define DLGC_WANTCHARS 128
+#define DLGC_STATIC 256
+#define DLGC_BUTTON 0x2000
+#define LB_CTLCODE 0
+#define WA_INACTIVE 0
+#define WA_ACTIVE 1
+#define WA_CLICKACTIVE 2
+#define ICON_SMALL 0
+#define ICON_BIG 1
+#define HBMMENU_CALLBACK ((HBITMAP) -1)
+#define HBMMENU_SYSTEM ((HBITMAP)1)
+#define HBMMENU_MBAR_RESTORE ((HBITMAP)2)
+#define HBMMENU_MBAR_MINIMIZE ((HBITMAP)3)
+#define HBMMENU_MBAR_CLOSE ((HBITMAP)5)
+#define HBMMENU_MBAR_CLOSE_D ((HBITMAP)6)
+#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP)7)
+#define HBMMENU_POPUP_CLOSE ((HBITMAP)8)
+#define HBMMENU_POPUP_RESTORE ((HBITMAP)9)
+#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP)10)
+#define HBMMENU_POPUP_MINIMIZE ((HBITMAP)11)
+#define MOD_ALT 1
+#define MOD_CONTROL 2
+#define MOD_SHIFT 4
+#define MOD_WIN 8
+#define MOD_IGNORE_ALL_MODIFIER 1024
+#define MOD_ON_KEYUP  2048
+#define MOD_RIGHT 16384
+#define MOD_LEFT 32768
+#define LLKHF_ALTDOWN  0x00000020
+
+#ifndef RC_INVOKED
+typedef BOOL(CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
+typedef VOID(CALLBACK *TIMERPROC)(HWND,UINT,UINT,DWORD);
+typedef BOOL(CALLBACK *GRAYSTRINGPROC)(HDC,LPARAM,int);
+typedef LRESULT(CALLBACK *HOOKPROC)(int,WPARAM,LPARAM);
+typedef BOOL(CALLBACK *PROPENUMPROCA)(HWND,LPCSTR,HANDLE);
+typedef BOOL(CALLBACK *PROPENUMPROCW)(HWND,LPCWSTR,HANDLE);
+typedef BOOL(CALLBACK *PROPENUMPROCEXA)(HWND,LPSTR,HANDLE,DWORD);
+typedef BOOL(CALLBACK *PROPENUMPROCEXW)(HWND,LPWSTR,HANDLE,DWORD);
+typedef int(CALLBACK *EDITWORDBREAKPROCA)(LPSTR,int,int,int);
+typedef int(CALLBACK *EDITWORDBREAKPROCW)(LPWSTR,int,int,int);
+typedef LRESULT(CALLBACK *WNDPROC)(HWND,UINT,WPARAM,LPARAM);
+typedef BOOL(CALLBACK *DRAWSTATEPROC)(HDC,LPARAM,WPARAM,int,int);
+typedef BOOL(CALLBACK *WNDENUMPROC)(HWND,LPARAM);
+typedef BOOL(CALLBACK *ENUMWINDOWSPROC)(HWND,LPARAM);
+typedef BOOL(CALLBACK* MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM);
+typedef BOOL(CALLBACK *NAMEENUMPROCA)(LPSTR,LPARAM);
+typedef BOOL(CALLBACK *NAMEENUMPROCW)(LPWSTR,LPARAM);
+typedef NAMEENUMPROCA DESKTOPENUMPROCA;
+typedef NAMEENUMPROCW DESKTOPENUMPROCW;
+typedef NAMEENUMPROCA WINSTAENUMPROCA;
+typedef NAMEENUMPROCW WINSTAENUMPROCW;
+typedef void(CALLBACK *SENDASYNCPROC)(HWND,UINT,DWORD,LRESULT);
+DECLARE_HANDLE(HHOOK);
+DECLARE_HANDLE(HDWP);
+typedef struct tagACCEL {
+	BYTE fVirt;
+	WORD key;
+	WORD cmd;
+} ACCEL,*LPACCEL;
+typedef struct tagACCESSTIMEOUT {
+	UINT cbSize;
+	DWORD dwFlags;
+	DWORD iTimeOutMSec;
+} ACCESSTIMEOUT, *LPACCESSTIMEOUT;
+typedef struct tagANIMATIONINFO {
+	UINT cbSize;
+	int iMinAnimate;
+} ANIMATIONINFO,*LPANIMATIONINFO;
+typedef struct tagCREATESTRUCTA {
+	LPVOID	lpCreateParams;
+	HINSTANCE	hInstance;
+	HMENU	hMenu;
+	HWND	hwndParent;
+	int	cy;
+	int	cx;
+	int	y;
+	int	x;
+	LONG	style;
+	LPCSTR	lpszName;
+	LPCSTR	lpszClass;
+	DWORD	dwExStyle;
+} CREATESTRUCTA,*LPCREATESTRUCTA;
+typedef struct tagCREATESTRUCTW {
+	LPVOID	lpCreateParams;
+	HINSTANCE	hInstance;
+	HMENU	hMenu;
+	HWND	hwndParent;
+	int	cy;
+	int	cx;
+	int	y;
+	int	x;
+	LONG	style;
+	LPCWSTR	lpszName;
+	LPCWSTR	lpszClass;
+	DWORD	dwExStyle;
+} CREATESTRUCTW,*LPCREATESTRUCTW;
+typedef struct tagCBT_CREATEWNDA {
+	LPCREATESTRUCTA lpcs;
+	HWND	hwndInsertAfter;
+} CBT_CREATEWNDA, *LPCBT_CREATEWNDA;
+typedef struct tagCBT_CREATEWNDW {
+	LPCREATESTRUCTW lpcs;
+	HWND	hwndInsertAfter;
+} CBT_CREATEWNDW, *LPCBT_CREATEWNDW;
+typedef struct tagCBTACTIVATESTRUCT {
+	BOOL fMouse;
+	HWND hWndActive;
+} CBTACTIVATESTRUCT,*LPCBTACTIVATESTRUCT;
+typedef struct tagCLIENTCREATESTRUCT {
+	HANDLE	hWindowMenu;
+	UINT	idFirstChild;
+} CLIENTCREATESTRUCT,*LPCLIENTCREATESTRUCT;
+typedef struct tagCOMPAREITEMSTRUCT {
+	UINT	CtlType;
+	UINT	CtlID;
+	HWND	hwndItem;
+	UINT	itemID1;
+	DWORD	itemData1;
+	UINT	itemID2;
+	DWORD	itemData2;
+	DWORD	dwLocaleId;
+} COMPAREITEMSTRUCT,*LPCOMPAREITEMSTRUCT;
+typedef struct tagCOPYDATASTRUCT {
+	DWORD dwData;
+	DWORD cbData;
+	PVOID lpData;
+} COPYDATASTRUCT,*PCOPYDATASTRUCT;
+typedef struct tagCURSORSHAPE {
+	int xHotSpot;
+	int yHotSpot;
+	int cx;
+	int cy;
+	int cbWidth;
+    BYTE Planes;
+    BYTE BitsPixel;
+} CURSORSHAPE,*LPCURSORSHAPE;
+typedef struct tagCWPRETSTRUCT {
+	LRESULT lResult;
+	LPARAM lParam;
+	WPARAM wParam;
+	DWORD message;
+	HWND hwnd;
+} CWPRETSTRUCT;
+typedef struct tagCWPSTRUCT {
+	LPARAM lParam;
+	WPARAM wParam;
+	UINT message;
+	HWND hwnd;
+} CWPSTRUCT,*PCWPSTRUCT;
+typedef struct tagDEBUGHOOKINFO {
+	DWORD idThread;
+	DWORD idThreadInstaller;
+	LPARAM lParam;
+	WPARAM wParam;
+	int code;
+} DEBUGHOOKINFO,*PDEBUGHOOKINFO,*LPDEBUGHOOKINFO;
+typedef struct tagDELETEITEMSTRUCT {
+	UINT CtlType;
+	UINT CtlID;
+	UINT itemID;
+	HWND hwndItem;
+	UINT itemData;
+} DELETEITEMSTRUCT,*PDELETEITEMSTRUCT,*LPDELETEITEMSTRUCT;
+#pragma pack(push,2)
+typedef struct {
+	DWORD style;
+	DWORD dwExtendedStyle;
+	short x;
+	short y;
+	short cx;
+	short cy;
+	WORD id;
+} DLGITEMTEMPLATE,*LPDLGITEMTEMPLATE;
+typedef struct {
+	DWORD style;
+	DWORD dwExtendedStyle;
+	WORD cdit;
+	short x;
+	short y;
+	short cx;
+	short cy;
+} DLGTEMPLATE,*LPDLGTEMPLATE;
+typedef const DLGTEMPLATE *LPCDLGTEMPLATE;
+#pragma pack(pop)
+typedef struct tagDRAWITEMSTRUCT {
+	UINT CtlType;
+	UINT CtlID;
+	UINT itemID;
+	UINT itemAction;
+	UINT itemState;
+	HWND hwndItem;
+	HDC	hDC;
+	RECT rcItem;
+	DWORD itemData;
+} DRAWITEMSTRUCT,*LPDRAWITEMSTRUCT,*PDRAWITEMSTRUCT;
+typedef struct {
+	UINT cbSize;
+	int iTabLength;
+	int iLeftMargin;
+	int iRightMargin;
+	UINT uiLengthDrawn;
+} DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS;
+typedef struct tagPAINTSTRUCT {
+	HDC	hdc;
+	BOOL fErase;
+	RECT rcPaint;
+	BOOL fRestore;
+	BOOL fIncUpdate;
+	BYTE rgbReserved[32];
+} PAINTSTRUCT,*LPPAINTSTRUCT;
+typedef struct tagMSG {
+	HWND hwnd;
+	UINT message;
+	WPARAM wParam;
+	LPARAM lParam;
+	DWORD time;
+	POINT pt;
+} MSG,*LPMSG,*PMSG;
+typedef struct _ICONINFO {
+	BOOL fIcon;
+	DWORD xHotspot;
+	DWORD yHotspot;
+	HBITMAP hbmMask;
+	HBITMAP hbmColor;
+} ICONINFO,*PICONINFO;
+typedef struct tagNMHDR {
+	HWND hwndFrom;
+	UINT idFrom;
+	UINT code;
+} NMHDR,*LPNMHDR;
+typedef struct _WNDCLASSA {
+	UINT style;
+	WNDPROC lpfnWndProc;
+	int cbClsExtra;
+	int cbWndExtra;
+	HANDLE hInstance;
+	HICON hIcon;
+	HCURSOR hCursor;
+	HBRUSH hbrBackground;
+	LPCSTR lpszMenuName;
+	LPCSTR lpszClassName;
+} WNDCLASSA,*LPWNDCLASSA,*PWNDCLASSA;
+typedef struct _WNDCLASSW {
+	UINT style;
+	WNDPROC lpfnWndProc;
+	int cbClsExtra;
+	int cbWndExtra;
+	HANDLE hInstance;
+	HICON hIcon;
+	HCURSOR hCursor;
+	HBRUSH hbrBackground;
+	LPCWSTR lpszMenuName;
+	LPCWSTR lpszClassName;
+} WNDCLASSW,*LPWNDCLASSW,*PWNDCLASSW;
+typedef struct _WNDCLASSEXA {
+	UINT cbSize;
+	UINT style;
+	WNDPROC lpfnWndProc;
+	int cbClsExtra;
+	int cbWndExtra;
+	HANDLE hInstance;
+	HICON hIcon;
+	HCURSOR hCursor;
+	HBRUSH hbrBackground;
+	LPCSTR lpszMenuName;
+	LPCSTR lpszClassName;
+	HICON hIconSm;
+} WNDCLASSEXA,*LPWNDCLASSEXA,*PWNDCLASSEXA;
+typedef struct _WNDCLASSEXW {
+	UINT cbSize;
+	UINT style;
+	WNDPROC lpfnWndProc;
+	int cbClsExtra;
+	int cbWndExtra;
+	HANDLE hInstance;
+	HICON hIcon;
+	HCURSOR hCursor;
+	HBRUSH hbrBackground;
+	LPCWSTR lpszMenuName;
+	LPCWSTR lpszClassName;
+	HICON hIconSm;
+} WNDCLASSEXW,*LPWNDCLASSEXW,*PWNDCLASSEXW;
+typedef struct tagMENUITEMINFOA {
+	UINT cbSize;
+	UINT fMask;
+	UINT fType;
+	UINT fState;
+	UINT wID;
+	HMENU hSubMenu;
+	HBITMAP hbmpChecked;
+	HBITMAP hbmpUnchecked;
+	DWORD dwItemData;
+	LPSTR dwTypeData;
+	UINT cch;
+#if (_WIN32_WINNT >= 0x0500)
+	HBITMAP hbmpItem;
+#endif
+} MENUITEMINFOA,*LPMENUITEMINFOA;
+typedef const MENUITEMINFOA *LPCMENUITEMINFOA;
+typedef struct tagMENUITEMINFOW {
+	UINT cbSize;
+	UINT fMask;
+	UINT fType;
+	UINT fState;
+	UINT wID;
+	HMENU hSubMenu;
+	HBITMAP hbmpChecked;
+	HBITMAP hbmpUnchecked;
+	DWORD dwItemData;
+	LPWSTR dwTypeData;
+	UINT cch;
+#if (_WIN32_WINNT >= 0x0500)
+	HBITMAP hbmpItem;
+#endif
+} MENUITEMINFOW,*LPMENUITEMINFOW;
+typedef const MENUITEMINFOW *LPCMENUITEMINFOW;
+typedef struct tagSCROLLINFO {
+	UINT cbSize;
+	UINT fMask;
+	int nMin;
+	int nMax;
+	UINT nPage;
+	int nPos;
+	int nTrackPos;
+} SCROLLINFO,*LPSCROLLINFO;
+typedef const SCROLLINFO *LPCSCROLLINFO;
+typedef struct _WINDOWPLACEMENT {
+	UINT length;
+	UINT flags;
+	UINT showCmd;
+	POINT ptMinPosition;
+	POINT ptMaxPosition;
+	RECT rcNormalPosition;
+} WINDOWPLACEMENT,*LPWINDOWPLACEMENT,*PWINDOWPLACEMENT;
+typedef struct {
+	WORD versionNumber;
+	WORD offset;
+} MENUITEMTEMPLATEHEADER;
+typedef struct {
+	WORD mtOption;
+	WORD mtID;
+	WCHAR mtString[1];
+} MENUITEMTEMPLATE;
+typedef void MENUTEMPLATE,MENUTEMPLATEA,MENUTEMPLATEW,*LPMENUTEMPLATEA,*LPMENUTEMPLATEW,*LPMENUTEMPLATE;
+typedef struct tagHELPINFO {
+	UINT cbSize;
+	int iContextType;
+	int iCtrlId;
+	HANDLE hItemHandle;
+	DWORD dwContextId;
+	POINT MousePos;
+} HELPINFO,*LPHELPINFO;
+typedef void(CALLBACK *MSGBOXCALLBACK)(LPHELPINFO);
+typedef struct {
+	UINT cbSize;
+	HWND hwndOwner;
+	HINSTANCE hInstance;
+	LPCSTR lpszText;
+	LPCSTR lpszCaption;
+	DWORD dwStyle;
+	LPCSTR lpszIcon;
+	DWORD dwContextHelpId;
+	MSGBOXCALLBACK lpfnMsgBoxCallback;
+	DWORD dwLanguageId;
+} MSGBOXPARAMSA,*PMSGBOXPARAMSA,*LPMSGBOXPARAMSA;
+typedef struct {
+	UINT cbSize;
+	HWND hwndOwner;
+	HINSTANCE hInstance;
+	LPCWSTR lpszText;
+	LPCWSTR lpszCaption;
+	DWORD dwStyle;
+	LPCWSTR lpszIcon;
+	DWORD dwContextHelpId;
+	MSGBOXCALLBACK lpfnMsgBoxCallback;
+	DWORD dwLanguageId;
+} MSGBOXPARAMSW,*PMSGBOXPARAMSW,*LPMSGBOXPARAMSW;
+typedef struct tagUSEROBJECTFLAGS {
+	BOOL fInherit;
+	BOOL fReserved;
+	DWORD dwFlags;
+} USEROBJECTFLAGS;
+typedef struct tagFILTERKEYS {
+	UINT cbSize;
+	DWORD dwFlags;
+	DWORD iWaitMSec;
+	DWORD iDelayMSec;
+	DWORD iRepeatMSec;
+	DWORD iBounceMSec;
+} FILTERKEYS;
+typedef struct tagHIGHCONTRASTA {
+	UINT cbSize;
+	DWORD dwFlags;
+	LPSTR lpszDefaultScheme;
+} HIGHCONTRASTA,*LPHIGHCONTRASTA;
+typedef struct tagHIGHCONTRASTW {
+	UINT cbSize;
+	DWORD dwFlags;
+	LPWSTR lpszDefaultScheme;
+} HIGHCONTRASTW,*LPHIGHCONTRASTW;
+typedef struct tagICONMETRICSA {
+	UINT cbSize;
+	int iHorzSpacing;
+	int iVertSpacing;
+	int iTitleWrap;
+	LOGFONTA lfFont;
+} ICONMETRICSA,*LPICONMETRICSA;
+typedef struct tagICONMETRICSW {
+	UINT cbSize;
+	int iHorzSpacing;
+	int iVertSpacing;
+	int iTitleWrap;
+	LOGFONTW lfFont;
+} ICONMETRICSW,*LPICONMETRICSW;
+typedef struct tagMINIMIZEDMETRICS {
+	UINT cbSize;
+	int iWidth;
+	int iHorzGap;
+	int iVertGap;
+	int iArrange;
+} MINIMIZEDMETRICS,*LPMINIMIZEDMETRICS;
+typedef struct tagMOUSEKEYS{
+	UINT cbSize;
+	DWORD dwFlags;
+	DWORD iMaxSpeed;
+	DWORD iTimeToMaxSpeed;
+	DWORD iCtrlSpeed;
+	DWORD dwReserved1;
+	DWORD dwReserved2;
+} MOUSEKEYS, *LPMOUSEKEYS;
+typedef struct tagNONCLIENTMETRICSA {
+	UINT cbSize;
+	int iBorderWidth;
+	int iScrollWidth;
+	int iScrollHeight;
+	int iCaptionWidth;
+	int iCaptionHeight;
+	LOGFONTA lfCaptionFont;
+	int iSmCaptionWidth;
+	int iSmCaptionHeight;
+	LOGFONTA lfSmCaptionFont;
+	int iMenuWidth;
+	int iMenuHeight;
+	LOGFONTA lfMenuFont;
+	LOGFONTA lfStatusFont;
+	LOGFONTA lfMessageFont;
+} NONCLIENTMETRICSA,*LPNONCLIENTMETRICSA;
+typedef struct tagNONCLIENTMETRICSW {
+	UINT cbSize;
+	int iBorderWidth;
+	int iScrollWidth;
+	int iScrollHeight;
+	int iCaptionWidth;
+	int iCaptionHeight;
+	LOGFONTW lfCaptionFont;
+	int iSmCaptionWidth;
+	int iSmCaptionHeight;
+	LOGFONTW lfSmCaptionFont;
+	int iMenuWidth;
+	int iMenuHeight;
+	LOGFONTW lfMenuFont;
+	LOGFONTW lfStatusFont;
+	LOGFONTW lfMessageFont;
+} NONCLIENTMETRICSW,*LPNONCLIENTMETRICSW;
+typedef struct tagSERIALKEYSA {
+	UINT cbSize;
+	DWORD dwFlags;
+	LPSTR lpszActivePort;
+	LPSTR lpszPort;
+	UINT iBaudRate;
+	UINT iPortState;
+	UINT iActive;
+} SERIALKEYSA,*LPSERIALKEYSA;
+typedef struct tagSERIALKEYSW {
+	UINT cbSize;
+	DWORD dwFlags;
+	LPWSTR lpszActivePort;
+	LPWSTR lpszPort;
+	UINT iBaudRate;
+	UINT iPortState;
+	UINT iActive;
+} SERIALKEYSW,*LPSERIALKEYSW;
+typedef struct tagSOUNDSENTRYA {
+	UINT cbSize;
+	DWORD dwFlags;
+	DWORD iFSTextEffect;
+	DWORD iFSTextEffectMSec;
+	DWORD iFSTextEffectColorBits;
+	DWORD iFSGrafEffect;
+	DWORD iFSGrafEffectMSec;
+	DWORD iFSGrafEffectColor;
+	DWORD iWindowsEffect;
+	DWORD iWindowsEffectMSec;
+	LPSTR lpszWindowsEffectDLL;
+	DWORD iWindowsEffectOrdinal;
+} SOUNDSENTRYA,*LPSOUNDSENTRYA;
+typedef struct tagSOUNDSENTRYW {
+	UINT cbSize;
+	DWORD dwFlags;
+	DWORD iFSTextEffect;
+	DWORD iFSTextEffectMSec;
+	DWORD iFSTextEffectColorBits;
+	DWORD iFSGrafEffect;
+	DWORD iFSGrafEffectMSec;
+	DWORD iFSGrafEffectColor;
+	DWORD iWindowsEffect;
+	DWORD iWindowsEffectMSec;
+	LPWSTR lpszWindowsEffectDLL;
+	DWORD iWindowsEffectOrdinal;
+} SOUNDSENTRYW,*LPSOUNDSENTRYW;
+typedef struct tagSTICKYKEYS {
+	DWORD cbSize;
+	DWORD dwFlags;
+} STICKYKEYS,*LPSTICKYKEYS;
+typedef struct tagTOGGLEKEYS {
+	DWORD cbSize;
+	DWORD dwFlags;
+} TOGGLEKEYS;
+typedef struct tagTRACKMOUSEEVENT {
+	DWORD cbSize;
+	DWORD dwFlags;
+	HWND  hwndTrack;
+	DWORD dwHoverTime;
+} TRACKMOUSEEVENT,*LPTRACKMOUSEEVENT;
+typedef struct tagTPMPARAMS {
+	UINT cbSize;
+	RECT rcExclude;
+} TPMPARAMS,*LPTPMPARAMS;
+typedef struct tagEVENTMSG {
+	UINT message;
+	UINT paramL;
+	UINT paramH;
+	DWORD time;
+	HWND hwnd;
+} EVENTMSG,*PEVENTMSGMSG,*LPEVENTMSGMSG, *PEVENTMSG, *LPEVENTMSG;
+typedef struct _WINDOWPOS {
+	HWND hwnd;
+	HWND hwndInsertAfter;
+	int x;
+	int y;
+	int cx;
+	int cy;
+	UINT flags;
+} WINDOWPOS,*PWINDOWPOS,*LPWINDOWPOS;
+typedef struct tagMDICREATESTRUCTA {
+	LPCSTR szClass;
+	LPCSTR szTitle;
+	HANDLE hOwner;
+	int x;
+	int y;
+	int cx;
+	int cy;
+	DWORD style;
+	LPARAM lParam;
+} MDICREATESTRUCTA,*LPMDICREATESTRUCTA;
+typedef struct tagMDICREATESTRUCTW {
+	LPCWSTR szClass;
+	LPCWSTR szTitle;
+	HANDLE hOwner;
+	int x;
+	int y;
+	int cx;
+	int cy;
+	DWORD style;
+	LPARAM lParam;
+} MDICREATESTRUCTW,*LPMDICREATESTRUCTW;
+typedef struct tagMINMAXINFO {
+	POINT ptReserved;
+	POINT ptMaxSize;
+	POINT ptMaxPosition;
+	POINT ptMinTrackSize;
+	POINT ptMaxTrackSize;
+} MINMAXINFO,*PMINMAXINFO,*LPMINMAXINFO;
+typedef struct tagMDINEXTMENU {
+	HMENU hmenuIn;
+	HMENU hmenuNext;
+	HWND hwndNext;
+} MDINEXTMENU,*PMDINEXTMENU,*LPMDINEXTMENU;
+typedef struct tagMEASUREITEMSTRUCT {
+	UINT CtlType;
+	UINT CtlID;
+	UINT itemID;
+	UINT itemWidth;
+	UINT itemHeight;
+	DWORD itemData;
+} MEASUREITEMSTRUCT,*PMEASUREITEMSTRUCT,*LPMEASUREITEMSTRUCT;
+typedef struct tagDROPSTRUCT {
+	HWND hwndSource;
+	HWND hwndSink;
+	DWORD wFmt;
+	DWORD dwData;
+	POINT ptDrop;
+	DWORD dwControlData;
+} DROPSTRUCT,*PDROPSTRUCT,*LPDROPSTRUCT;
+typedef DWORD HELPPOLY;
+typedef struct tagMULTIKEYHELPA {
+	DWORD mkSize;
+	CHAR mkKeylist;
+	CHAR szKeyphrase[1];
+} MULTIKEYHELPA,*PMULTIKEYHELPA,*LPMULTIKEYHELPA;
+typedef struct tagMULTIKEYHELPW {
+	DWORD mkSize;
+	WCHAR mkKeylist;
+	WCHAR szKeyphrase[1];
+} MULTIKEYHELPW,*PMULTIKEYHELPW,*LPMULTIKEYHELPW;
+typedef struct tagHELPWININFOA {
+	int wStructSize;
+	int x;
+	int y;
+	int dx;
+	int dy;
+	int wMax;
+	CHAR rgchMember[2];
+} HELPWININFOA,*PHELPWININFOA,*LPHELPWININFOA;
+typedef struct tagHELPWININFOW {
+	int wStructSize;
+	int x;
+	int y;
+	int dx;
+	int dy;
+	int wMax;
+	WCHAR rgchMember[2];
+} HELPWININFOW,*PHELPWININFOW,*LPHELPWININFOW;
+typedef struct tagSTYLESTRUCT {  
+	DWORD styleOld;
+	DWORD styleNew;
+} STYLESTRUCT,*LPSTYLESTRUCT;
+typedef struct tagALTTABINFO {
+	DWORD cbSize;
+	int   cItems;
+	int   cColumns;
+	int   cRows;
+	int   iColFocus;
+	int   iRowFocus;
+	int   cxItem;
+	int   cyItem;
+	POINT ptStart;
+} ALTTABINFO, *PALTTABINFO, *LPALTTABINFO;
+typedef struct tagCOMBOBOXINFO {
+	DWORD cbSize;
+	RECT rcItem;
+	RECT rcButton;
+	DWORD stateButton;
+	HWND hwndCombo;
+	HWND hwndItem;
+	HWND hwndList;
+} COMBOBOXINFO, *PCOMBOBOXINFO, *LPCOMBOBOXINFO;
+typedef struct tagCURSORINFO {
+	DWORD cbSize;
+	DWORD flags;
+	HCURSOR hCursor;
+	POINT ptScreenPos;
+} CURSORINFO,*PCURSORINFO,*LPCURSORINFO;
+typedef struct tagMENUBARINFO {
+	DWORD cbSize;
+	RECT  rcBar;
+	HMENU hMenu;
+	HWND  hwndMenu;
+	BOOL  fBarFocused:1;
+	BOOL  fFocused:1;
+} MENUBARINFO, *PMENUBARINFO;
+typedef struct tagMENUINFO {
+	DWORD cbSize;
+	DWORD fMask;
+	DWORD dwStyle;
+	UINT cyMax;
+	HBRUSH  hbrBack;
+	DWORD   dwContextHelpID;
+	ULONG_PTR dwMenuData;
+} MENUINFO, *LPMENUINFO;
+typedef MENUINFO CONST *LPCMENUINFO; 
+#define CCHILDREN_SCROLLBAR 5
+typedef struct tagSCROLLBARINFO {
+	DWORD cbSize;
+	RECT  rcScrollBar;
+	int   dxyLineButton;
+	int   xyThumbTop;
+	int   xyThumbBottom;
+	int   reserved;
+	DWORD rgstate[CCHILDREN_SCROLLBAR + 1];
+} SCROLLBARINFO, *PSCROLLBARINFO, *LPSCROLLBARINFO;
+#define CCHILDREN_TITLEBAR 5
+typedef struct tagTITLEBARINFO {
+	DWORD cbSize;
+	RECT  rcTitleBar;
+	DWORD rgstate[CCHILDREN_TITLEBAR + 1];
+} TITLEBARINFO, *PTITLEBARINFO, *LPTITLEBARINFO;
+typedef struct tagWINDOWINFO {
+	DWORD cbSize;
+	RECT  rcWindow;
+	RECT  rcClient;
+	DWORD dwStyle;
+	DWORD dwExStyle;
+	DWORD dwWindowStatus;
+	UINT  cxWindowBorders;
+	UINT  cyWindowBorders;
+	ATOM  atomWindowType;
+	WORD  wCreatorVersion;
+} WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO;
+typedef struct tagLASTINPUTINFO {
+	UINT cbSize;
+	DWORD dwTime;
+} LASTINPUTINFO, * PLASTINPUTINFO;
+typedef struct tagMONITORINFO {
+	DWORD cbSize;
+	RECT rcMonitor;
+	RECT rcWork;
+	DWORD dwFlags;
+} MONITORINFO,*LPMONITORINFO;
+typedef struct tagKBDLLHOOKSTRUCT {
+	DWORD vkCode;
+	DWORD scanCode;
+	DWORD flags;
+	DWORD time;
+	DWORD dwExtraInfo;
+} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
+
+
+#define AnsiToOem CharToOemA
+#define OemToAnsi OemToCharA
+#define AnsiToOemBuff CharToOemBuffA
+#define OemToAnsiBuff OemToCharBuffA
+#define AnsiUpper CharUpperA
+#define AnsiUpperBuff CharUpperBuffA
+#define AnsiLower CharLowerA
+#define AnsiLowerBuff CharLowerBuffA
+#define AnsiNext CharNextA
+#define AnsiPrev CharPrevA
+#define MAKELPARAM(l,h) ((LPARAM)MAKELONG(l,h))
+#define MAKEWPARAM(l,h) ((WPARAM)MAKELONG(l,h))
+#define MAKELRESULT(l,h) ((LRESULT)MAKELONG(l,h))
+#define POINTSTOPOINT(p,ps) { \
+  (p).x=LOWORD(*(DWORD *)&ps); \
+  (p).y=HIWORD(*(DWORD *)&ps); \
+}
+#define POINTTOPOINTS(p) ((POINTS)MAKELONG((p).x,(p).y))
+
+HKL WINAPI ActivateKeyboardLayout(HKL,UINT);
+BOOL WINAPI AdjustWindowRect(LPRECT,DWORD,BOOL);
+BOOL WINAPI AdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD);
+BOOL WINAPI AnyPopup(void);
+BOOL WINAPI AppendMenuA(HMENU,UINT,UINT,LPCSTR);
+BOOL WINAPI AppendMenuW(HMENU,UINT,UINT,LPCWSTR);
+UINT WINAPI ArrangeIconicWindows(HWND);
+BOOL WINAPI AttachThreadInput(DWORD,DWORD,BOOL);
+HDWP WINAPI BeginDeferWindowPos(int);
+HDC WINAPI BeginPaint(HWND,LPPAINTSTRUCT);
+BOOL WINAPI BringWindowToTop(HWND);
+long WINAPI BroadcastSystemMessage(DWORD,LPDWORD,UINT,WPARAM,LPARAM);
+BOOL WINAPI CallMsgFilter(PMSG,int);
+LRESULT WINAPI CallNextHookEx(HHOOK,int,WPARAM,LPARAM);
+LRESULT WINAPI CallWindowProcA(WNDPROC,HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI CallWindowProcW(WNDPROC,HWND,UINT,WPARAM,LPARAM);
+WORD WINAPI CascadeWindows(HWND,UINT,LPCRECT,UINT,const HWND*);
+BOOL WINAPI ChangeClipboardChain(HWND,HWND);
+LONG WINAPI ChangeDisplaySettingsA(PDEVMODEA,DWORD);
+LONG WINAPI ChangeDisplaySettingsW(PDEVMODEW,DWORD);
+BOOL WINAPI ChangeMenuA(HMENU,UINT,LPCSTR,UINT,UINT);
+BOOL WINAPI ChangeMenuW(HMENU,UINT,LPCWSTR,UINT,UINT);
+LPSTR WINAPI CharLowerA(LPSTR);
+LPWSTR WINAPI CharLowerW(LPWSTR);
+DWORD WINAPI CharLowerBuffA(LPSTR,DWORD);
+DWORD WINAPI CharLowerBuffW(LPWSTR,DWORD);
+LPSTR WINAPI CharNextA(LPCSTR);
+LPWSTR WINAPI CharNextW(LPCWSTR);
+LPSTR WINAPI CharNextExA(WORD,LPCSTR,DWORD);
+LPWSTR WINAPI CharNextExW(WORD,LPCWSTR,DWORD);
+LPSTR WINAPI CharPrevA(LPCSTR,LPCSTR);
+LPWSTR WINAPI CharPrevW(LPCWSTR,LPCWSTR);
+LPSTR WINAPI CharPrevExA(WORD,LPCSTR,LPCSTR,DWORD);
+LPWSTR WINAPI CharPrevExW(WORD,LPCWSTR,LPCWSTR,DWORD);
+BOOL WINAPI CharToOemA(LPCSTR,LPSTR);
+BOOL WINAPI CharToOemW(LPCWSTR,LPSTR);
+BOOL WINAPI CharToOemBuffA(LPCSTR,LPSTR,DWORD);
+BOOL WINAPI CharToOemBuffW(LPCWSTR,LPSTR,DWORD);
+LPSTR WINAPI CharUpperA(LPSTR);
+LPWSTR WINAPI CharUpperW(LPWSTR);
+DWORD WINAPI CharUpperBuffA(LPSTR,DWORD);
+DWORD WINAPI CharUpperBuffW(LPWSTR,DWORD);
+BOOL WINAPI CheckDlgButton(HWND,int,UINT);
+DWORD WINAPI CheckMenuItem(HMENU,UINT,UINT);
+BOOL WINAPI CheckMenuRadioItem(HMENU,UINT,UINT,UINT,UINT);
+BOOL WINAPI CheckRadioButton(HWND,int,int,int);
+HWND WINAPI ChildWindowFromPoint(HWND,POINT);
+HWND WINAPI ChildWindowFromPointEx(HWND,POINT,UINT);
+BOOL WINAPI ClientToScreen(HWND,LPPOINT);
+BOOL WINAPI ClipCursor(LPCRECT);
+BOOL WINAPI CloseClipboard(void);
+BOOL WINAPI CloseDesktop(HDESK);
+BOOL WINAPI CloseWindow(HWND);
+BOOL WINAPI CloseWindowStation(HWINSTA);
+int WINAPI CopyAcceleratorTableA(HACCEL,LPACCEL,int);
+int WINAPI CopyAcceleratorTableW(HACCEL,LPACCEL,int);
+HCURSOR WINAPI CopyCursor(HCURSOR);
+HICON WINAPI CopyIcon(HICON);
+HANDLE WINAPI CopyImage(HANDLE,UINT,int,int,UINT);
+BOOL WINAPI CopyRect(LPRECT,LPCRECT);
+int WINAPI CountClipboardFormats(void);
+HACCEL WINAPI CreateAcceleratorTableA(LPACCEL,int);
+HACCEL WINAPI CreateAcceleratorTableW(LPACCEL,int);
+BOOL WINAPI CreateCaret(HWND,HBITMAP,int,int);
+HCURSOR WINAPI CreateCursor(HINSTANCE,int,int,int,int,PCVOID,PCVOID);
+HDESK WINAPI CreateDesktopA(LPSTR,LPSTR,LPDEVMODEA,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+HDESK WINAPI CreateDesktopW(LPWSTR,LPWSTR,LPDEVMODEW,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+#define CreateDialogA(h,n,w,f) CreateDialogParamA(h,n,w,f,0)
+#define CreateDialogW(h,n,w,f) CreateDialogParamW(h,n,w,f,0)
+#define CreateDialogIndirectA(h,t,w,f) CreateDialogIndirectParamA(h,t,w,f,0)
+#define CreateDialogIndirectW(h,t,w,f) CreateDialogIndirectParamW(h,t,w,f,0)
+HWND WINAPI CreateDialogIndirectParamA(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM);
+HWND WINAPI CreateDialogIndirectParamW(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM);
+HWND WINAPI CreateDialogParamA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);
+HWND WINAPI CreateDialogParamW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);
+HICON WINAPI CreateIcon(HINSTANCE,int,int,BYTE,BYTE,const BYTE*,const BYTE*);
+HICON WINAPI CreateIconFromResource(PBYTE,DWORD,BOOL,DWORD);
+HICON WINAPI CreateIconFromResourceEx(PBYTE,DWORD,BOOL,DWORD,int,int,UINT);
+HICON WINAPI CreateIconIndirect(PICONINFO);
+HWND WINAPI CreateMDIWindowA(LPSTR,LPSTR,DWORD,int,int,int,int,HWND,HINSTANCE,LPARAM);
+HWND WINAPI CreateMDIWindowW(LPWSTR,LPWSTR,DWORD,int,int,int,int,HWND,HINSTANCE,LPARAM);
+HMENU WINAPI CreateMenu(void);
+HMENU WINAPI CreatePopupMenu(void);
+#define CreateWindowA(a,b,c,d,e,f,g,h,i,j,k) CreateWindowExA(0,a,b,c,d,e,f,g,h,i,j,k)
+#define CreateWindowW(a,b,c,d,e,f,g,h,i,j,k) CreateWindowExW(0,a,b,c,d,e,f,g,h,i,j,k)
+HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
+HWND WINAPI CreateWindowExW(DWORD,LPCWSTR,LPCWSTR,DWORD,int,int,int,int,HWND,HMENU,HINSTANCE,LPVOID);
+HWINSTA WINAPI CreateWindowStationA(LPSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+HWINSTA WINAPI CreateWindowStationW(LPWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES);
+LRESULT WINAPI DefDlgProcA(HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI DefDlgProcW(HWND,UINT,WPARAM,LPARAM);
+HDWP WINAPI DeferWindowPos(HDWP,HWND,HWND,int,int,int,int,UINT);
+LRESULT WINAPI DefFrameProcA(HWND,HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI DefFrameProcW(HWND,HWND,UINT,WPARAM,LPARAM);
+#define DefHookProc(c,p,lp,h) CallNextHookEx((HHOOK)*h,c,p,lp)
+LRESULT WINAPI DefMDIChildProcA(HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI DefMDIChildProcW(HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI DefWindowProcA(HWND,UINT,WPARAM,LPARAM);
+LRESULT WINAPI DefWindowProcW(HWND,UINT,WPARAM,LPARAM);
+BOOL WINAPI DeleteMenu(HMENU,UINT,UINT);
+BOOL WINAPI DestroyAcceleratorTable(HACCEL);
+BOOL WINAPI DestroyCaret(void);
+BOOL WINAPI DestroyCursor(HCURSOR);
+BOOL WINAPI DestroyIcon(HICON);
+BOOL WINAPI DestroyMenu(HMENU);
+BOOL WINAPI DestroyWindow(HWND);
+#define DialogBoxA(i,t,p,f) DialogBoxParamA(i,t,p,f,0)
+#define DialogBoxW(i,t,p,f) DialogBoxParamW(i,t,p,f,0)
+#define DialogBoxIndirectA(i,t,p,f) DialogBoxIndirectParamA(i,t,p,f,0)
+#define DialogBoxIndirectW(i,t,p,f) DialogBoxIndirectParamW(i,t,p,f,0)
+int WINAPI DialogBoxIndirectParamA(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM);
+int WINAPI DialogBoxIndirectParamW(HINSTANCE,LPCDLGTEMPLATE,HWND,DLGPROC,LPARAM);
+int WINAPI DialogBoxParamA(HINSTANCE,LPCSTR,HWND,DLGPROC,LPARAM);
+int WINAPI DialogBoxParamW(HINSTANCE,LPCWSTR,HWND,DLGPROC,LPARAM);
+LONG WINAPI DispatchMessageA(const MSG*);
+LONG WINAPI DispatchMessageW(const MSG*);
+int WINAPI DlgDirListA(HWND,LPSTR,int,int,UINT);
+int WINAPI DlgDirListW(HWND,LPWSTR,int,int,UINT);
+int WINAPI DlgDirListComboBoxA(HWND,LPSTR,int,int,UINT);
+int WINAPI DlgDirListComboBoxW(HWND,LPWSTR,int,int,UINT);
+BOOL WINAPI DlgDirSelectComboBoxExA(HWND,LPSTR,int,int);
+BOOL WINAPI DlgDirSelectComboBoxExW(HWND,LPWSTR,int,int);
+BOOL WINAPI DlgDirSelectExA(HWND,LPSTR,int,int);
+BOOL WINAPI DlgDirSelectExW(HWND,LPWSTR,int,int);
+BOOL WINAPI DragDetect(HWND,POINT);
+DWORD WINAPI DragObject(HWND,HWND,UINT,DWORD,HCURSOR);
+BOOL WINAPI DrawAnimatedRects(HWND,int,LPCRECT,LPCRECT);
+BOOL WINAPI DrawCaption(HWND,HDC,LPCRECT,UINT);
+BOOL WINAPI DrawEdge(HDC,LPRECT,UINT,UINT);
+BOOL WINAPI DrawFocusRect(HDC,LPCRECT);
+BOOL WINAPI DrawFrameControl(HDC,LPRECT,UINT,UINT);
+BOOL WINAPI DrawIcon(HDC,int,int,HICON);
+BOOL WINAPI DrawIconEx(HDC,int,int,HICON,int,int,UINT,HBRUSH,UINT);
+BOOL WINAPI DrawMenuBar(HWND);
+BOOL WINAPI DrawStateA(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,int,int,int,int,UINT);
+BOOL WINAPI DrawStateW(HDC,HBRUSH,DRAWSTATEPROC,LPARAM,WPARAM,int,int,int,int,UINT);
+int WINAPI DrawTextA(HDC,LPCSTR,int,LPRECT,UINT);
+int WINAPI DrawTextW(HDC,LPCWSTR,int,LPRECT,UINT);
+int WINAPI DrawTextExA(HDC,LPSTR,int,LPRECT,UINT,LPDRAWTEXTPARAMS);
+int WINAPI DrawTextExW(HDC,LPWSTR,int,LPRECT,UINT,LPDRAWTEXTPARAMS);
+BOOL WINAPI EmptyClipboard(void);
+BOOL WINAPI EnableMenuItem(HMENU,UINT,UINT);
+BOOL WINAPI EnableScrollBar(HWND,UINT,UINT);
+BOOL WINAPI EnableWindow(HWND,BOOL);
+BOOL WINAPI EndDeferWindowPos(HDWP);
+BOOL WINAPI EndDialog(HWND,int);
+BOOL WINAPI EndMenu(VOID);
+BOOL WINAPI EndPaint(HWND,const PAINTSTRUCT*);
+BOOL WINAPI EnumChildWindows(HWND,ENUMWINDOWSPROC,LPARAM);
+UINT WINAPI EnumClipboardFormats(UINT);
+BOOL WINAPI EnumDesktopsA(HWINSTA,DESKTOPENUMPROCA,LPARAM);
+BOOL WINAPI EnumDesktopsW(HWINSTA,DESKTOPENUMPROCW,LPARAM);
+BOOL WINAPI EnumDesktopWindows(HDESK,ENUMWINDOWSPROC,LPARAM);
+BOOL WINAPI EnumDisplayMonitors(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
+BOOL WINAPI EnumDisplaySettingsA(LPCSTR,DWORD,PDEVMODEA);
+BOOL WINAPI EnumDisplaySettingsW(LPCWSTR,DWORD,PDEVMODEW);
+int WINAPI EnumPropsA(HWND,PROPENUMPROCA);
+int WINAPI EnumPropsW(HWND,PROPENUMPROCW);
+int WINAPI EnumPropsExA(HWND,PROPENUMPROCEXA,LPARAM);
+int WINAPI EnumPropsExW(HWND,PROPENUMPROCEXW,LPARAM);
+#define EnumTaskWindows(h,f,p) EnumThreadWindows((DWORD)h,f,p)
+BOOL WINAPI EnumThreadWindows(DWORD,WNDENUMPROC,LPARAM);
+BOOL WINAPI EnumWindows(WNDENUMPROC,LPARAM);
+BOOL WINAPI EnumWindowStationsA(WINSTAENUMPROCA,LPARAM);
+BOOL WINAPI EnumWindowStationsW(WINSTAENUMPROCW,LPARAM);
+BOOL WINAPI EqualRect(LPCRECT,LPCRECT);
+#define ExitWindows(r,c) ExitWindowsEx(EWX_LOGOFF,0)
+BOOL WINAPI ExitWindowsEx(UINT,DWORD);
+HWND WINAPI FindWindowA(LPCSTR,LPCSTR);
+HWND WINAPI FindWindowExA(HWND,HWND,LPCSTR,LPCSTR);
+HWND WINAPI FindWindowExW(HWND,HWND,LPCWSTR,LPCWSTR);
+HWND WINAPI FindWindowW(LPCWSTR,LPCWSTR);
+BOOL WINAPI FlashWindow(HWND,BOOL);
+int WINAPI FrameRect(HDC,LPCRECT,HBRUSH);
+BOOL WINAPI FrameRgn(HDC,HRGN,HBRUSH,int,int);
+HWND WINAPI GetActiveWindow(void);
+SHORT WINAPI GetAsyncKeyState(int);
+HWND WINAPI GetCapture(void);
+UINT WINAPI GetCaretBlinkTime(void);
+BOOL WINAPI GetCaretPos(LPPOINT);
+BOOL WINAPI GetClassInfoA(HINSTANCE,LPCSTR,PWNDCLASSA);
+BOOL WINAPI GetClassInfoExA(HINSTANCE,LPCSTR,PWNDCLASSEXA);
+BOOL WINAPI GetClassInfoW(HINSTANCE,LPCWSTR,PWNDCLASSW);
+BOOL WINAPI GetClassInfoExW(HINSTANCE,LPCWSTR,PWNDCLASSEXW);
+DWORD WINAPI GetClassLongA(HWND,int);
+DWORD WINAPI GetClassLongW(HWND,int);
+int WINAPI GetClassNameA(HWND,LPSTR,int);
+int WINAPI GetClassNameW(HWND,LPWSTR,int);
+WORD WINAPI GetClassWord(HWND,int);
+BOOL WINAPI GetClientRect(HWND,LPRECT);
+HANDLE WINAPI GetClipboardData(UINT);
+int WINAPI GetClipboardFormatNameA(UINT,LPSTR,int);
+int WINAPI GetClipboardFormatNameW(UINT,LPWSTR,int);
+HWND WINAPI GetClipboardOwner(void);
+HWND WINAPI GetClipboardViewer(void);
+BOOL WINAPI GetClipCursor(LPRECT);
+BOOL WINAPI GetCursorPos(LPPOINT);
+HDC WINAPI GetDC(HWND);
+HDC WINAPI GetDCEx(HWND,HRGN,DWORD);
+HWND WINAPI GetDesktopWindow(void);
+long WINAPI GetDialogBaseUnits(void);
+int WINAPI GetDlgCtrlID(HWND);
+HWND WINAPI GetDlgItem(HWND,int);
+UINT WINAPI GetDlgItemInt(HWND,int,PBOOL,BOOL);
+UINT WINAPI GetDlgItemTextA(HWND,int,LPSTR,int);
+UINT WINAPI GetDlgItemTextW(HWND,int,LPWSTR,int);
+UINT WINAPI GetDoubleClickTime(void);
+HWND WINAPI GetFocus(void);
+HWND WINAPI GetForegroundWindow(void);
+BOOL WINAPI GetIconInfo(HICON,PICONINFO);
+BOOL WINAPI GetInputState(void);
+UINT WINAPI GetKBCodePage(void);
+HKL WINAPI GetKeyboardLayout(DWORD);
+int WINAPI GetKeyboardLayoutList(int,HKL*);
+BOOL WINAPI GetKeyboardLayoutNameA(LPSTR);
+BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR);
+BOOL WINAPI GetKeyboardState(PBYTE);
+int WINAPI GetKeyboardType(int);
+int WINAPI GetKeyNameTextA(LONG,LPSTR,int);
+int WINAPI GetKeyNameTextW(LONG,LPWSTR,int);
+SHORT WINAPI GetKeyState(int);
+HWND WINAPI GetLastActivePopup(HWND);
+DWORD WINAPI GetLastError(void);
+HMENU WINAPI GetMenu(HWND);
+LONG WINAPI GetMenuCheckMarkDimensions(void);
+DWORD WINAPI GetMenuContextHelpId(HMENU);
+UINT WINAPI GetMenuDefaultItem(HMENU,UINT,UINT);
+int WINAPI GetMenuItemCount(HMENU);
+UINT WINAPI GetMenuItemID(HMENU,int);
+BOOL WINAPI GetMenuItemInfoA(HMENU,UINT,BOOL,LPMENUITEMINFOA);
+BOOL WINAPI GetMenuItemInfoW(HMENU,UINT,BOOL,LPMENUITEMINFOW);
+BOOL WINAPI GetMenuItemRect(HWND,HMENU,UINT,LPRECT);
+UINT WINAPI GetMenuState(HMENU,UINT,UINT);
+int WINAPI GetMenuStringA(HMENU,UINT,LPSTR,int,UINT);
+int WINAPI GetMenuStringW(HMENU,UINT,LPWSTR,int,UINT);
+BOOL WINAPI GetMessageA(LPMSG,HWND,UINT,UINT);
+BOOL WINAPI GetMessageW(LPMSG,HWND,UINT,UINT);
+LONG WINAPI GetMessageExtraInfo(void);
+DWORD WINAPI GetMessagePos(void);
+LONG WINAPI GetMessageTime(void);
+HWND WINAPI GetNextDlgGroupItem(HWND,HWND,BOOL);
+HWND WINAPI GetNextDlgTabItem(HWND,HWND,BOOL);
+#define GetNextWindow(h,c) GetWindow(h,c)
+HWND WINAPI GetOpenClipboardWindow(void);
+HWND WINAPI GetParent(HWND);
+int WINAPI GetPriorityClipboardFormat(UINT*,int);
+HANDLE WINAPI GetPropA(HWND,LPCSTR);
+HANDLE WINAPI GetPropW(HWND,LPCWSTR);
+DWORD WINAPI GetQueueStatus(UINT);
+BOOL WINAPI GetScrollInfo(HWND,int,LPSCROLLINFO);
+int WINAPI GetScrollPos(HWND,int);
+BOOL WINAPI GetScrollRange(HWND,int,LPINT,LPINT);
+HMENU WINAPI GetSubMenu(HMENU,int);
+DWORD WINAPI GetSysColor(int);
+HBRUSH WINAPI GetSysColorBrush(int);
+#define GetSysModalWindow() (NULL)
+HMENU WINAPI GetSystemMenu(HWND,BOOL);
+int WINAPI GetSystemMetrics(int);
+DWORD WINAPI GetTabbedTextExtentA(HDC,LPCSTR,int,int,LPINT);
+DWORD WINAPI GetTabbedTextExtentW(HDC,LPCWSTR,int,int,LPINT);
+LONG WINAPI GetWindowLongA(HWND,int);
+LONG WINAPI GetWindowLongW(HWND,int);
+#ifdef _WIN64
+LONG_PTR WINAPI GetWindowLongPtrA(HWND,int);
+LONG_PTR WINAPI GetWindowLongPtrW(HWND,int);
+#else
+#define GetWindowLongPtrA GetWindowLongA
+#define GetWindowLongPtrW GetWindowLongW
+#endif
+HDESK WINAPI GetThreadDesktop(DWORD);
+HWND WINAPI GetTopWindow(HWND);
+BOOL WINAPI GetUpdateRect(HWND,LPRECT,BOOL);
+int WINAPI GetUpdateRgn(HWND,HRGN,BOOL);
+BOOL WINAPI GetUserObjectInformationA(HANDLE,int,PVOID,DWORD,PDWORD);
+BOOL WINAPI GetUserObjectInformationW(HANDLE,int,PVOID,DWORD,PDWORD);
+BOOL WINAPI GetUserObjectSecurity(HANDLE,PSECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,PDWORD);
+HWND WINAPI GetWindow(HWND,UINT);
+DWORD WINAPI GetWindowContextHelpId(HWND);
+HDC WINAPI GetWindowDC(HWND);
+BOOL WINAPI GetWindowExtEx(HDC,LPSIZE);
+BOOL WINAPI GetWindowPlacement(HWND,WINDOWPLACEMENT*);
+BOOL WINAPI GetWindowRect(HWND,LPRECT);
+int WINAPI GetWindowRgn(HWND,HRGN);
+#define GetWindowTask(hWnd) ((HANDLE)GetWindowThreadProcessId(hWnd, NULL))
+int WINAPI GetWindowTextA(HWND,LPSTR,int);
+int WINAPI GetWindowTextLengthA(HWND);
+int WINAPI GetWindowTextLengthW(HWND);
+int WINAPI GetWindowTextW(HWND,LPWSTR,int);
+WORD WINAPI GetWindowWord(HWND,int);
+BOOL WINAPI GetAltTabInfoA(HWND,int,PALTTABINFO,LPSTR,UINT);
+BOOL WINAPI GetAltTabInfoW(HWND,int,PALTTABINFO,LPWSTR,UINT);
+BOOL WINAPI GetComboBoxInfo(HWND,PCOMBOBOXINFO);
+BOOL WINAPI GetCursorInfo(PCURSORINFO);
+BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO);
+DWORD WINAPI GetListBoxInfo(HWND);
+BOOL WINAPI GetMenuBarInfo(HWND,LONG,LONG,PMENUBARINFO);
+BOOL WINAPI GetMenuInfo(HMENU,LPMENUINFO);
+BOOL WINAPI GetScrollBarInfo(HWND,LONG,PSCROLLBARINFO);
+BOOL WINAPI GetTitleBarInfo(HWND,PTITLEBARINFO);
+BOOL WINAPI GetWindowInfo(HWND,PWINDOWINFO);
+BOOL WINAPI GetMonitorInfoA(HMONITOR,LPMONITORINFO);
+BOOL WINAPI GetMonitorInfoW(HMONITOR,LPMONITORINFO);
+UINT WINAPI GetWindowModuleFileNameA(HWND,LPSTR,UINT);
+UINT WINAPI GetWindowModuleFileNameW(HWND,LPWSTR,UINT);
+BOOL WINAPI GrayStringA(HDC,HBRUSH,GRAYSTRINGPROC,LPARAM,int,int,int,int,int);
+BOOL WINAPI GrayStringW(HDC,HBRUSH,GRAYSTRINGPROC,LPARAM,int,int,int,int,int);
+BOOL WINAPI HideCaret(HWND);
+BOOL WINAPI HiliteMenuItem(HWND,HMENU,UINT,UINT);
+BOOL WINAPI InflateRect(LPRECT,int,int);
+BOOL WINAPI InSendMessage(VOID);
+BOOL WINAPI InsertMenuA(HMENU,UINT,UINT,UINT,LPCSTR);
+BOOL WINAPI InsertMenuW(HMENU,UINT,UINT,UINT,LPCWSTR);
+BOOL WINAPI InsertMenuItemA(HMENU,UINT,BOOL,LPCMENUITEMINFOA);
+BOOL WINAPI InsertMenuItemW(HMENU,UINT,BOOL,LPCMENUITEMINFOW);
+BOOL WINAPI IntersectRect(LPRECT,LPCRECT,LPCRECT);
+BOOL WINAPI InvalidateRect(HWND,LPCRECT,BOOL);
+BOOL WINAPI InvalidateRgn(HWND,HRGN,BOOL);
+BOOL WINAPI InvertRect(HDC,LPCRECT);
+BOOL WINAPI IsCharAlphaA(CHAR ch);
+BOOL WINAPI IsCharAlphaNumericA(CHAR);
+BOOL WINAPI IsCharAlphaNumericW(WCHAR);
+BOOL WINAPI IsCharAlphaW(WCHAR);
+BOOL WINAPI IsCharLowerA(CHAR);
+BOOL WINAPI IsCharLowerW(WCHAR);
+BOOL WINAPI IsCharUpperA(CHAR);
+BOOL WINAPI IsCharUpperW(WCHAR);
+BOOL WINAPI IsChild(HWND,HWND);
+BOOL WINAPI IsClipboardFormatAvailable(UINT);
+BOOL WINAPI IsDialogMessageA(HWND,LPMSG);
+BOOL WINAPI IsDialogMessageW(HWND,LPMSG);
+UINT WINAPI IsDlgButtonChecked(HWND,int);
+BOOL WINAPI IsIconic(HWND);
+BOOL WINAPI IsMenu(HMENU);
+BOOL WINAPI IsRectEmpty(LPCRECT);
+BOOL WINAPI IsWindow(HWND);
+BOOL WINAPI IsWindowEnabled(HWND);
+BOOL WINAPI IsWindowUnicode(HWND);
+BOOL WINAPI IsWindowVisible(HWND);
+BOOL WINAPI IsZoomed(HWND);
+VOID WINAPI keybd_event(BYTE,BYTE,DWORD,DWORD);
+BOOL WINAPI KillTimer(HWND,UINT);
+HACCEL WINAPI LoadAcceleratorsA(HINSTANCE,LPCSTR);
+HACCEL WINAPI LoadAcceleratorsW(HINSTANCE,LPCWSTR);
+HBITMAP WINAPI LoadBitmapA(HINSTANCE,LPCSTR);
+HBITMAP WINAPI LoadBitmapW(HINSTANCE,LPCWSTR);
+HCURSOR WINAPI LoadCursorA(HINSTANCE,LPCSTR);
+HCURSOR WINAPI LoadCursorFromFileA(LPCSTR);
+HCURSOR WINAPI LoadCursorFromFileW(LPCWSTR);
+HCURSOR WINAPI LoadCursorW(HINSTANCE,LPCWSTR);
+HICON WINAPI LoadIconA(HINSTANCE,LPCSTR);
+HICON WINAPI LoadIconW(HINSTANCE,LPCWSTR);
+HANDLE WINAPI LoadImageA(HINSTANCE,LPCSTR,UINT,int,int,UINT);
+HANDLE WINAPI LoadImageW(HINSTANCE,LPCWSTR,UINT,int,int,UINT);
+HKL WINAPI LoadKeyboardLayoutA(LPCSTR,UINT);
+HKL WINAPI LoadKeyboardLayoutW(LPCWSTR,UINT);
+HMENU WINAPI LoadMenuA(HINSTANCE,LPCSTR);
+HMENU WINAPI LoadMenuIndirectA(const MENUTEMPLATE*);
+HMENU WINAPI LoadMenuIndirectW(const MENUTEMPLATE*);
+HMENU WINAPI LoadMenuW(HINSTANCE,LPCWSTR);
+int WINAPI LoadStringA(HINSTANCE,UINT,LPSTR,int);
+int WINAPI LoadStringW(HINSTANCE,UINT,LPWSTR,int);
+BOOL WINAPI LockWindowUpdate(HWND);
+int WINAPI LookupIconIdFromDirectory(PBYTE,BOOL);
+int WINAPI LookupIconIdFromDirectoryEx(PBYTE,BOOL,int,int,UINT);
+BOOL WINAPI MapDialogRect(HWND,LPRECT);
+UINT WINAPI MapVirtualKeyA(UINT,UINT);
+UINT WINAPI MapVirtualKeyExA(UINT,UINT,HKL);
+UINT WINAPI MapVirtualKeyExW(UINT,UINT,HKL);
+UINT WINAPI MapVirtualKeyW(UINT,UINT);
+int WINAPI MapWindowPoints(HWND,HWND,LPPOINT,UINT);
+int WINAPI MenuItemFromPoint(HWND,HMENU,POINT);
+BOOL WINAPI MessageBeep(UINT);
+int WINAPI MessageBoxA(HWND,LPCSTR,LPCSTR,UINT);
+int WINAPI MessageBoxW(HWND,LPCWSTR,LPCWSTR,UINT);
+int WINAPI MessageBoxExA(HWND,LPCSTR,LPCSTR,UINT,WORD);
+int WINAPI MessageBoxExW(HWND,LPCWSTR,LPCWSTR,UINT,WORD);
+int WINAPI MessageBoxIndirectA(LPMSGBOXPARAMSA);
+int WINAPI MessageBoxIndirectW(LPMSGBOXPARAMSW);
+BOOL WINAPI ModifyMenuA(HMENU,UINT,UINT,UINT,LPCSTR);
+BOOL WINAPI ModifyMenuW(HMENU,UINT,UINT,UINT,LPCWSTR);
+void WINAPI mouse_event(DWORD,DWORD,DWORD,DWORD,DWORD);
+BOOL WINAPI MoveWindow(HWND,int,int,int,int,BOOL);
+DWORD WINAPI MsgWaitForMultipleObjects(DWORD,LPHANDLE,BOOL,DWORD,DWORD);
+DWORD WINAPI MsgWaitForMultipleObjectsEx(DWORD,LPHANDLE,DWORD,DWORD,DWORD);
+DWORD WINAPI OemKeyScan(WORD);
+BOOL WINAPI OemToCharA(LPCSTR,LPSTR);
+BOOL WINAPI OemToCharBuffA(LPCSTR,LPSTR,DWORD);
+BOOL WINAPI OemToCharBuffW(LPCSTR,LPWSTR,DWORD);
+BOOL WINAPI OemToCharW(LPCSTR,LPWSTR);
+BOOL WINAPI OffsetRect(LPRECT,int,int);
+BOOL WINAPI OpenClipboard(HWND);
+HDESK WINAPI OpenDesktopA(LPSTR,DWORD,BOOL,DWORD);
+HDESK WINAPI OpenDesktopW(LPWSTR,DWORD,BOOL,DWORD);
+BOOL WINAPI OpenIcon(HWND);
+HDESK WINAPI OpenInputDesktop(DWORD,BOOL,DWORD);
+HWINSTA WINAPI OpenWindowStationA(LPSTR,BOOL,DWORD);
+HWINSTA WINAPI OpenWindowStationW(LPWSTR,BOOL,DWORD);
+BOOL WINAPI PaintDesktop(HDC);
+BOOL WINAPI PeekMessageA(LPMSG,HWND,UINT,UINT,UINT);
+BOOL WINAPI PeekMessageW(LPMSG,HWND,UINT,UINT,UINT);
+#define PostAppMessageA(t,m,w,l) PostThreadMessageA((DWORD)t,m,w,l)
+#define PostAppMessageW(t,m,w,l) PostThreadMessageW((DWORD)t,m,w,l)
+BOOL WINAPI PostMessageA(HWND,UINT,WPARAM,LPARAM);
+BOOL WINAPI PostMessageW(HWND,UINT,WPARAM,LPARAM);
+void WINAPI PostQuitMessage(int);
+BOOL WINAPI PostThreadMessageA(DWORD,UINT,WPARAM,LPARAM);
+BOOL WINAPI PostThreadMessageW(DWORD,UINT,WPARAM,LPARAM);
+BOOL WINAPI PtInRect(LPCRECT,POINT);
+BOOL WINAPI RedrawWindow(HWND,LPCRECT,HRGN,UINT);
+ATOM WINAPI RegisterClassA(const WNDCLASSA*);
+ATOM WINAPI RegisterClassW(const WNDCLASSW*);
+ATOM WINAPI RegisterClassExA(const WNDCLASSEXA*);
+ATOM WINAPI RegisterClassExW(const WNDCLASSEXW*);
+UINT WINAPI RegisterClipboardFormatA(LPCSTR);
+UINT WINAPI RegisterClipboardFormatW(LPCWSTR);
+BOOL WINAPI RegisterHotKey(HWND,int,UINT,UINT);
+UINT WINAPI RegisterWindowMessageA(LPCSTR);
+UINT WINAPI RegisterWindowMessageW(LPCWSTR);
+BOOL WINAPI ReleaseCapture(void);
+int WINAPI ReleaseDC(HWND,HDC);
+BOOL WINAPI RemoveMenu(HMENU,UINT,UINT);
+HANDLE WINAPI RemovePropA(HWND,LPCSTR);
+HANDLE WINAPI RemovePropW(HWND,LPCWSTR);
+BOOL WINAPI ReplyMessage(LRESULT);
+BOOL WINAPI ScreenToClient(HWND,LPPOINT);
+BOOL WINAPI ScrollDC(HDC,int,int,LPCRECT,LPCRECT,HRGN,LPRECT);
+BOOL WINAPI ScrollWindow(HWND,int,int,LPCRECT,LPCRECT);
+int WINAPI ScrollWindowEx(HWND,int,int,LPCRECT,LPCRECT,HRGN,LPRECT,UINT);
+LONG WINAPI SendDlgItemMessageA(HWND,int,UINT,WPARAM,LPARAM);
+LONG WINAPI SendDlgItemMessageW(HWND,int,UINT,WPARAM,LPARAM);
+LRESULT WINAPI SendMessageA(HWND,UINT,WPARAM,LPARAM);
+BOOL WINAPI SendMessageCallbackA(HWND,UINT,WPARAM,LPARAM,SENDASYNCPROC,DWORD);
+BOOL WINAPI SendMessageCallbackW(HWND,UINT,WPARAM,LPARAM,SENDASYNCPROC,DWORD);
+LRESULT WINAPI SendMessageTimeoutA(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD);
+LRESULT WINAPI SendMessageTimeoutW(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD);
+LRESULT WINAPI SendMessageW(HWND,UINT,WPARAM,LPARAM);
+BOOL WINAPI SendNotifyMessageA(HWND,UINT,WPARAM,LPARAM);
+BOOL WINAPI SendNotifyMessageW(HWND,UINT,WPARAM,LPARAM);
+HWND WINAPI SetActiveWindow(HWND);
+HWND WINAPI SetCapture(HWND hWnd);
+BOOL WINAPI SetCaretBlinkTime(UINT);
+BOOL WINAPI SetCaretPos(int,int);
+DWORD WINAPI SetClassLongA(HWND,int,LONG);
+DWORD WINAPI SetClassLongW(HWND,int,LONG);
+WORD WINAPI SetClassWord(HWND,int,WORD);
+HANDLE WINAPI SetClipboardData(UINT,HANDLE);
+HWND WINAPI SetClipboardViewer(HWND);
+HCURSOR WINAPI SetCursor(HCURSOR);
+BOOL WINAPI SetCursorPos(int,int);
+VOID WINAPI SetDebugErrorLevel(DWORD);
+BOOL WINAPI SetDlgItemInt(HWND,int,UINT,BOOL);
+BOOL WINAPI SetDlgItemTextA(HWND,int,LPCSTR);
+BOOL WINAPI SetDlgItemTextW(HWND,int,LPCWSTR);
+BOOL WINAPI SetDoubleClickTime(UINT);
+HWND WINAPI SetFocus(HWND);
+BOOL WINAPI SetForegroundWindow(HWND);
+BOOL WINAPI SetKeyboardState(PBYTE);
+BOOL WINAPI SetMenu(HWND,HMENU);
+BOOL WINAPI SetMenuContextHelpId(HMENU,DWORD);
+BOOL WINAPI SetMenuDefaultItem(HMENU,UINT,UINT);
+BOOL WINAPI SetMenuInfo(HMENU,LPCMENUINFO);
+BOOL WINAPI SetMenuItemBitmaps(HMENU,UINT,UINT,HBITMAP,HBITMAP);
+BOOL WINAPI SetMenuItemInfoA(HMENU,UINT,BOOL,LPCMENUITEMINFOA);
+BOOL WINAPI SetMenuItemInfoW( HMENU,UINT,BOOL,LPCMENUITEMINFOW);
+LPARAM WINAPI SetMessageExtraInfo(LPARAM);
+BOOL WINAPI SetMessageQueue(int);
+HWND WINAPI SetParent(HWND,HWND);
+BOOL WINAPI SetProcessWindowStation(HWINSTA);
+BOOL WINAPI SetPropA(HWND,LPCSTR,HANDLE);
+BOOL WINAPI SetPropW(HWND,LPCWSTR,HANDLE);
+BOOL WINAPI SetRect(LPRECT,int,int,int,int);
+BOOL WINAPI SetRectEmpty(LPRECT);
+int WINAPI SetScrollInfo(HWND,int,LPCSCROLLINFO,BOOL);
+int WINAPI SetScrollPos(HWND,int,int,BOOL);
+BOOL WINAPI SetScrollRange(HWND,int,int,int,BOOL);
+BOOL WINAPI SetSysColors(int,const INT *,const COLORREF *);
+#define SetSysModalWindow(h) (NULL)
+BOOL WINAPI SetSystemCursor(HCURSOR,DWORD);
+BOOL WINAPI SetThreadDesktop(HDESK);
+UINT WINAPI SetTimer(HWND,UINT,UINT,TIMERPROC);
+BOOL WINAPI SetUserObjectInformationA(HANDLE,int,PVOID,DWORD);
+BOOL WINAPI SetUserObjectInformationW(HANDLE,int,PVOID,DWORD);
+BOOL WINAPI SetUserObjectSecurity(HANDLE,PSECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+BOOL WINAPI SetWindowContextHelpId(HWND,DWORD);
+LONG WINAPI SetWindowLongA(HWND,int,LONG);
+LONG WINAPI SetWindowLongW(HWND,int,LONG);
+#ifdef _WIN64
+LONG_PTR WINAPI SetWindowLongPtrA(HWND,int,LONG_PTR);
+LONG_PTR WINAPI SetWindowLongPtrW(HWND,int,LONG_PTR);
+#else 
+#define SetWindowLongPtrA SetWindowLongA
+#define SetWindowLongPtrW SetWindowLongW
+#endif
+BOOL WINAPI SetWindowPlacement(HWND hWnd,const WINDOWPLACEMENT*);
+BOOL WINAPI SetWindowPos(HWND,HWND,int,int,int,int,UINT);
+int WINAPI SetWindowRgn(HWND,HRGN,BOOL);
+HOOKPROC WINAPI SetWindowsHookA(int,HOOKPROC);
+HHOOK WINAPI SetWindowsHookExA(int,HOOKPROC,HINSTANCE,DWORD);
+HHOOK WINAPI SetWindowsHookExW(int,HOOKPROC,HINSTANCE,DWORD);
+BOOL WINAPI SetWindowTextA(HWND,LPCSTR);
+BOOL WINAPI SetWindowTextW(HWND,LPCWSTR);
+WORD WINAPI SetWindowWord(HWND,int,WORD);
+BOOL WINAPI ShowCaret(HWND);
+int WINAPI ShowCursor(BOOL);
+BOOL WINAPI ShowOwnedPopups(HWND,BOOL);
+BOOL WINAPI ShowScrollBar(HWND,int,BOOL);
+BOOL WINAPI ShowWindow(HWND,int);
+BOOL WINAPI ShowWindowAsync(HWND,int);
+BOOL WINAPI SubtractRect(LPRECT,LPCRECT,LPCRECT);
+BOOL WINAPI SwapMouseButton(BOOL);
+BOOL WINAPI SwitchDesktop(HDESK);
+BOOL WINAPI SystemParametersInfoA(UINT,UINT,PVOID,UINT);
+BOOL WINAPI SystemParametersInfoW(UINT,UINT,PVOID,UINT);
+LONG WINAPI TabbedTextOutA(HDC,int,int,LPCSTR,int,int,LPINT,int);
+LONG WINAPI TabbedTextOutW(HDC,int,int,LPCWSTR,int,int,LPINT,int);
+WORD WINAPI TileWindows(HWND,UINT,LPCRECT,UINT,const HWND *);
+int WINAPI ToAscii(UINT,UINT,PBYTE,LPWORD,UINT);
+int WINAPI ToAsciiEx(UINT,UINT,PBYTE,LPWORD,UINT,HKL);
+int WINAPI ToUnicode(UINT,UINT,PBYTE,LPWSTR,int,UINT);
+int WINAPI ToUnicodeEx(UINT,UINT,PBYTE,LPWSTR,int,UINT,HKL);
+BOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT);
+BOOL WINAPI TrackPopupMenu(HMENU,UINT,int,int,int,HWND,LPCRECT);
+BOOL WINAPI TrackPopupMenuEx(HMENU,UINT,int,int,HWND,LPTPMPARAMS);
+int WINAPI TranslateAcceleratorA(HWND,HACCEL,LPMSG);
+int WINAPI TranslateAcceleratorW(HWND,HACCEL,LPMSG);
+BOOL WINAPI TranslateMDISysAccel(HWND,LPMSG);
+BOOL WINAPI TranslateMessage(const MSG*);
+BOOL WINAPI UnhookWindowsHook(int,HOOKPROC);
+BOOL WINAPI UnhookWindowsHookEx(HHOOK);
+BOOL WINAPI UnionRect(LPRECT,LPCRECT,LPCRECT);
+BOOL WINAPI UnloadKeyboardLayout(HKL);
+BOOL WINAPI UnregisterClassA(LPCSTR,HINSTANCE);
+BOOL WINAPI UnregisterClassW(LPCWSTR,HINSTANCE);
+BOOL WINAPI UnregisterHotKey(HWND,int);
+BOOL WINAPI UpdateWindow(HWND);
+BOOL WINAPI ValidateRect(HWND,LPCRECT);
+BOOL WINAPI ValidateRgn(HWND,HRGN);
+SHORT WINAPI VkKeyScanA(CHAR);
+SHORT WINAPI VkKeyScanExA(CHAR,HKL);
+SHORT WINAPI VkKeyScanExW(WCHAR,HKL);
+SHORT WINAPI VkKeyScanW(WCHAR);
+DWORD WINAPI WaitForInputIdle(HANDLE,DWORD);
+BOOL WINAPI WaitMessage(void);
+HWND WINAPI WindowFromDC(HDC hDC);
+HWND WINAPI WindowFromPoint(POINT);
+UINT WINAPI WinExec(LPCSTR,UINT);
+BOOL WINAPI WinHelpA(HWND,LPCSTR,UINT,DWORD);
+BOOL WINAPI WinHelpW(HWND,LPCWSTR,UINT,DWORD);
+int WINAPIV wsprintfA(LPSTR,LPCSTR,...);
+int WINAPIV wsprintfW(LPWSTR,LPCWSTR,...);
+int WINAPI wvsprintfA(LPSTR,LPCSTR,va_list arglist);
+int WINAPI wvsprintfW(LPWSTR,LPCWSTR,va_list arglist);
+
+#ifdef UNICODE
+#define EDITWORDBREAKPROC EDITWORDBREAKPROCW
+#define PROPENUMPROC PROPENUMPROCW
+#define PROPENUMPROCEX PROPENUMPROCEXW
+#define DEKSTOPENUMPROC DEKSTOPENUMPROCW
+#define WINSTAENUMPROC WINSTAENUMPROCW
+#define PROPENUMPROC PROPENUMPROCW
+#define PROPENUMPROCEX PROPENUMPROCEXW
+#define MAKEINTRESOURCE MAKEINTRESOURCEW
+typedef WNDCLASSW WNDCLASS,*LPWNDCLASS,*PWNDCLASS;
+typedef WNDCLASSEXW WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX;
+typedef MENUITEMINFOW MENUITEMINFO,*LPMENUITEMINFO;
+typedef LPCMENUITEMINFOW LPCMENUITEMINFO;
+typedef MSGBOXPARAMSW MSGBOXPARAMS,*PMSGBOXPARAMS,*LPMSGBOXPARAMS;
+typedef HIGHCONTRASTW HIGHCONTRAST,*LPHIGHCONTRAST;
+typedef ICONMETRICSW ICONMETRICS,*LPICONMETRICS;
+typedef NONCLIENTMETRICSW NONCLIENTMETRICS,*LPNONCLIENTMETRICS;
+typedef SERIALKEYSW SERIALKEYS,*LPSERIALKEYS;
+typedef SOUNDSENTRYW SOUNDSENTRY,*LPSOUNDSENTRY;
+typedef CREATESTRUCTW CREATESTRUCT, *LPCREATESTRUCT;
+typedef CBT_CREATEWNDW CBT_CREATEWND, *LPCBT_CREATEWND;
+typedef MDICREATESTRUCTW MDICREATESTRUCT,*LPMDICREATESTRUCT;
+typedef MULTIKEYHELPW MULTIKEYHELP,*PMULTIKEYHELP,*LPMULTIKEYHELP;
+#define AppendMenu AppendMenuW
+#define CallWindowProc CallWindowProcW
+#define ChangeDisplaySettings ChangeDisplaySettingsW
+#define ChangeMenu ChangeMenuW
+#define CharLower CharLowerW
+#define CharLowerBuff CharLowerBuffW
+#define CharNext CharNextW
+#define CharNextEx CharNextExW
+#define CharPrev CharPrevW
+#define CharPrevEx CharPrevExW
+#define CharToOem CharToOemW
+#define CharToOemBuff CharToOemBuffW
+#define CharUpper CharUpperW
+#define CharUpperBuff CharUpperBuffW
+#define CopyAcceleratorTable CopyAcceleratorTableW
+#define CreateAcceleratorTable CreateAcceleratorTableW
+#define CreateDesktop CreateDesktopW
+#define CreateDialog CreateDialogW
+#define CreateDialogIndirect CreateDialogIndirectW
+#define CreateDialogIndirectParam CreateDialogIndirectParamW
+#define CreateDialogParam CreateDialogParamW
+#define CreateMDIWindow CreateMDIWindowW
+#define CreateWindow CreateWindowW
+#define CreateWindowEx CreateWindowExW
+#define CreateWindowStation CreateWindowStationW
+#define DefDlgProc DefDlgProcW
+#define DefFrameProc DefFrameProcW
+#define DefMDIChildProc DefMDIChildProcW
+#define DefWindowProc DefWindowProcW
+#define DialogBox DialogBoxW
+#define DialogBoxIndirect DialogBoxIndirectW
+#define DialogBoxIndirectParam DialogBoxIndirectParamW
+#define DialogBoxParam DialogBoxParamW
+#define DispatchMessage DispatchMessageW
+#define DlgDirList DlgDirListW
+#define DlgDirListComboBox DlgDirListComboBoxW
+#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExW
+#define DlgDirSelectEx DlgDirSelectExW
+#define DrawState DrawStateW
+#define DrawText DrawTextW
+#define DrawTextEx DrawTextExW
+#define EnumDesktops EnumDesktopsW
+#define EnumDisplaySettings EnumDisplaySettingsW
+#define EnumProps EnumPropsW
+#define EnumPropsEx EnumPropsExW
+#define EnumWindowStations EnumWindowStationsW
+#define FindWindow FindWindowW
+#define FindWindowEx FindWindowExW
+#define GetClassInfo GetClassInfoW
+#define GetClassInfoEx GetClassInfoExW
+#define GetClassLong GetClassLongW
+#define GetClassName GetClassNameW
+#define GetClipboardFormatName GetClipboardFormatNameW
+#define GetDlgItemText GetDlgItemTextW
+#define GetKeyboardLayoutName GetKeyboardLayoutNameW
+#define GetKeyNameText GetKeyNameTextW
+#define GetMenuItemInfo GetMenuItemInfoW
+#define GetMenuString GetMenuStringW
+#define GetMessage GetMessageW
+#define GetMonitorInfo  GetMonitorInfoW
+#define GetProp GetPropW
+#define GetTabbedTextExtent GetTabbedTextExtentW
+#define GetUserObjectInformation GetUserObjectInformationW
+#define GetWindowLong GetWindowLongW
+#define GetWindowLongPtr GetWindowLongPtrW
+#define GetWindowText GetWindowTextW
+#define GetWindowTextLength GetWindowTextLengthW
+#define GetAltTabInfo GetAltTabInfoW
+#define GetWindowModuleFileName GetWindowModuleFileNameW
+#define GrayString GrayStringW
+#define InsertMenu InsertMenuW
+#define InsertMenuItem InsertMenuItemW
+#define IsCharAlpha IsCharAlphaW
+#define IsCharAlphaNumeric IsCharAlphaNumericW
+#define IsCharLower IsCharLowerW
+#define IsCharUpper IsCharUpperW
+#define IsDialogMessage IsDialogMessageW
+#define LoadAccelerators LoadAcceleratorsW
+#define LoadBitmap LoadBitmapW
+#define LoadCursor LoadCursorW
+#define LoadCursorFromFile LoadCursorFromFileW
+#define LoadIcon LoadIconW
+#define LoadImage LoadImageW
+#define LoadKeyboardLayout LoadKeyboardLayoutW
+#define LoadMenu LoadMenuW
+#define LoadMenuIndirect LoadMenuIndirectW
+#define LoadString LoadStringW
+#define MapVirtualKey MapVirtualKeyW
+#define MapVirtualKeyEx MapVirtualKeyExW
+#define MessageBox MessageBoxW
+#define MessageBoxEx MessageBoxExW
+#define MessageBoxIndirect MessageBoxIndirectW
+#define ModifyMenu ModifyMenuW
+#define OemToChar OemToCharW
+#define OemToCharBuff OemToCharBuffW
+#define OpenDesktop OpenDesktopW
+#define OpenWindowStation OpenWindowStationW
+#define PeekMessage PeekMessageW
+#define PostAppMessage PostAppMessageW
+#define PostMessage PostMessageW
+#define PostThreadMessage PostThreadMessageW
+#define RegisterClass RegisterClassW
+#define RegisterClassEx RegisterClassExW
+#define RegisterClipboardFormat RegisterClipboardFormatW
+#define RegisterWindowMessage RegisterWindowMessageW
+#define RemoveProp RemovePropW
+#define SendDlgItemMessage SendDlgItemMessageW
+#define SendMessage SendMessageW
+#define SendMessageCallback SendMessageCallbackW
+#define SendMessageTimeout SendMessageTimeoutW
+#define SendNotifyMessage SendNotifyMessageW
+#define SetClassLong SetClassLongW
+#define SetDlgItemText SetDlgItemTextW
+#define SetMenuItemInfo SetMenuItemInfoW
+#define SetProp SetPropW
+#define SetUserObjectInformation SetUserObjectInformationW
+#define SetWindowLong SetWindowLongW
+#define SetWindowLongPtr SetWindowLongPtrW
+#define SetWindowsHook SetWindowsHookW
+#define SetWindowsHookEx SetWindowsHookExW
+#define SetWindowText SetWindowTextW
+#define SystemParametersInfo SystemParametersInfoW
+#define TabbedTextOut TabbedTextOutW
+#define TranslateAccelerator TranslateAcceleratorW
+#define UnregisterClass UnregisterClassW
+#define VkKeyScan VkKeyScanW
+#define VkKeyScanEx VkKeyScanExW
+#define WinHelp WinHelpW
+#define wsprintf wsprintfW
+#define wvsprintf wvsprintfW
+#else
+#define EDITWORDBREAKPROC EDITWORDBREAKPROCA
+#define PROPENUMPROC PROPENUMPROCA
+#define PROPENUMPROCEX PROPENUMPROCEXA
+#define DEKSTOPENUMPROC DEKSTOPENUMPROCA
+#define WINSTAENUMPROC WINSTAENUMPROCA
+#define PROPENUMPROC PROPENUMPROCA
+#define PROPENUMPROCEX PROPENUMPROCEXA
+#define MAKEINTRESOURCE MAKEINTRESOURCEA
+typedef WNDCLASSA WNDCLASS,*LPWNDCLASS,*PWNDCLASS;
+typedef WNDCLASSEXA WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX;
+typedef MENUITEMINFOA MENUITEMINFO,*LPMENUITEMINFO;
+typedef LPCMENUITEMINFOA LPCMENUITEMINFO;
+typedef MSGBOXPARAMSA MSGBOXPARAMS,*PMSGBOXPARAMS,*LPMSGBOXPARAMS;
+typedef HIGHCONTRASTA HIGHCONTRAST,*LPHIGHCONTRAST;
+typedef ICONMETRICSA ICONMETRICS,*LPICONMETRICS;
+typedef NONCLIENTMETRICSA NONCLIENTMETRICS,*LPNONCLIENTMETRICS;
+typedef SERIALKEYSA SERIALKEYS,*LPSERIALKEYS;
+typedef SOUNDSENTRYA SOUNDSENTRY,*LPSOUNDSENTRY;
+typedef CREATESTRUCTA CREATESTRUCT, *LPCREATESTRUCT;
+typedef CBT_CREATEWNDA CBT_CREATEWND, *LPCBT_CREATEWND;
+typedef MDICREATESTRUCTA MDICREATESTRUCT,*LPMDICREATESTRUCT;
+typedef MULTIKEYHELPA MULTIKEYHELP,*PMULTIKEYHELP,*LPMULTIKEYHELP;
+#define AppendMenu AppendMenuA
+#define CallWindowProc CallWindowProcA
+#define ChangeDisplaySettings ChangeDisplaySettingsA
+#define ChangeMenu ChangeMenuA
+#define CharLower CharLowerA
+#define CharLowerBuff CharLowerBuffA
+#define CharNext CharNextA
+#define CharNextEx CharNextExA
+#define CharPrev CharPrevA
+#define CharPrevEx CharPrevExA
+#define CharToOem CharToOemA
+#define CharToOemBuff CharToOemBuffA
+#define CharUpper CharUpperA
+#define CharUpperBuff CharUpperBuffA
+#define CopyAcceleratorTable CopyAcceleratorTableA
+#define CreateAcceleratorTable CreateAcceleratorTableA
+#define CreateDesktop CreateDesktopA
+#define CreateDialog CreateDialogA
+#define CreateDialogIndirect CreateDialogIndirectA
+#define CreateDialogIndirectParam CreateDialogIndirectParamA
+#define CreateDialogParam CreateDialogParamA
+#define CreateMDIWindow CreateMDIWindowA
+#define CreateWindow CreateWindowA
+#define CreateWindowEx CreateWindowExA
+#define CreateWindowStation CreateWindowStationA
+#define DefDlgProc DefDlgProcA
+#define DefFrameProc DefFrameProcA
+#define DefMDIChildProc DefMDIChildProcA
+#define DefWindowProc DefWindowProcA
+#define DialogBox DialogBoxA
+#define DialogBoxIndirect DialogBoxIndirectA
+#define DialogBoxIndirectParam DialogBoxIndirectParamA
+#define DialogBoxParam DialogBoxParamA
+#define DispatchMessage DispatchMessageA
+#define DlgDirList DlgDirListA
+#define DlgDirListComboBox DlgDirListComboBoxA
+#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExA
+#define DlgDirSelectEx DlgDirSelectExA
+#define DrawState DrawStateA
+#define DrawText DrawTextA
+#define DrawTextEx DrawTextExA
+#define EnumDesktops EnumDesktopsA
+#define EnumDisplaySettings EnumDisplaySettingsA
+#define EnumProps EnumPropsA
+#define EnumPropsEx EnumPropsExA
+#define EnumWindowStations EnumWindowStationsA
+#define FindWindow FindWindowA
+#define FindWindowEx FindWindowExA
+#define GetClassInfo GetClassInfoA
+#define GetClassInfoEx GetClassInfoExA
+#define GetClassLong GetClassLongA
+#define GetClassName GetClassNameA
+#define GetClipboardFormatName GetClipboardFormatNameA
+#define GetDlgItemText GetDlgItemTextA
+#define GetKeyboardLayoutName GetKeyboardLayoutNameA
+#define GetKeyNameText GetKeyNameTextA
+#define GetMenuItemInfo GetMenuItemInfoA
+#define GetMenuString GetMenuStringA
+#define GetMessage GetMessageA
+#define GetMonitorInfo  GetMonitorInfoA
+#define GetProp GetPropA
+#define GetTabbedTextExtent GetTabbedTextExtentA
+#define GetUserObjectInformation GetUserObjectInformationA
+#define GetWindowLong GetWindowLongA
+#define GetWindowLongPtr GetWindowLongPtrA
+#define GetWindowText GetWindowTextA
+#define GetWindowTextLength GetWindowTextLengthA
+#define GetAltTabInfo GetAltTabInfoA
+#define GetWindowModuleFileName GetWindowModuleFileNameA
+#define GrayString GrayStringA
+#define InsertMenu InsertMenuA
+#define InsertMenuItem InsertMenuItemA
+#define IsCharAlpha IsCharAlphaA
+#define IsCharAlphaNumeric IsCharAlphaNumericA
+#define IsCharLower IsCharLowerA
+#define IsCharUpper IsCharUpperA
+#define IsDialogMessage IsDialogMessageA
+#define LoadAccelerators LoadAcceleratorsA
+#define LoadBitmap LoadBitmapA
+#define LoadCursor LoadCursorA
+#define LoadIcon LoadIconA
+#define LoadCursorFromFile LoadCursorFromFileA
+#define LoadImage LoadImageA
+#define LoadKeyboardLayout LoadKeyboardLayoutA
+#define LoadMenu LoadMenuA
+#define LoadMenuIndirect LoadMenuIndirectA
+#define LoadString LoadStringA
+#define MapVirtualKey MapVirtualKeyA
+#define MapVirtualKeyEx MapVirtualKeyExA
+#define MessageBox MessageBoxA
+#define MessageBoxEx MessageBoxExA
+#define MessageBoxIndirect MessageBoxIndirectA
+#define ModifyMenu ModifyMenuA
+#define OemToChar OemToCharA
+#define OemToCharBuff OemToCharBuffA
+#define OpenDesktop OpenDesktopA
+#define OpenWindowStation OpenWindowStationA
+#define PeekMessage PeekMessageA
+#define PostAppMessage PostAppMessageA
+#define PostMessage PostMessageA
+#define PostThreadMessage PostThreadMessageA
+#define RegisterClass RegisterClassA
+#define RegisterClassEx RegisterClassExA
+#define RegisterClipboardFormat RegisterClipboardFormatA
+#define RegisterWindowMessage RegisterWindowMessageA
+#define RemoveProp RemovePropA
+#define SendDlgItemMessage SendDlgItemMessageA
+#define SendMessage SendMessageA
+#define SendMessageCallback SendMessageCallbackA
+#define SendMessageTimeout SendMessageTimeoutA
+#define SendNotifyMessage SendNotifyMessageA
+#define SetClassLong SetClassLongA
+#define SetDlgItemText SetDlgItemTextA
+#define SetMenuItemInfo SetMenuItemInfoA
+#define SetProp SetPropA
+#define SetUserObjectInformation SetUserObjectInformationA
+#define SetWindowLong SetWindowLongA
+#define SetWindowLongPtr SetWindowLongPtrA
+#define SetWindowsHook SetWindowsHookA
+#define SetWindowsHookEx SetWindowsHookExA
+#define SetWindowText SetWindowTextA
+#define SystemParametersInfo SystemParametersInfoA
+#define TabbedTextOut TabbedTextOutA
+#define TranslateAccelerator TranslateAcceleratorA
+#define UnregisterClass UnregisterClassA
+#define VkKeyScan VkKeyScanA
+#define VkKeyScanEx VkKeyScanExA
+#define WinHelp WinHelpA
+#define wsprintf wsprintfA
+#define wvsprintf wvsprintfA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _WINUSER_H */
diff --git a/tinyc/win32/include/winapi/winver.h b/tinyc/win32/include/winapi/winver.h
new file mode 100755
index 000000000..f20333ac8
--- /dev/null
+++ b/tinyc/win32/include/winapi/winver.h
@@ -0,0 +1,133 @@
+#ifndef _WINVER_H
+#define _WINVER_H
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define VS_FILE_INFO RT_VERSION
+#define VS_VERSION_INFO 1
+#define VS_USER_DEFINED 100
+#define VS_FFI_SIGNATURE 0xFEEF04BD
+#define VS_FFI_STRUCVERSION 0x10000
+#define VS_FFI_FILEFLAGSMASK 0x3F
+#define VS_FF_DEBUG 1
+#define VS_FF_PRERELEASE 2
+#define VS_FF_PATCHED 4
+#define VS_FF_PRIVATEBUILD 8
+#define VS_FF_INFOINFERRED 16
+#define VS_FF_SPECIALBUILD 32
+#define VOS_UNKNOWN 0
+#define VOS_DOS 0x10000
+#define VOS_OS216 0x20000
+#define VOS_OS232 0x30000
+#define VOS_NT 0x40000
+#define VOS__BASE 0
+#define VOS__WINDOWS16 1
+#define VOS__PM16 2
+#define VOS__PM32 3
+#define VOS__WINDOWS32 4
+#define VOS_DOS_WINDOWS16 0x10001
+#define VOS_DOS_WINDOWS32 0x10004
+#define VOS_OS216_PM16 0x20002
+#define VOS_OS232_PM32 0x30003
+#define VOS_NT_WINDOWS32 0x40004
+#define VFT_UNKNOWN 0
+#define VFT_APP 1
+#define VFT_DLL 2
+#define VFT_DRV 3
+#define VFT_FONT 4
+#define VFT_VXD 5
+#define VFT_STATIC_LIB 7
+#define VFT2_UNKNOWN 0
+#define VFT2_DRV_PRINTER 1
+#define VFT2_DRV_KEYBOARD 2
+#define VFT2_DRV_LANGUAGE 3
+#define VFT2_DRV_DISPLAY 4
+#define VFT2_DRV_MOUSE 5
+#define VFT2_DRV_NETWORK 6
+#define VFT2_DRV_SYSTEM 7
+#define VFT2_DRV_INSTALLABLE 8
+#define VFT2_DRV_SOUND 9
+#define VFT2_DRV_COMM 10
+#define VFT2_DRV_INPUTMETHOD 11
+#define VFT2_FONT_RASTER 1
+#define VFT2_FONT_VECTOR 2
+#define VFT2_FONT_TRUETYPE 3
+#define VFFF_ISSHAREDFILE 1
+#define VFF_CURNEDEST 1
+#define VFF_FILEINUSE 2
+#define VFF_BUFFTOOSMALL 4
+#define VIFF_FORCEINSTALL 1
+#define VIFF_DONTDELETEOLD 2
+#define VIF_TEMPFILE 1
+#define VIF_MISMATCH 2
+#define VIF_SRCOLD 4
+#define VIF_DIFFLANG 8
+#define VIF_DIFFCODEPG 16
+#define VIF_DIFFTYPE 32
+#define VIF_WRITEPROT 64
+#define VIF_FILEINUSE 128
+#define VIF_OUTOFSPACE 256
+#define VIF_ACCESSVIOLATION 512
+#define VIF_SHARINGVIOLATION 1024
+#define VIF_CANNOTCREATE 2048
+#define VIF_CANNOTDELETE 4096
+#define VIF_CANNOTRENAME 8192
+#define VIF_CANNOTDELETECUR 16384
+#define VIF_OUTOFMEMORY 32768
+#define VIF_CANNOTREADSRC  65536
+#define VIF_CANNOTREADDST 0x20000
+#define VIF_BUFFTOOSMALL 0x40000
+#ifndef RC_INVOKED
+typedef struct tagVS_FIXEDFILEINFO {
+	DWORD dwSignature;
+	DWORD dwStrucVersion;
+	DWORD dwFileVersionMS;
+	DWORD dwFileVersionLS;
+	DWORD dwProductVersionMS;
+	DWORD dwProductVersionLS;
+	DWORD dwFileFlagsMask;
+	DWORD dwFileFlags;
+	DWORD dwFileOS;
+	DWORD dwFileType;
+	DWORD dwFileSubtype;
+	DWORD dwFileDateMS;
+	DWORD dwFileDateLS;
+} VS_FIXEDFILEINFO;
+DWORD WINAPI VerFindFileA(DWORD,LPSTR,LPSTR,LPSTR,LPSTR,PUINT,LPSTR,PUINT);
+DWORD WINAPI VerFindFileW(DWORD,LPWSTR,LPWSTR,LPWSTR,LPWSTR,PUINT,LPWSTR,PUINT);
+DWORD WINAPI VerInstallFileA(DWORD,LPSTR,LPSTR,LPSTR,LPSTR,LPSTR,LPSTR,PUINT);
+DWORD WINAPI VerInstallFileW(DWORD,LPWSTR,LPWSTR,LPWSTR,LPWSTR,LPWSTR,LPWSTR,PUINT);
+DWORD WINAPI GetFileVersionInfoSizeA(LPSTR,PDWORD);
+DWORD WINAPI GetFileVersionInfoSizeW(LPWSTR,PDWORD);
+BOOL WINAPI GetFileVersionInfoA(LPSTR,DWORD,DWORD,PVOID);
+BOOL WINAPI GetFileVersionInfoW(LPWSTR,DWORD,DWORD,PVOID);
+DWORD WINAPI VerLanguageNameA(DWORD,LPSTR,DWORD);
+DWORD WINAPI VerLanguageNameW(DWORD,LPWSTR,DWORD);
+BOOL WINAPI VerQueryValueA(PCVOID,LPSTR,PVOID*,PUINT);
+BOOL WINAPI VerQueryValueW(PCVOID,LPWSTR,PVOID*,PUINT);
+#ifdef UNICODE
+#define VerFindFile VerFindFileW
+#define VerQueryValue VerQueryValueW
+#define VerInstallFile VerInstallFileW
+#define GetFileVersionInfoSize GetFileVersionInfoSizeW
+#define GetFileVersionInfo GetFileVersionInfoW
+#define VerLanguageName VerLanguageNameW
+#define VerQueryValue VerQueryValueW
+#else
+#define VerQueryValue VerQueryValueA
+#define VerFindFile VerFindFileA
+#define VerInstallFile VerInstallFileA
+#define GetFileVersionInfoSize GetFileVersionInfoSizeA
+#define GetFileVersionInfo GetFileVersionInfoA
+#define VerLanguageName VerLanguageNameA
+#define VerQueryValue VerQueryValueA
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/tinyc/win32/lib/chkstk.S b/tinyc/win32/lib/chkstk.S
new file mode 100755
index 000000000..837d8af2b
--- /dev/null
+++ b/tinyc/win32/lib/chkstk.S
@@ -0,0 +1,29 @@
+// =================================================
+// chkstk.s
+
+.text
+.globl __chkstk
+
+__chkstk:
+	xchg    (%esp), %ebp   // store ebp, get ret.addr
+	push    %ebp           // push ret.addr
+	lea     4(%esp), %ebp  // setup frame ptr
+	push    %ecx           // save ecx
+	mov     %ebp, %ecx
+P0:
+	sub     $4096,%ecx
+	test    %eax,(%ecx)
+	sub     $4096,%eax
+	cmp     $4096,%eax
+	jge     P0
+
+	sub     %eax,%ecx
+	mov     %esp,%eax
+	test    %eax,(%ecx)
+	mov     %ecx,%esp
+
+	mov     (%eax),%ecx     // restore ecx
+	mov     4(%eax),%eax
+	push    %eax
+	ret
+
diff --git a/tinyc/win32/lib/crt1.c b/tinyc/win32/lib/crt1.c
new file mode 100755
index 000000000..1cf12f294
--- /dev/null
+++ b/tinyc/win32/lib/crt1.c
@@ -0,0 +1,35 @@
+// =============================================
+// crt1.c
+
+#include <stdlib.h>
+
+#define __UNKNOWN_APP    0
+#define __CONSOLE_APP    1
+#define __GUI_APP        2
+void __set_app_type(int);
+void _controlfp(unsigned a, unsigned b);
+
+typedef struct
+{
+	int newmode;
+} _startupinfo;
+
+void __getmainargs(int *pargc, char ***pargv, char ***penv, int globb, _startupinfo*);
+
+int main(int argc, char **argv, char **env);
+
+int _start(void)
+{
+	int argc; char **argv; char **env; int ret;
+	_startupinfo start_info = {0};
+
+	_controlfp(0x10000, 0x30000);
+	__set_app_type(__CONSOLE_APP);
+	__getmainargs(&argc, &argv, &env, 0, &start_info);
+
+	ret = main(argc, argv, env);
+	exit(ret);
+}
+
+// =============================================
+
diff --git a/tinyc/win32/lib/dllcrt1.c b/tinyc/win32/lib/dllcrt1.c
new file mode 100755
index 000000000..9fc8339cf
--- /dev/null
+++ b/tinyc/win32/lib/dllcrt1.c
@@ -0,0 +1,13 @@
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
+
+BOOL WINAPI _dllstart(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+	BOOL bRet;
+	bRet = DllMain (hDll, dwReason, lpReserved);
+	return bRet;
+}
+
diff --git a/tinyc/win32/lib/dllmain.c b/tinyc/win32/lib/dllmain.c
new file mode 100755
index 000000000..e32df481c
--- /dev/null
+++ b/tinyc/win32/lib/dllmain.c
@@ -0,0 +1,9 @@
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+	return TRUE;
+}
+
diff --git a/tinyc/win32/lib/gdi32.def b/tinyc/win32/lib/gdi32.def
new file mode 100755
index 000000000..02766da43
--- /dev/null
+++ b/tinyc/win32/lib/gdi32.def
@@ -0,0 +1,337 @@
+LIBRARY gdi32.dll
+
+EXPORTS
+AbortDoc
+AbortPath
+AddFontResourceA
+AddFontResourceW
+AngleArc
+AnimatePalette
+Arc
+ArcTo
+BeginPath
+BitBlt
+ByeByeGDI
+CancelDC
+CheckColorsInGamut
+ChoosePixelFormat
+Chord
+CloseEnhMetaFile
+CloseFigure
+CloseMetaFile
+ColorCorrectPalette
+ColorMatchToTarget
+CombineRgn
+CombineTransform
+CopyEnhMetaFileA
+CopyEnhMetaFileW
+CopyMetaFileA
+CopyMetaFileW
+CreateBitmap
+CreateBitmapIndirect
+CreateBrushIndirect
+CreateColorSpaceA
+CreateColorSpaceW
+CreateCompatibleBitmap
+CreateCompatibleDC
+CreateDCA
+CreateDCW
+CreateDIBPatternBrush
+CreateDIBPatternBrushPt
+CreateDIBSection
+CreateDIBitmap
+CreateDiscardableBitmap
+CreateEllipticRgn
+CreateEllipticRgnIndirect
+CreateEnhMetaFileA
+CreateEnhMetaFileW
+CreateFontA
+CreateFontIndirectA
+CreateFontIndirectW
+CreateFontW
+CreateHalftonePalette
+CreateHatchBrush
+CreateICA
+CreateICW
+CreateMetaFileA
+CreateMetaFileW
+CreatePalette
+CreatePatternBrush
+CreatePen
+CreatePenIndirect
+CreatePolyPolygonRgn
+CreatePolygonRgn
+CreateRectRgn
+CreateRectRgnIndirect
+CreateRoundRectRgn
+CreateScalableFontResourceA
+CreateScalableFontResourceW
+CreateSolidBrush
+DPtoLP
+DeleteColorSpace
+DeleteDC
+DeleteEnhMetaFile
+DeleteMetaFile
+DeleteObject
+DescribePixelFormat
+DeviceCapabilitiesEx
+DeviceCapabilitiesExA
+DeviceCapabilitiesExW
+DrawEscape
+Ellipse
+EnableEUDC
+EndDoc
+EndPage
+EndPath
+EnumEnhMetaFile
+EnumFontFamiliesA
+EnumFontFamiliesExA
+EnumFontFamiliesExW
+EnumFontFamiliesW
+EnumFontsA
+EnumFontsW
+EnumICMProfilesA
+EnumICMProfilesW
+EnumMetaFile
+EnumObjects
+EqualRgn
+Escape
+ExcludeClipRect
+ExtCreatePen
+ExtCreateRegion
+ExtEscape
+ExtFloodFill
+ExtSelectClipRgn
+ExtTextOutA
+ExtTextOutW
+FillPath
+FillRgn
+FixBrushOrgEx
+FlattenPath
+FloodFill
+FrameRgn
+GdiComment
+GdiFlush
+GdiGetBatchLimit
+GdiPlayDCScript
+GdiPlayJournal
+GdiPlayScript
+GdiSetBatchLimit
+GetArcDirection
+GetAspectRatioFilterEx
+GetBitmapBits
+GetBitmapDimensionEx
+GetBkColor
+GetBkMode
+GetBoundsRect
+GetBrushOrgEx
+GetCharABCWidthsA
+GetCharABCWidthsFloatA
+GetCharABCWidthsFloatW
+GetCharABCWidthsW
+GetCharWidth32A
+GetCharWidth32W
+GetCharWidthA
+GetCharWidthFloatA
+GetCharWidthFloatW
+GetCharWidthW
+GetCharacterPlacementA
+GetCharacterPlacementW
+GetClipBox
+GetClipRgn
+GetColorAdjustment
+GetColorSpace
+GetCurrentObject
+GetCurrentPositionEx
+GetDCOrgEx
+GetDIBColorTable
+GetDIBits
+GetDeviceCaps
+GetDeviceGammaRamp
+GetEnhMetaFileA
+GetEnhMetaFileBits
+GetEnhMetaFileDescriptionA
+GetEnhMetaFileDescriptionW
+GetEnhMetaFileHeader
+GetEnhMetaFilePaletteEntries
+GetEnhMetaFileW
+GetFontData
+GetFontLanguageInfo
+GetFontResourceInfo
+GetGlyphOutline
+GetGlyphOutlineA
+GetGlyphOutlineW
+GetGraphicsMode
+GetICMProfileA
+GetICMProfileW
+GetKerningPairs
+GetKerningPairsA
+GetKerningPairsW
+GetLayout
+GetLogColorSpaceA
+GetLogColorSpaceW
+GetMapMode
+GetMetaFileA
+GetMetaFileBitsEx
+GetMetaFileW
+GetMetaRgn
+GetMiterLimit
+GetNearestColor
+GetNearestPaletteIndex
+GetObjectA
+GetObjectType
+GetObjectW
+GetOutlineTextMetricsA
+GetOutlineTextMetricsW
+GetPaletteEntries
+GetPath
+GetPixel
+GetPixelFormat
+GetPolyFillMode
+GetROP2
+GetRandomRgn
+GetRasterizerCaps
+GetRegionData
+GetRgnBox
+GetStockObject
+GetStretchBltMode
+GetSystemPaletteEntries
+GetSystemPaletteUse
+GetTextAlign
+GetTextCharacterExtra
+GetTextCharset
+GetTextCharsetInfo
+GetTextColor
+GetTextExtentExPointA
+GetTextExtentExPointW
+GetTextExtentPoint32A
+GetTextExtentPoint32W
+GetTextExtentPointA
+GetTextExtentPointW
+GetTextFaceA
+GetTextFaceW
+GetTextMetricsA
+GetTextMetricsW
+GetViewportExtEx
+GetViewportOrgEx
+GetWinMetaFileBits
+GetWindowExtEx
+GetWindowOrgEx
+GetWorldTransform
+IntersectClipRect
+InvertRgn
+LPtoDP
+LineDDA
+LineTo
+MaskBlt
+ModifyWorldTransform
+MoveToEx
+OffsetClipRgn
+OffsetRgn
+OffsetViewportOrgEx
+OffsetWindowOrgEx
+PaintRgn
+PatBlt
+PathToRegion
+Pie
+PlayEnhMetaFile
+PlayEnhMetaFileRecord
+PlayMetaFile
+PlayMetaFileRecord
+PlgBlt
+PolyBezier
+PolyBezierTo
+PolyDraw
+PolyPolygon
+PolyPolyline
+PolyTextOutA
+PolyTextOutW
+Polygon
+Polyline
+PolylineTo
+PtInRegion
+PtVisible
+RealizePalette
+RectInRegion
+RectVisible
+Rectangle
+RemoveFontResourceA
+RemoveFontResourceW
+ResetDCA
+ResetDCW
+ResizePalette
+RestoreDC
+RoundRect
+SaveDC
+ScaleViewportExtEx
+ScaleWindowExtEx
+SelectClipPath
+SelectClipRgn
+SelectObject
+SelectPalette
+SetAbortProc
+SetArcDirection
+SetBitmapBits
+SetBitmapDimensionEx
+SetBkColor
+SetBkMode
+SetBoundsRect
+SetBrushOrgEx
+SetColorAdjustment
+SetColorSpace
+SetDIBColorTable
+SetDIBits
+SetDIBitsToDevice
+SetDeviceGammaRamp
+SetEnhMetaFileBits
+SetFontEnumeration
+SetGraphicsMode
+SetICMMode
+SetICMProfileA
+SetICMProfileW
+SetLayout
+SetMagicColors
+SetMapMode
+SetMapperFlags
+SetMetaFileBitsEx
+SetMetaRgn
+SetMiterLimit
+SetObjectOwner
+SetPaletteEntries
+SetPixel
+SetPixelFormat
+SetPixelV
+SetPolyFillMode
+SetROP2
+SetRectRgn
+SetStretchBltMode
+SetSystemPaletteUse
+SetTextAlign
+SetTextCharacterExtra
+SetTextColor
+SetTextJustification
+SetViewportExtEx
+SetViewportOrgEx
+SetWinMetaFileBits
+SetWindowExtEx
+SetWindowOrgEx
+SetWorldTransform
+StartDocA
+StartDocW
+StartPage
+StretchBlt
+StretchDIBits
+StrokeAndFillPath
+StrokePath
+SwapBuffers
+TextOutA
+TextOutW
+TranslateCharsetInfo
+UnrealizeObject
+UpdateColors
+UpdateICMRegKeyA
+UpdateICMRegKeyW
+WidenPath
+gdiPlaySpoolStream
+pfnRealizePalette
+pfnSelectPalette
diff --git a/tinyc/win32/lib/kernel32.def b/tinyc/win32/lib/kernel32.def
new file mode 100755
index 000000000..85dd980d5
--- /dev/null
+++ b/tinyc/win32/lib/kernel32.def
@@ -0,0 +1,763 @@
+LIBRARY kernel32.dll
+
+EXPORTS
+AddAtomA
+AddAtomW
+AllocConsole
+AllocLSCallback
+AllocSLCallback
+AreFileApisANSI
+BackupRead
+BackupSeek
+BackupWrite
+Beep
+BeginUpdateResourceA
+BeginUpdateResourceW
+BuildCommDCBA
+BuildCommDCBAndTimeoutsA
+BuildCommDCBAndTimeoutsW
+BuildCommDCBW
+CallNamedPipeA
+CallNamedPipeW
+Callback12
+Callback16
+Callback20
+Callback24
+Callback28
+Callback32
+Callback36
+Callback4
+Callback40
+Callback44
+Callback48
+Callback52
+Callback56
+Callback60
+Callback64
+Callback8
+CancelDeviceWakeupRequest
+CancelIo
+CancelWaitableTimer
+ClearCommBreak
+ClearCommError
+CloseHandle
+CloseProfileUserMapping
+CloseSystemHandle
+CommConfigDialogA
+CommConfigDialogW
+CompareFileTime
+CompareStringA
+CompareStringW
+ConnectNamedPipe
+ContinueDebugEvent
+ConvertDefaultLocale
+ConvertThreadToFiber
+ConvertToGlobalHandle
+CopyFileA
+CopyFileExA
+CopyFileExW
+CopyFileW
+CreateConsoleScreenBuffer
+CreateDirectoryA
+CreateDirectoryExA
+CreateDirectoryExW
+CreateDirectoryW
+CreateEventA
+CreateEventW
+CreateFiber
+CreateFileA
+CreateFileMappingA
+CreateFileMappingW
+CreateFileW
+CreateIoCompletionPort
+CreateKernelThread
+CreateMailslotA
+CreateMailslotW
+CreateMutexA
+CreateMutexW
+CreateNamedPipeA
+CreateNamedPipeW
+CreatePipe
+CreateProcessA
+CreateProcessW
+CreateRemoteThread
+CreateSemaphoreA
+CreateSemaphoreW
+CreateSocketHandle
+CreateTapePartition
+CreateThread
+CreateToolhelp32Snapshot
+CreateWaitableTimerA
+CreateWaitableTimerW
+DebugActiveProcess
+DebugBreak
+DefineDosDeviceA
+DefineDosDeviceW
+DeleteAtom
+DeleteCriticalSection
+DeleteFiber
+DeleteFileA
+DeleteFileW
+DeviceIoControl
+DisableThreadLibraryCalls
+DisconnectNamedPipe
+DosDateTimeToFileTime
+DuplicateHandle
+EndUpdateResourceA
+EndUpdateResourceW
+EnterCriticalSection
+EnumCalendarInfoA
+EnumCalendarInfoExA
+EnumCalendarInfoExW
+EnumCalendarInfoW
+EnumDateFormatsA
+EnumDateFormatsExA
+EnumDateFormatsExW
+EnumDateFormatsW
+EnumLanguageGroupLocalesA
+EnumLanguageGroupLocalesW
+EnumResourceLanguagesA
+EnumResourceLanguagesW
+EnumResourceNamesA
+EnumResourceNamesW
+EnumResourceTypesA
+EnumResourceTypesW
+EnumSystemCodePagesA
+EnumSystemCodePagesW
+EnumSystemGeoID
+EnumSystemLanguageGroupsA
+EnumSystemLanguageGroupsW
+EnumSystemLocalesA
+EnumSystemLocalesW
+EnumTimeFormatsA
+EnumTimeFormatsW
+EnumUILanguagesA
+EnumUILanguagesW
+EraseTape
+EscapeCommFunction
+ExitProcess
+ExitThread
+ExpandEnvironmentStringsA
+ExpandEnvironmentStringsW
+FT_Exit0
+FT_Exit12
+FT_Exit16
+FT_Exit20
+FT_Exit24
+FT_Exit28
+FT_Exit32
+FT_Exit36
+FT_Exit4
+FT_Exit40
+FT_Exit44
+FT_Exit48
+FT_Exit52
+FT_Exit56
+FT_Exit8
+FT_Prolog
+FT_Thunk
+FatalAppExitA
+FatalAppExitW
+FatalExit
+FileTimeToDosDateTime
+FileTimeToLocalFileTime
+FileTimeToSystemTime
+FillConsoleOutputAttribute
+FillConsoleOutputCharacterA
+FillConsoleOutputCharacterW
+FindAtomA
+FindAtomW
+FindClose
+FindCloseChangeNotification
+FindFirstChangeNotificationA
+FindFirstChangeNotificationW
+FindFirstFileA
+FindFirstFileExA
+FindFirstFileExW
+FindFirstFileW
+FindNextChangeNotification
+FindNextFileA
+FindNextFileW
+FindResourceA
+FindResourceExA
+FindResourceExW
+FindResourceW
+FlushConsoleInputBuffer
+FlushFileBuffers
+FlushInstructionCache
+FlushViewOfFile
+FoldStringA
+FoldStringW
+FormatMessageA
+FormatMessageW
+FreeConsole
+FreeEnvironmentStringsA
+FreeEnvironmentStringsW
+FreeLSCallback
+FreeLibrary
+FreeLibraryAndExitThread
+FreeResource
+FreeSLCallback
+GenerateConsoleCtrlEvent
+GetACP
+GetAtomNameA
+GetAtomNameW
+GetBinaryType
+GetBinaryTypeA
+GetBinaryTypeW
+GetCPInfo
+GetCPInfoExA
+GetCPInfoExW
+GetCalendarInfoA
+GetCalendarInfoW
+GetCommConfig
+GetCommMask
+GetCommModemStatus
+GetCommProperties
+GetCommState
+GetCommTimeouts
+GetCommandLineA
+GetCommandLineW
+GetCompressedFileSizeA
+GetCompressedFileSizeW
+GetComputerNameA
+GetComputerNameW
+GetConsoleCP
+GetConsoleCursorInfo
+GetConsoleMode
+GetConsoleOutputCP
+GetConsoleScreenBufferInfo
+GetConsoleTitleA
+GetConsoleTitleW
+GetCurrencyFormatA
+GetCurrencyFormatW
+GetCurrentDirectoryA
+GetCurrentDirectoryW
+GetCurrentProcess
+GetCurrentProcessId
+GetCurrentThread
+GetCurrentThreadId
+GetDateFormatA
+GetDateFormatW
+GetDaylightFlag
+GetDefaultCommConfigA
+GetDefaultCommConfigW
+GetDevicePowerState
+GetDiskFreeSpaceA
+GetDiskFreeSpaceExA
+GetDiskFreeSpaceExW
+GetDiskFreeSpaceW
+GetDriveTypeA
+GetDriveTypeW
+GetEnvironmentStrings
+GetEnvironmentStringsA
+GetEnvironmentStringsW
+GetEnvironmentVariableA
+GetEnvironmentVariableW
+GetErrorMode
+GetExitCodeProcess
+GetExitCodeThread
+GetFileAttributesA
+GetFileAttributesExA
+GetFileAttributesExW
+GetFileAttributesW
+GetFileInformationByHandle
+GetFileSize
+GetFileTime
+GetFileType
+GetFullPathNameA
+GetFullPathNameW
+GetGeoInfoA
+GetGeoInfoW
+GetHandleContext
+GetHandleInformation
+GetLSCallbackTarget
+GetLSCallbackTemplate
+GetLargestConsoleWindowSize
+GetLastError
+GetLocalTime
+GetLocaleInfoA
+GetLocaleInfoW
+GetLogicalDriveStringsA
+GetLogicalDriveStringsW
+GetLogicalDrives
+GetLongPathNameA
+GetLongPathNameW
+GetMailslotInfo
+GetModuleFileNameA
+GetModuleFileNameW
+GetModuleHandleA
+GetModuleHandleW
+GetNamedPipeHandleStateA
+GetNamedPipeHandleStateW
+GetNamedPipeInfo
+GetNumberFormatA
+GetNumberFormatW
+GetNumberOfConsoleInputEvents
+GetNumberOfConsoleMouseButtons
+GetOEMCP
+GetOverlappedResult
+GetPriorityClass
+GetPrivateProfileIntA
+GetPrivateProfileIntW
+GetPrivateProfileSectionA
+GetPrivateProfileSectionNamesA
+GetPrivateProfileSectionNamesW
+GetPrivateProfileSectionW
+GetPrivateProfileStringA
+GetPrivateProfileStringW
+GetPrivateProfileStructA
+GetPrivateProfileStructW
+GetProcAddress
+GetProcessAffinityMask
+GetProcessFlags
+GetProcessHeap
+GetProcessHeaps
+GetProcessPriorityBoost
+GetProcessShutdownParameters
+GetProcessTimes
+GetProcessVersion
+GetProcessWorkingSetSize
+GetProductName
+GetProfileIntA
+GetProfileIntW
+GetProfileSectionA
+GetProfileSectionW
+GetProfileStringA
+GetProfileStringW
+GetQueuedCompletionStatus
+GetSLCallbackTarget
+GetSLCallbackTemplate
+GetShortPathNameA
+GetShortPathNameW
+GetStartupInfoA
+GetStartupInfoW
+GetStdHandle
+GetStringTypeA
+GetStringTypeExA
+GetStringTypeExW
+GetStringTypeW
+GetSystemDefaultLCID
+GetSystemDefaultLangID
+GetSystemDefaultUILanguage
+GetSystemDirectoryA
+GetSystemDirectoryW
+GetSystemInfo
+GetSystemPowerStatus
+GetSystemTime
+GetSystemTimeAdjustment
+GetSystemTimeAsFileTime
+GetTapeParameters
+GetTapePosition
+GetTapeStatus
+GetTempFileNameA
+GetTempFileNameW
+GetTempPathA
+GetTempPathW
+GetThreadContext
+GetThreadLocale
+GetThreadPriority
+GetThreadPriorityBoost
+GetThreadSelectorEntry
+GetThreadTimes
+GetTickCount
+GetTimeFormatA
+GetTimeFormatW
+GetTimeZoneInformation
+GetUserDefaultLCID
+GetUserDefaultLangID
+GetUserDefaultUILanguage
+GetUserGeoID
+GetVersion
+GetVersionExA
+GetVersionExW
+GetVolumeInformationA
+GetVolumeInformationW
+GetWindowsDirectoryA
+GetWindowsDirectoryW
+GetWriteWatch
+GlobalAddAtomA
+GlobalAddAtomW
+GlobalAlloc
+GlobalCompact
+GlobalDeleteAtom
+GlobalFindAtomA
+GlobalFindAtomW
+GlobalFix
+GlobalFlags
+GlobalFree
+GlobalGetAtomNameA
+GlobalGetAtomNameW
+GlobalHandle
+GlobalLock
+GlobalMemoryStatus
+GlobalReAlloc
+GlobalSize
+GlobalUnWire
+GlobalUnfix
+GlobalUnlock
+GlobalWire
+Heap32First
+Heap32ListFirst
+Heap32ListNext
+Heap32Next
+HeapAlloc
+HeapCompact
+HeapCreate
+HeapDestroy
+HeapFree
+HeapLock
+HeapReAlloc
+HeapSetFlags
+HeapSize
+HeapUnlock
+HeapValidate
+HeapWalk
+InitAtomTable
+InitializeCriticalSection
+InitializeCriticalSectionAndSpinCount
+InterlockedCompareExchange
+InterlockedDecrement
+InterlockedExchange
+InterlockedExchangeAdd
+InterlockedIncrement
+InvalidateNLSCache
+IsBadCodePtr
+IsBadHugeReadPtr
+IsBadHugeWritePtr
+IsBadReadPtr
+IsBadStringPtrA
+IsBadStringPtrW
+IsBadWritePtr
+IsDBCSLeadByte
+IsDBCSLeadByteEx
+IsDebuggerPresent
+IsLSCallback
+IsProcessorFeaturePresent
+IsSLCallback
+IsSystemResumeAutomatic
+IsValidCodePage
+IsValidLanguageGroup
+IsValidLocale
+K32Thk1632Epilog
+K32Thk1632Prolog
+K32_NtCreateFile
+K32_RtlNtStatusToDosError
+LCMapStringA
+LCMapStringW
+LeaveCriticalSection
+LoadLibraryA
+LoadLibraryExA
+LoadLibraryExW
+LoadLibraryW
+LoadModule
+LoadResource
+LocalAlloc
+LocalCompact
+LocalFileTimeToFileTime
+LocalFlags
+LocalFree
+LocalHandle
+LocalLock
+LocalReAlloc
+LocalShrink
+LocalSize
+LocalUnlock
+LockFile
+LockFileEx
+LockResource
+MakeCriticalSectionGlobal
+MapHInstLS
+MapHInstLS_PN
+MapHInstSL
+MapHInstSL_PN
+MapHModuleLS
+MapHModuleSL
+MapLS
+MapSL
+MapSLFix
+MapViewOfFile
+MapViewOfFileEx
+Module32First
+Module32Next
+MoveFileA
+MoveFileExA
+MoveFileExW
+MoveFileW
+MulDiv
+MultiByteToWideChar
+NotifyNLSUserCache
+OpenEventA
+OpenEventW
+OpenFile
+OpenFileMappingA
+OpenFileMappingW
+OpenMutexA
+OpenMutexW
+OpenProcess
+OpenProfileUserMapping
+OpenSemaphoreA
+OpenSemaphoreW
+OpenThread
+OpenVxDHandle
+OpenWaitableTimerA
+OpenWaitableTimerW
+OutputDebugStringA
+OutputDebugStringW
+PeekConsoleInputA
+PeekConsoleInputW
+PeekNamedPipe
+PostQueuedCompletionStatus
+PrepareTape
+Process32First
+Process32Next
+PulseEvent
+PurgeComm
+QT_Thunk
+QueryDosDeviceA
+QueryDosDeviceW
+QueryNumberOfEventLogRecords
+QueryOldestEventLogRecord
+QueryPerformanceCounter
+QueryPerformanceFrequency
+QueueUserAPC
+RaiseException
+ReadConsoleA
+ReadConsoleInputA
+ReadConsoleInputW
+ReadConsoleOutputA
+ReadConsoleOutputAttribute
+ReadConsoleOutputCharacterA
+ReadConsoleOutputCharacterW
+ReadConsoleOutputW
+ReadConsoleW
+ReadDirectoryChangesW
+ReadFile
+ReadFileEx
+ReadFileScatter
+ReadProcessMemory
+RegisterServiceProcess
+RegisterSysMsgHandler
+ReinitializeCriticalSection
+ReleaseMutex
+ReleaseSemaphore
+RemoveDirectoryA
+RemoveDirectoryW
+RequestDeviceWakeup
+RequestWakeupLatency
+ResetEvent
+ResetNLSUserInfoCache
+ResetWriteWatch
+ResumeThread
+RtlFillMemory
+RtlMoveMemory
+RtlUnwind
+RtlZeroMemory
+SMapLS
+SMapLS_IP_EBP_12
+SMapLS_IP_EBP_16
+SMapLS_IP_EBP_20
+SMapLS_IP_EBP_24
+SMapLS_IP_EBP_28
+SMapLS_IP_EBP_32
+SMapLS_IP_EBP_36
+SMapLS_IP_EBP_40
+SMapLS_IP_EBP_8
+SUnMapLS
+SUnMapLS_IP_EBP_12
+SUnMapLS_IP_EBP_16
+SUnMapLS_IP_EBP_20
+SUnMapLS_IP_EBP_24
+SUnMapLS_IP_EBP_28
+SUnMapLS_IP_EBP_32
+SUnMapLS_IP_EBP_36
+SUnMapLS_IP_EBP_40
+SUnMapLS_IP_EBP_8
+ScrollConsoleScreenBufferA
+ScrollConsoleScreenBufferW
+SearchPathA
+SearchPathW
+SetCalendarInfoA
+SetCalendarInfoW
+SetCommBreak
+SetCommConfig
+SetCommMask
+SetCommState
+SetCommTimeouts
+SetComputerNameA
+SetComputerNameW
+SetConsoleActiveScreenBuffer
+SetConsoleCP
+SetConsoleCtrlHandler
+SetConsoleCursorInfo
+SetConsoleCursorPosition
+SetConsoleMode
+SetConsoleOutputCP
+SetConsoleScreenBufferSize
+SetConsoleTextAttribute
+SetConsoleTitleA
+SetConsoleTitleW
+SetConsoleWindowInfo
+SetCriticalSectionSpinCount
+SetCurrentDirectoryA
+SetCurrentDirectoryW
+SetDaylightFlag
+SetDefaultCommConfigA
+SetDefaultCommConfigW
+SetEndOfFile
+SetEnvironmentVariableA
+SetEnvironmentVariableW
+SetErrorMode
+SetEvent
+SetFileApisToANSI
+SetFileApisToOEM
+SetFileAttributesA
+SetFileAttributesW
+SetFilePointer
+SetFileTime
+SetHandleContext
+SetHandleCount
+SetHandleInformation
+SetLastError
+SetLocalTime
+SetLocaleInfoA
+SetLocaleInfoW
+SetMailslotInfo
+SetMessageWaitingIndicator
+SetNamedPipeHandleState
+SetPriorityClass
+SetProcessAffinityMask
+SetProcessPriorityBoost
+SetProcessShutdownParameters
+SetProcessWorkingSetSize
+SetStdHandle
+SetSystemPowerState
+SetSystemTime
+SetSystemTimeAdjustment
+SetTapeParameters
+SetTapePosition
+SetThreadAffinityMask
+SetThreadContext
+SetThreadExecutionState
+SetThreadIdealProcessor
+SetThreadLocale
+SetThreadPriority
+SetThreadPriorityBoost
+SetTimeZoneInformation
+SetUnhandledExceptionFilter
+SetUserGeoID
+SetVolumeLabelA
+SetVolumeLabelW
+SetWaitableTimer
+SetupComm
+SignalObjectAndWait
+SignalSysMsgHandlers
+SizeofResource
+Sleep
+SleepEx
+SuspendThread
+SwitchToFiber
+SwitchToThread
+SystemTimeToFileTime
+SystemTimeToTzSpecificLocalTime
+TerminateProcess
+TerminateThread
+Thread32First
+Thread32Next
+ThunkConnect32
+TlsAlloc
+TlsAllocInternal
+TlsFree
+TlsFreeInternal
+TlsGetValue
+TlsSetValue
+Toolhelp32ReadProcessMemory
+TransactNamedPipe
+TransmitCommChar
+TryEnterCriticalSection
+UTRegister
+UTUnRegister
+UnMapLS
+UnMapSLFixArray
+UnhandledExceptionFilter
+UninitializeCriticalSection
+UnlockFile
+UnlockFileEx
+UnmapViewOfFile
+UpdateResourceA
+UpdateResourceW
+VerLanguageNameA
+VerLanguageNameW
+VirtualAlloc
+VirtualAllocEx
+VirtualFree
+VirtualFreeEx
+VirtualLock
+VirtualProtect
+VirtualProtectEx
+VirtualQuery
+VirtualQueryEx
+VirtualUnlock
+WaitCommEvent
+WaitForDebugEvent
+WaitForMultipleObjects
+WaitForMultipleObjectsEx
+WaitForSingleObject
+WaitForSingleObjectEx
+WaitNamedPipeA
+WaitNamedPipeW
+WideCharToMultiByte
+WinExec
+WriteConsoleA
+WriteConsoleInputA
+WriteConsoleInputW
+WriteConsoleOutputA
+WriteConsoleOutputAttribute
+WriteConsoleOutputCharacterA
+WriteConsoleOutputCharacterW
+WriteConsoleOutputW
+WriteConsoleW
+WriteFile
+WriteFileEx
+WriteFileGather
+WritePrivateProfileSectionA
+WritePrivateProfileSectionW
+WritePrivateProfileStringA
+WritePrivateProfileStringW
+WritePrivateProfileStructA
+WritePrivateProfileStructW
+WriteProcessMemory
+WriteProfileSectionA
+WriteProfileSectionW
+WriteProfileStringA
+WriteProfileStringW
+WriteTapemark
+_DebugOut
+_DebugPrintf
+_hread
+_hwrite
+_lclose
+_lcreat
+_llseek
+_lopen
+_lread
+_lwrite
+dprintf
+lstrcat
+lstrcatA
+lstrcatW
+lstrcmp
+lstrcmpA
+lstrcmpW
+lstrcmpi
+lstrcmpiA
+lstrcmpiW
+lstrcpy
+lstrcpyA
+lstrcpyW
+lstrcpyn
+lstrcpynA
+lstrcpynW
+lstrlen
+lstrlenA
+lstrlenW
diff --git a/tinyc/win32/lib/libtcc1.a b/tinyc/win32/lib/libtcc1.a
new file mode 100755
index 000000000..0062e8f93
--- /dev/null
+++ b/tinyc/win32/lib/libtcc1.a
Binary files differdiff --git a/tinyc/win32/lib/msvcrt.def b/tinyc/win32/lib/msvcrt.def
new file mode 100755
index 000000000..e4f202373
--- /dev/null
+++ b/tinyc/win32/lib/msvcrt.def
@@ -0,0 +1,782 @@
+LIBRARY msvcrt.dll
+
+EXPORTS
+$I10_OUTPUT
+??0__non_rtti_object@@QAE@ABV0@@Z
+??0__non_rtti_object@@QAE@PBD@Z
+??0bad_cast@@QAE@ABQBD@Z
+??0bad_cast@@QAE@ABV0@@Z
+??0bad_typeid@@QAE@ABV0@@Z
+??0bad_typeid@@QAE@PBD@Z
+??0exception@@QAE@ABQBD@Z
+??0exception@@QAE@ABV0@@Z
+??0exception@@QAE@XZ
+??1__non_rtti_object@@UAE@XZ
+??1bad_cast@@UAE@XZ
+??1bad_typeid@@UAE@XZ
+??1exception@@UAE@XZ
+??1type_info@@UAE@XZ
+??2@YAPAXI@Z
+??3@YAXPAX@Z
+??4__non_rtti_object@@QAEAAV0@ABV0@@Z
+??4bad_cast@@QAEAAV0@ABV0@@Z
+??4bad_typeid@@QAEAAV0@ABV0@@Z
+??4exception@@QAEAAV0@ABV0@@Z
+??8type_info@@QBEHABV0@@Z
+??9type_info@@QBEHABV0@@Z
+??_7__non_rtti_object@@6B@
+??_7bad_cast@@6B@
+??_7bad_typeid@@6B@
+??_7exception@@6B@
+??_E__non_rtti_object@@UAEPAXI@Z
+??_Ebad_cast@@UAEPAXI@Z
+??_Ebad_typeid@@UAEPAXI@Z
+??_Eexception@@UAEPAXI@Z
+??_G__non_rtti_object@@UAEPAXI@Z
+??_Gbad_cast@@UAEPAXI@Z
+??_Gbad_typeid@@UAEPAXI@Z
+??_Gexception@@UAEPAXI@Z
+??_U@YAPAXI@Z
+??_V@YAXPAX@Z
+?_query_new_handler@@YAP6AHI@ZXZ
+?_query_new_mode@@YAHXZ
+?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
+?_set_new_mode@@YAHH@Z
+?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z
+?before@type_info@@QBEHABV1@@Z
+?name@type_info@@QBEPBDXZ
+?raw_name@type_info@@QBEPBDXZ
+?set_new_handler@@YAP6AXXZP6AXXZ@Z
+?set_terminate@@YAP6AXXZP6AXXZ@Z
+?set_unexpected@@YAP6AXXZP6AXXZ@Z
+?terminate@@YAXXZ
+?unexpected@@YAXXZ
+?what@exception@@UBEPBDXZ
+_CIacos
+_CIasin
+_CIatan
+_CIatan2
+_CIcos
+_CIcosh
+_CIexp
+_CIfmod
+_CIlog
+_CIlog10
+_CIpow
+_CIsin
+_CIsinh
+_CIsqrt
+_CItan
+_CItanh
+_CxxThrowException
+_EH_prolog
+_Getdays
+_Getmonths
+_Gettnames
+_HUGE
+_Strftime
+_XcptFilter
+__CxxFrameHandler
+__CxxLongjmpUnwind
+__RTCastToVoid
+__RTDynamicCast
+__RTtypeid
+__STRINGTOLD
+__argc
+__argv
+__badioinfo
+__crtCompareStringA
+__crtGetLocaleInfoW
+__crtLCMapStringA
+__dllonexit
+__doserrno
+__fpecode
+__getmainargs
+__initenv
+__isascii
+__iscsym
+__iscsymf
+__lc_codepage
+__lc_collate_cp
+__lc_handle
+__lconv_init
+__mb_cur_max
+__p___argc
+__p___argv
+__p___initenv
+__p___mb_cur_max
+__p___wargv
+__p___winitenv
+__p__acmdln
+__p__amblksiz
+__p__commode
+__p__daylight
+__p__dstbias
+__p__environ
+__p__fileinfo
+__p__fmode
+__p__iob
+__p__mbcasemap
+__p__mbctype
+__p__osver
+__p__pctype
+__p__pgmptr
+__p__pwctype
+__p__timezone
+__p__tzname
+__p__wcmdln
+__p__wenviron
+__p__winmajor
+__p__winminor
+__p__winver
+__p__wpgmptr
+__pioinfo
+__pxcptinfoptrs
+__set_app_type
+__setlc_active
+__setusermatherr
+__threadhandle
+__threadid
+__toascii
+__unDName
+__unDNameEx
+__unguarded_readlc_active
+__wargv
+__wgetmainargs
+__winitenv
+_abnormal_termination
+_access
+_acmdln
+_adj_fdiv_m16i
+_adj_fdiv_m32
+_adj_fdiv_m32i
+_adj_fdiv_m64
+_adj_fdiv_r
+_adj_fdivr_m16i
+_adj_fdivr_m32
+_adj_fdivr_m32i
+_adj_fdivr_m64
+_adj_fpatan
+_adj_fprem
+_adj_fprem1
+_adj_fptan
+_adjust_fdiv
+_aexit_rtn
+_amsg_exit
+_assert
+_atodbl
+_atoi64
+_atoldbl
+_beep
+_beginthread
+_beginthreadex
+_c_exit
+_cabs
+_callnewh
+_cexit
+_cgets
+_chdir
+_chdrive
+_chgsign
+_chkesp
+_chmod
+_chsize
+_clearfp
+_close
+_commit
+_commode
+_control87
+_controlfp
+_copysign
+_cprintf
+_cputs
+_creat
+_cscanf
+_ctime64
+_ctype
+_cwait
+_daylight
+_dstbias
+_dup
+_dup2
+_ecvt
+_endthread
+_endthreadex
+_environ
+_eof
+_errno
+_except_handler2
+_except_handler3
+_execl
+_execle
+_execlp
+_execlpe
+_execv
+_execve
+_execvp
+_execvpe
+_exit
+_expand
+_fcloseall
+_fcvt
+_fdopen
+_fgetchar
+_fgetwchar
+_filbuf
+_fileinfo
+_filelength
+_filelengthi64
+_fileno
+_findclose
+_findfirst
+_findfirst64
+_findfirsti64
+_findnext
+_findnext64
+_findnexti64
+_finite
+_flsbuf
+_flushall
+_fmode
+_fpclass
+_fpieee_flt
+_fpreset
+_fputchar
+_fputwchar
+_fsopen
+_fstat
+_fstat64
+_fstati64
+_ftime
+_ftime64
+_ftol
+_fullpath
+_futime
+_futime64
+_gcvt
+_get_osfhandle
+_get_sbh_threshold
+_getch
+_getche
+_getcwd
+_getdcwd
+_getdiskfree
+_getdllprocaddr
+_getdrive
+_getdrives
+_getmaxstdio
+_getmbcp
+_getpid
+_getsystime
+_getw
+_getws
+_global_unwind2
+_gmtime64
+_heapadd
+_heapchk
+_heapmin
+_heapset
+_heapused
+_heapwalk
+_hypot
+_i64toa
+_i64tow
+_initterm
+_inp
+_inpd
+_inpw
+_iob
+_isatty
+_isctype
+_ismbbalnum
+_ismbbalpha
+_ismbbgraph
+_ismbbkalnum
+_ismbbkana
+_ismbbkprint
+_ismbbkpunct
+_ismbblead
+_ismbbprint
+_ismbbpunct
+_ismbbtrail
+_ismbcalnum
+_ismbcalpha
+_ismbcdigit
+_ismbcgraph
+_ismbchira
+_ismbckata
+_ismbcl0
+_ismbcl1
+_ismbcl2
+_ismbclegal
+_ismbclower
+_ismbcprint
+_ismbcpunct
+_ismbcspace
+_ismbcsymbol
+_ismbcupper
+_ismbslead
+_ismbstrail
+_isnan
+_itoa
+_itow
+_j0
+_j1
+_jn
+_kbhit
+_lfind
+_loaddll
+_local_unwind2
+_localtime64
+_lock
+_locking
+_logb
+_longjmpex
+_lrotl
+_lrotr
+_lsearch
+_lseek
+_lseeki64
+_ltoa
+_ltow
+_makepath
+_mbbtombc
+_mbbtype
+_mbcasemap
+_mbccpy
+_mbcjistojms
+_mbcjmstojis
+_mbclen
+_mbctohira
+_mbctokata
+_mbctolower
+_mbctombb
+_mbctoupper
+_mbctype
+_mbsbtype
+_mbscat
+_mbschr
+_mbscmp
+_mbscoll
+_mbscpy
+_mbscspn
+_mbsdec
+_mbsdup
+_mbsicmp
+_mbsicoll
+_mbsinc
+_mbslen
+_mbslwr
+_mbsnbcat
+_mbsnbcmp
+_mbsnbcnt
+_mbsnbcoll
+_mbsnbcpy
+_mbsnbicmp
+_mbsnbicoll
+_mbsnbset
+_mbsncat
+_mbsnccnt
+_mbsncmp
+_mbsncoll
+_mbsncpy
+_mbsnextc
+_mbsnicmp
+_mbsnicoll
+_mbsninc
+_mbsnset
+_mbspbrk
+_mbsrchr
+_mbsrev
+_mbsset
+_mbsspn
+_mbsspnp
+_mbsstr
+_mbstok
+_mbstrlen
+_mbsupr
+_memccpy
+_memicmp
+_mkdir
+_mktemp
+_mktime64
+_msize
+_nextafter
+_onexit
+_open
+_open_osfhandle
+_osplatform
+_osver
+_outp
+_outpd
+_outpw
+_pclose
+_pctype
+_pgmptr
+_pipe
+_popen
+_purecall
+_putch
+_putenv
+_putw
+_putws
+_pwctype
+_read
+_rmdir
+_rmtmp
+_rotl
+_rotr
+_safe_fdiv
+_safe_fdivr
+_safe_fprem
+_safe_fprem1
+_scalb
+_searchenv
+_seh_longjmp_unwind
+_set_error_mode
+_set_sbh_threshold
+_seterrormode
+_setjmp
+_setjmp3
+_setmaxstdio
+_setmbcp
+_setmode
+_setsystime
+_sleep
+_snprintf
+_snwprintf
+_sopen
+_spawnl
+_spawnle
+_spawnlp
+_spawnlpe
+_spawnv
+_spawnve
+_spawnvp
+_spawnvpe
+_splitpath
+_stat
+_stat64
+_stati64
+_statusfp
+_strcmpi
+_strdate
+_strdup
+_strerror
+_stricmp
+_stricoll
+_strlwr
+_strncoll
+_strnicmp
+_strnicoll
+_strnset
+_strrev
+_strset
+_strtime
+_strupr
+_swab
+_sys_errlist
+_sys_nerr
+_tell
+_telli64
+_tempnam
+_time64
+_timezone
+_tolower
+_toupper
+_tzname
+_tzset
+_ui64toa
+_ui64tow
+_ultoa
+_ultow
+_umask
+_ungetch
+_unlink
+_unloaddll
+_unlock
+_utime
+_utime64
+_vsnprintf
+_vsnwprintf
+_waccess
+_wasctime
+_wchdir
+_wchmod
+_wcmdln
+_wcreat
+_wcsdup
+_wcsicmp
+_wcsicoll
+_wcslwr
+_wcsncoll
+_wcsnicmp
+_wcsnicoll
+_wcsnset
+_wcsrev
+_wcsset
+_wcsupr
+_wctime
+_wctime64
+_wenviron
+_wexecl
+_wexecle
+_wexeclp
+_wexeclpe
+_wexecv
+_wexecve
+_wexecvp
+_wexecvpe
+_wfdopen
+_wfindfirst
+_wfindfirst64
+_wfindfirsti64
+_wfindnext
+_wfindnext64
+_wfindnexti64
+_wfopen
+_wfreopen
+_wfsopen
+_wfullpath
+_wgetcwd
+_wgetdcwd
+_wgetenv
+_winmajor
+_winminor
+_winver
+_wmakepath
+_wmkdir
+_wmktemp
+_wopen
+_wperror
+_wpgmptr
+_wpopen
+_wputenv
+_wremove
+_wrename
+_write
+_wrmdir
+_wsearchenv
+_wsetlocale
+_wsopen
+_wspawnl
+_wspawnle
+_wspawnlp
+_wspawnlpe
+_wspawnv
+_wspawnve
+_wspawnvp
+_wspawnvpe
+_wsplitpath
+_wstat
+_wstat64
+_wstati64
+_wstrdate
+_wstrtime
+_wsystem
+_wtempnam
+_wtmpnam
+_wtoi
+_wtoi64
+_wtol
+_wunlink
+_wutime
+_wutime64
+_y0
+_y1
+_yn
+abort
+abs
+acos
+asctime
+asin
+atan
+atan2
+atexit
+atof
+atoi
+atol
+bsearch
+calloc
+ceil
+clearerr
+clock
+cos
+cosh
+ctime
+difftime
+div
+exit
+exp
+fabs
+fclose
+feof
+ferror
+fflush
+fgetc
+fgetpos
+fgets
+fgetwc
+fgetws
+floor
+fmod
+fopen
+fprintf
+fputc
+fputs
+fputwc
+fputws
+fread
+free
+freopen
+frexp
+fscanf
+fseek
+fsetpos
+ftell
+fwprintf
+fwrite
+fwscanf
+getc
+getchar
+getenv
+gets
+getwc
+getwchar
+gmtime
+is_wctype
+isalnum
+isalpha
+iscntrl
+isdigit
+isgraph
+isleadbyte
+islower
+isprint
+ispunct
+isspace
+isupper
+iswalnum
+iswalpha
+iswascii
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+labs
+ldexp
+ldiv
+localeconv
+localtime
+log
+log10
+longjmp
+malloc
+mblen
+mbstowcs
+mbtowc
+memchr
+memcmp
+memcpy
+memmove
+memset
+mktime
+modf
+perror
+pow
+printf
+putc
+putchar
+puts
+putwc
+putwchar
+qsort
+raise
+rand
+realloc
+remove
+rename
+rewind
+scanf
+setbuf
+setlocale
+setvbuf
+signal
+sin
+sinh
+sprintf
+sqrt
+srand
+sscanf
+strcat
+strchr
+strcmp
+strcoll
+strcpy
+strcspn
+strerror
+strftime
+strlen
+strncat
+strncmp
+strncpy
+strpbrk
+strrchr
+strspn
+strstr
+strtod
+strtok
+strtol
+strtoul
+strxfrm
+swprintf
+swscanf
+system
+tan
+tanh
+time
+tmpfile
+tmpnam
+tolower
+toupper
+towlower
+towupper
+ungetc
+ungetwc
+vfprintf
+vfwprintf
+vprintf
+vsprintf
+vswprintf
+vwprintf
+wcscat
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscspn
+wcsftime
+wcslen
+wcsncat
+wcsncmp
+wcsncpy
+wcspbrk
+wcsrchr
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstol
+wcstombs
+wcstoul
+wcsxfrm
+wctomb
+wprintf
+wscanf
diff --git a/tinyc/win32/lib/user32.def b/tinyc/win32/lib/user32.def
new file mode 100755
index 000000000..4d2f704e1
--- /dev/null
+++ b/tinyc/win32/lib/user32.def
@@ -0,0 +1,654 @@
+LIBRARY user32.dll
+
+EXPORTS
+ActivateKeyboardLayout
+AdjustWindowRect
+AdjustWindowRectEx
+AlignRects
+AllowSetForegroundWindow
+AnimateWindow
+AnyPopup
+AppendMenuA
+AppendMenuW
+ArrangeIconicWindows
+AttachThreadInput
+BeginDeferWindowPos
+BeginPaint
+BlockInput
+BringWindowToTop
+BroadcastSystemMessage
+BroadcastSystemMessageA
+BroadcastSystemMessageW
+CalcChildScroll
+CallMsgFilter
+CallMsgFilterA
+CallMsgFilterW
+CallNextHookEx
+CallWindowProcA
+CallWindowProcW
+CascadeChildWindows
+CascadeWindows
+ChangeClipboardChain
+ChangeDisplaySettingsA
+ChangeDisplaySettingsExA
+ChangeDisplaySettingsExW
+ChangeDisplaySettingsW
+ChangeMenuA
+ChangeMenuW
+CharLowerA
+CharLowerBuffA
+CharLowerBuffW
+CharLowerW
+CharNextA
+CharNextExA
+CharNextExW
+CharNextW
+CharPrevA
+CharPrevExA
+CharPrevExW
+CharPrevW
+CharToOemA
+CharToOemBuffA
+CharToOemBuffW
+CharToOemW
+CharUpperA
+CharUpperBuffA
+CharUpperBuffW
+CharUpperW
+CheckDlgButton
+CheckMenuItem
+CheckMenuRadioItem
+CheckRadioButton
+ChildWindowFromPoint
+ChildWindowFromPointEx
+ClientThreadConnect
+ClientToScreen
+ClipCursor
+CloseClipboard
+CloseDesktop
+CloseWindow
+CloseWindowStation
+CopyAcceleratorTableA
+CopyAcceleratorTableW
+CopyIcon
+CopyImage
+CopyRect
+CountClipboardFormats
+CreateAcceleratorTableA
+CreateAcceleratorTableW
+CreateCaret
+CreateCursor
+CreateDesktopA
+CreateDesktopW
+CreateDialogIndirectParamA
+CreateDialogIndirectParamW
+CreateDialogParamA
+CreateDialogParamW
+CreateIcon
+CreateIconFromResource
+CreateIconFromResourceEx
+CreateIconIndirect
+CreateMDIWindowA
+CreateMDIWindowW
+CreateMenu
+CreatePopupMenu
+CreateWindowExA
+CreateWindowExW
+CreateWindowStationA
+CreateWindowStationW
+DdeAbandonTransaction
+DdeAccessData
+DdeAddData
+DdeClientTransaction
+DdeCmpStringHandles
+DdeConnect
+DdeConnectList
+DdeCreateDataHandle
+DdeCreateStringHandleA
+DdeCreateStringHandleW
+DdeDisconnect
+DdeDisconnectList
+DdeEnableCallback
+DdeFreeDataHandle
+DdeFreeStringHandle
+DdeGetData
+DdeGetLastError
+DdeImpersonateClient
+DdeInitializeA
+DdeInitializeW
+DdeKeepStringHandle
+DdeNameService
+DdePostAdvise
+DdeQueryConvInfo
+DdeQueryNextServer
+DdeQueryStringA
+DdeQueryStringW
+DdeReconnect
+DdeSetQualityOfService
+DdeSetUserHandle
+DdeUnaccessData
+DdeUninitialize
+DefDlgProcA
+DefDlgProcW
+DefFrameProcA
+DefFrameProcW
+DefMDIChildProcA
+DefMDIChildProcW
+DefWindowProcA
+DefWindowProcW
+DeferWindowPos
+DeleteMenu
+DestroyAcceleratorTable
+DestroyCaret
+DestroyCursor
+DestroyIcon
+DestroyMenu
+DestroyWindow
+DialogBoxIndirectParamA
+DialogBoxIndirectParamW
+DialogBoxParamA
+DialogBoxParamW
+DispatchMessageA
+DispatchMessageW
+DlgDirListA
+DlgDirListComboBoxA
+DlgDirListComboBoxW
+DlgDirListW
+DlgDirSelectComboBoxExA
+DlgDirSelectComboBoxExW
+DlgDirSelectExA
+DlgDirSelectExW
+DragDetect
+DragObject
+DrawAnimatedRects
+DrawCaption
+DrawCaptionTempA
+DrawCaptionTempW
+DrawEdge
+DrawFocusRect
+DrawFrame
+DrawFrameControl
+DrawIcon
+DrawIconEx
+DrawMenuBar
+DrawMenuBarTemp
+DrawStateA
+DrawStateW
+DrawTextA
+DrawTextExA
+DrawTextExW
+DrawTextW
+EditWndProc
+EmptyClipboard
+EnableMenuItem
+EnableScrollBar
+EnableWindow
+EndDeferWindowPos
+EndDialog
+EndMenu
+EndPaint
+EndTask
+EnumChildWindows
+EnumClipboardFormats
+EnumDesktopWindows
+EnumDesktopsA
+EnumDesktopsW
+EnumDisplayDevicesA
+EnumDisplayDevicesW
+EnumDisplayMonitors
+EnumDisplaySettingsA
+EnumDisplaySettingsExA
+EnumDisplaySettingsExW
+EnumDisplaySettingsW
+EnumPropsA
+EnumPropsExA
+EnumPropsExW
+EnumPropsW
+EnumThreadWindows
+EnumWindowStationsA
+EnumWindowStationsW
+EnumWindows
+EqualRect
+ExcludeUpdateRgn
+ExitWindowsEx
+FillRect
+FindWindowA
+FindWindowExA
+FindWindowExW
+FindWindowW
+FlashWindow
+FlashWindowEx
+FrameRect
+FreeDDElParam
+GetActiveWindow
+GetAltTabInfo
+GetAncestor
+GetAsyncKeyState
+GetCapture
+GetCaretBlinkTime
+GetCaretPos
+GetClassInfoA
+GetClassInfoExA
+GetClassInfoExW
+GetClassInfoW
+GetClassLongA
+GetClassLongW
+GetClassNameA
+GetClassNameW
+GetClassWord
+GetClientRect
+GetClipCursor
+GetClipboardData
+GetClipboardFormatNameA
+GetClipboardFormatNameW
+GetClipboardOwner
+GetClipboardSequenceNumber
+GetClipboardViewer
+GetComboBoxInfo
+GetCursor
+GetCursorInfo
+GetCursorPos
+GetDC
+GetDCEx
+GetDesktopWindow
+GetDialogBaseUnits
+GetDlgCtrlID
+GetDlgItem
+GetDlgItemInt
+GetDlgItemTextA
+GetDlgItemTextW
+GetDoubleClickTime
+GetFocus
+GetForegroundWindow
+GetGUIThreadInfo
+GetGuiResources
+GetIconInfo
+GetInputDesktop
+GetInputState
+GetInternalWindowPos
+GetKBCodePage
+GetKeyNameTextA
+GetKeyNameTextW
+GetKeyState
+GetKeyboardLayout
+GetKeyboardLayoutList
+GetKeyboardLayoutNameA
+GetKeyboardLayoutNameW
+GetKeyboardState
+GetKeyboardType
+GetLastActivePopup
+GetListBoxInfo
+GetMenu
+GetMenuBarInfo
+GetMenuCheckMarkDimensions
+GetMenuContextHelpId
+GetMenuDefaultItem
+GetMenuInfo
+GetMenuItemCount
+GetMenuItemID
+GetMenuItemInfoA
+GetMenuItemInfoW
+GetMenuItemRect
+GetMenuState
+GetMenuStringA
+GetMenuStringW
+GetMessageA
+GetMessageExtraInfo
+GetMessagePos
+GetMessageTime
+GetMessageW
+GetMonitorInfoA
+GetMonitorInfoW
+GetMouseMovePoints
+GetMouseMovePointsEx
+GetNextDlgGroupItem
+GetNextDlgTabItem
+GetNextQueueWindow
+GetOpenClipboardWindow
+GetParent
+GetPriorityClipboardFormat
+GetProcessDefaultLayout
+GetProcessWindowStation
+GetPropA
+GetPropW
+GetQueueStatus
+GetScrollBarInfo
+GetScrollInfo
+GetScrollPos
+GetScrollRange
+GetShellWindow
+GetSubMenu
+GetSysColor
+GetSysColorBrush
+GetSystemMenu
+GetSystemMetrics
+GetTabbedTextExtentA
+GetTabbedTextExtentW
+GetThreadDesktop
+GetTitleBarInfo
+GetTopWindow
+GetUpdateRect
+GetUpdateRgn
+GetUserObjectInformationA
+GetUserObjectInformationW
+GetUserObjectSecurity
+GetWindow
+GetWindowContextHelpId
+GetWindowDC
+GetWindowInfo
+GetWindowLongA
+GetWindowLongW
+GetWindowModuleFileNameA
+GetWindowModuleFileNameW
+GetWindowPlacement
+GetWindowRect
+GetWindowRgn
+GetWindowTextA
+GetWindowTextLengthA
+GetWindowTextLengthW
+GetWindowTextW
+GetWindowThreadProcessId
+GetWindowWord
+GrayStringA
+GrayStringW
+HasSystemSleepStarted
+HideCaret
+HiliteMenuItem
+IMPGetIMEA
+IMPGetIMEW
+IMPQueryIMEA
+IMPQueryIMEW
+IMPSetIMEA
+IMPSetIMEW
+ImpersonateDdeClientWindow
+InSendMessage
+InSendMessageEx
+InflateRect
+InitSharedTable
+InitTask
+InsertMenuA
+InsertMenuItemA
+InsertMenuItemW
+InsertMenuW
+InternalGetWindowText
+IntersectRect
+InvalidateRect
+InvalidateRgn
+InvertRect
+IsCharAlphaA
+IsCharAlphaNumericA
+IsCharAlphaNumericW
+IsCharAlphaW
+IsCharLowerA
+IsCharLowerW
+IsCharUpperA
+IsCharUpperW
+IsChild
+IsClipboardFormatAvailable
+IsDialogMessage
+IsDialogMessageA
+IsDialogMessageW
+IsDlgButtonChecked
+IsHungThread
+IsIconic
+IsMenu
+IsRectEmpty
+IsWindow
+IsWindowEnabled
+IsWindowUnicode
+IsWindowVisible
+IsZoomed
+KillTimer
+LoadAcceleratorsA
+LoadAcceleratorsW
+LoadBitmapA
+LoadBitmapW
+LoadCursorA
+LoadCursorFromFileA
+LoadCursorFromFileW
+LoadCursorW
+LoadIconA
+LoadIconW
+LoadImageA
+LoadImageW
+LoadKeyboardLayoutA
+LoadKeyboardLayoutW
+LoadMenuA
+LoadMenuIndirectA
+LoadMenuIndirectW
+LoadMenuW
+LoadStringA
+LoadStringW
+LockSetForegroundWindow
+LockWindowStation
+LockWindowUpdate
+LookupIconIdFromDirectory
+LookupIconIdFromDirectoryEx
+MapDialogRect
+MapVirtualKeyA
+MapVirtualKeyExA
+MapVirtualKeyExW
+MapVirtualKeyW
+MapWindowPoints
+MenuItemFromPoint
+MessageBeep
+MessageBoxA
+MessageBoxExA
+MessageBoxExW
+MessageBoxIndirectA
+MessageBoxIndirectW
+MessageBoxW
+ModifyAccess
+ModifyMenuA
+ModifyMenuW
+MonitorFromPoint
+MonitorFromRect
+MonitorFromWindow
+MoveWindow
+MsgWaitForMultipleObjects
+MsgWaitForMultipleObjectsEx
+NotifyWinEvent
+OemKeyScan
+OemToCharA
+OemToCharBuffA
+OemToCharBuffW
+OemToCharW
+OffsetRect
+OpenClipboard
+OpenDesktopA
+OpenDesktopW
+OpenIcon
+OpenInputDesktop
+OpenWindowStationA
+OpenWindowStationW
+PackDDElParam
+PaintDesktop
+PeekMessageA
+PeekMessageW
+PlaySoundEvent
+PostMessageA
+PostMessageW
+PostQuitMessage
+PostThreadMessageA
+PostThreadMessageW
+PtInRect
+RealChildWindowFromPoint
+RealGetWindowClass
+RedrawWindow
+RegisterClassA
+RegisterClassExA
+RegisterClassExW
+RegisterClassW
+RegisterClipboardFormatA
+RegisterClipboardFormatW
+RegisterDeviceNotificationA
+RegisterDeviceNotificationW
+RegisterHotKey
+RegisterLogonProcess
+RegisterNetworkCapabilities
+RegisterSystemThread
+RegisterTasklist
+RegisterWindowMessageA
+RegisterWindowMessageW
+ReleaseCapture
+ReleaseDC
+RemoveMenu
+RemovePropA
+RemovePropW
+ReplyMessage
+ReuseDDElParam
+ScreenToClient
+ScrollDC
+ScrollWindow
+ScrollWindowEx
+SendDlgItemMessageA
+SendDlgItemMessageW
+SendIMEMessageExA
+SendIMEMessageExW
+SendInput
+SendMessageA
+SendMessageCallbackA
+SendMessageCallbackW
+SendMessageTimeoutA
+SendMessageTimeoutW
+SendMessageW
+SendNotifyMessageA
+SendNotifyMessageW
+SetActiveWindow
+SetCapture
+SetCaretBlinkTime
+SetCaretPos
+SetClassLongA
+SetClassLongW
+SetClassWord
+SetClipboardData
+SetClipboardViewer
+SetCursor
+SetCursorPos
+SetDebugErrorLevel
+SetDeskWallpaper
+SetDesktopBitmap
+SetDlgItemInt
+SetDlgItemTextA
+SetDlgItemTextW
+SetDoubleClickTime
+SetFocus
+SetForegroundWindow
+SetInternalWindowPos
+SetKeyboardState
+SetLastErrorEx
+SetLogonNotifyWindow
+SetMenu
+SetMenuContextHelpId
+SetMenuDefaultItem
+SetMenuInfo
+SetMenuItemBitmaps
+SetMenuItemInfoA
+SetMenuItemInfoW
+SetMessageExtraInfo
+SetMessageQueue
+SetParent
+SetProcessDefaultLayout
+SetProcessWindowStation
+SetPropA
+SetPropW
+SetRect
+SetRectEmpty
+SetScrollInfo
+SetScrollPos
+SetScrollRange
+SetShellWindow
+SetSysColors
+SetSysColorsTemp
+SetSystemCursor
+SetThreadDesktop
+SetTimer
+SetUserObjectInformationA
+SetUserObjectInformationW
+SetUserObjectSecurity
+SetWinEventHook
+SetWindowContextHelpId
+SetWindowFullScreenState
+SetWindowLongA
+SetWindowLongW
+SetWindowPlacement
+SetWindowPos
+SetWindowRgn
+SetWindowTextA
+SetWindowTextW
+SetWindowWord
+SetWindowsHookA
+SetWindowsHookExA
+SetWindowsHookExW
+SetWindowsHookW
+ShowCaret
+ShowCursor
+ShowOwnedPopups
+ShowScrollBar
+ShowWindow
+ShowWindowAsync
+SubtractRect
+SwapMouseButton
+SwitchDesktop
+SwitchToThisWindow
+SysErrorBox
+SystemParametersInfoA
+SystemParametersInfoW
+TabbedTextOutA
+TabbedTextOutW
+TileChildWindows
+TileWindows
+ToAscii
+ToAsciiEx
+ToUnicode
+ToUnicodeEx
+TrackMouseEvent
+TrackPopupMenu
+TrackPopupMenuEx
+TranslateAccelerator
+TranslateAcceleratorA
+TranslateAcceleratorW
+TranslateMDISysAccel
+TranslateMessage
+UnhookWinEvent
+UnhookWindowsHook
+UnhookWindowsHookEx
+UnionRect
+UnloadKeyboardLayout
+UnlockWindowStation
+UnpackDDElParam
+UnregisterClassA
+UnregisterClassW
+UnregisterDeviceNotification
+UnregisterHotKey
+UpdateWindow
+UserClientDllInitialize
+UserIsSystemResumeAutomatic
+UserSetDeviceHoldState
+UserSignalProc
+UserTickleTimer
+ValidateRect
+ValidateRgn
+VkKeyScanA
+VkKeyScanExA
+VkKeyScanExW
+VkKeyScanW
+WINNLSEnableIME
+WINNLSGetEnableStatus
+WINNLSGetIMEHotkey
+WNDPROC_CALLBACK
+WaitForInputIdle
+WaitMessage
+WinHelpA
+WinHelpW
+WinOldAppHackoMatic
+WindowFromDC
+WindowFromPoint
+YieldTask
+_SetProcessDefaultLayout
+keybd_event
+mouse_event
+wsprintfA
+wsprintfW
+wvsprintfA
+wvsprintfW
diff --git a/tinyc/win32/lib/wincrt1.c b/tinyc/win32/lib/wincrt1.c
new file mode 100755
index 000000000..98edb6b9b
--- /dev/null
+++ b/tinyc/win32/lib/wincrt1.c
@@ -0,0 +1,49 @@
+//+---------------------------------------------------------------------------
+
+#include <windows.h>
+
+#define __UNKNOWN_APP    0
+#define __CONSOLE_APP    1
+#define __GUI_APP        2
+void __set_app_type(int);
+void _controlfp(unsigned a, unsigned b);
+
+int _winstart(void)
+{
+	char *szCmd; STARTUPINFO startinfo;
+
+	__set_app_type(__GUI_APP);
+	_controlfp(0x10000, 0x30000);
+
+	szCmd = GetCommandLine();
+	if (szCmd)
+	{
+		while (' ' == *szCmd) szCmd++;
+		if ('\"' == *szCmd)
+		{
+			while (*++szCmd)
+				if ('\"' == *szCmd) { szCmd++; break; }
+		}
+		else
+		{
+			while (*szCmd && ' ' != *szCmd) szCmd++;
+		}
+		while (' ' == *szCmd) szCmd++;
+	}
+
+	GetStartupInfo(&startinfo);
+	exit(WinMain(GetModuleHandle(NULL), NULL, szCmd,
+		(startinfo.dwFlags & STARTF_USESHOWWINDOW) ?
+			startinfo.wShowWindow : SW_SHOWDEFAULT));
+}
+
+int _runwinmain(int argc, char **argv)
+{
+	char *szCmd = NULL;
+	char *p = GetCommandLine();
+	if (argc > 1) szCmd = strstr(p, argv[1]);
+	if (NULL == szCmd) szCmd = "";
+	else if (szCmd > p && szCmd[-1] == '\"') --szCmd;
+	return WinMain(GetModuleHandle(NULL), NULL, szCmd, SW_SHOWDEFAULT);
+}
+
diff --git a/tinyc/win32/libtcc/libtcc.a b/tinyc/win32/libtcc/libtcc.a
new file mode 100755
index 000000000..c2d107453
--- /dev/null
+++ b/tinyc/win32/libtcc/libtcc.a
Binary files differdiff --git a/tinyc/win32/libtcc/libtcc.h b/tinyc/win32/libtcc/libtcc.h
new file mode 100755
index 000000000..96070e299
--- /dev/null
+++ b/tinyc/win32/libtcc/libtcc.h
@@ -0,0 +1,108 @@
+#ifndef LIBTCC_H
+#define LIBTCC_H
+
+#ifdef LIBTCC_AS_DLL
+#define LIBTCCAPI __declspec(dllexport)
+#else
+#define LIBTCCAPI
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct TCCState;
+
+typedef struct TCCState TCCState;
+
+/* create a new TCC compilation context */
+LIBTCCAPI TCCState *tcc_new(void);
+
+/* free a TCC compilation context */
+LIBTCCAPI void tcc_delete(TCCState *s);
+
+/* add debug information in the generated code */
+LIBTCCAPI void tcc_enable_debug(TCCState *s);
+
+/* set error/warning display callback */
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+                        void (*error_func)(void *opaque, const char *msg));
+
+/* set/reset a warning */
+LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value);
+
+/*****************************/
+/* preprocessor */
+
+/* add include path */
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
+
+/* add in system include path */
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
+
+/* define preprocessor symbol 'sym'. Can put optional value */
+LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
+
+/* undefine preprocess symbol 'sym' */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
+
+/*****************************/
+/* compiling */
+
+/* add a file (either a C file, dll, an object, a library or an ld
+   script). Return -1 if error. */
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
+
+/* compile a string containing a C source. Return non zero if
+   error. */
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
+
+/*****************************/
+/* linking commands */
+
+/* set output type. MUST BE CALLED before any compilation */
+#define TCC_OUTPUT_MEMORY   0 /* output will be ran in memory (no
+                                 output file) (default) */
+#define TCC_OUTPUT_EXE      1 /* executable file */
+#define TCC_OUTPUT_DLL      2 /* dynamic library */
+#define TCC_OUTPUT_OBJ      3 /* object file */
+#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
+
+#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
+#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
+#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
+
+/* equivalent to -Lpath option */
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
+
+/* add a symbol to the compiled program */
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, void *val);
+
+/* output an executable, library or object file. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
+
+/* link and run main() function and return its value. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
+
+/* copy code into memory passed in by the caller and do all relocations
+   (needed before using tcc_get_symbol()).
+   returns -1 on error and required size if ptr is NULL */
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
+
+/* return symbol value or NULL if not found */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tinyc/win32/tcc-win32.txt b/tinyc/win32/tcc-win32.txt
new file mode 100755
index 000000000..5b8ddb404
--- /dev/null
+++ b/tinyc/win32/tcc-win32.txt
@@ -0,0 +1,158 @@
+
+    TinyCC
+    ======
+
+    This file contains specific information for usage of TinyCC
+    under MS-Windows.  See tcc-doc.html to have all the features.
+
+
+
+    Compilation from source:
+    ------------------------
+    * You can use the MinGW and MSYS tools available at
+
+    	http://www.mingw.org
+
+    Untar the TCC archive and type in the MSYS shell:
+    
+       ./configure
+       make
+       make install 
+
+    The default install location is c:\Program Files\tcc
+
+
+    * Alternatively you can compile TCC with just GCC from MinGW using
+
+	win32\build-tcc.bat
+
+    To install, copy the entire contents of the win32 directory to
+    where you want.
+
+
+
+    Installation from the binary ZIP package:
+    -----------------------------------------
+    Unzip the package to a directory of your choice.
+    
+    (Note that the binary package does not include libtcc.  If you
+    want TCC as dynamic code generator, please use the source code
+    distribution.)
+
+
+
+    Set the system PATH:
+    --------------------
+    To be able to invoke the compiler from everywhere on your computer by
+    just typing "tcc", please add the directory containing tcc.exe to your
+    system PATH.
+
+
+
+    Examples:
+    ---------
+    Open a console window (DOS box) and 'cd' to the examples directory.
+
+    For the 'Fibonacci' example type:
+
+	tcc fib.c
+
+    For the 'Hello Windows' GUI example type:
+
+	tcc hello_win.c
+
+    for the 'Hello DLL' example type
+
+	tcc -shared dll.c
+	tiny_impdef dll.dll (optional)
+        tcc hello_dll.c dll.def
+
+
+
+    Import Definition Files:
+    ------------------------
+    To link with Windows system DLLs, TCC uses import definition
+    files (.def) instead of libraries.
+
+    The included 'tiny_impdef' program may be used to make additional 
+    .def files for any DLL. For example:
+
+        tiny_impdef.exe opengl32.dll
+
+    Put opengl32.def into the tcc/lib directory.  Specify -lopengl32 at
+    the TCC commandline to link a program that uses opengl32.dll.
+
+
+
+    Header Files:
+    -------------
+    The system header files (except _mingw.h) are from the MinGW
+    distribution:
+
+	http://www.mingw.org/
+
+    From the windows headers, only a minimal set is included.  If you need
+    more,  get MinGW's "w32api" package.
+
+
+
+    Resource Files:
+    ---------------
+    TCC can link windows resources in coff format as generated by MinGW's
+    windres.exe.  For example:
+
+        windres -O coff app.rc -o appres.o
+        tcc app.c appres.o -o app.exe
+
+
+
+    Tiny Libmaker:
+    --------------
+    The included tiny_libmaker tool by Timovj Lahde can be used as
+    'ar' replacement to make a library from several object files:
+
+	tiny_libmaker [rcs] library objectfiles ...
+
+
+
+    Limitations:
+    ------------
+    - On the object file level, currently TCC supports only the ELF format,
+      not COFF as used by MinGW and MSVC.  It is not possible to exchange
+      object files or libraries between TCC and these compilers.  However
+      libraries for TCC from objects by TCC can be made using tiny_libmaker
+      or MinGW's ar.
+
+    - No leading underscore is generated in the ELF symbols.
+
+    - With DLLs, only functions (not data) can be im-/exported.
+
+    - Bounds checking (option -b) is not supported currently.
+
+    - 64-bit systems are not (yet) supported.
+
+
+
+    Documentation and License:
+    --------------------------
+    TCC is distributed under the GNU Lesser General Public License. (See
+    COPYING file or http://www.gnu.org/licenses/lgpl-2.1.html)
+
+    TinyCC homepage is at:
+
+	http://fabrice.bellard.free.fr/tcc/
+
+
+
+    WinAPI Help and 3rd-party tools:
+    --------------------------------
+    The Windows API documentation (Win95) in a single .hlp file is
+    available on the lcc-win32 site as "win32hlp.exe" or from other
+    locations as "win32hlp_big.zip".
+
+    A nice RAD tool to create windows resources (dialog boxes etc.) is
+    "ResEd", available at the RadASM website.
+
+
+
+    --- grischka
diff --git a/tinyc/win32/tools/tiny_impdef.c b/tinyc/win32/tools/tiny_impdef.c
new file mode 100755
index 000000000..040c53acc
--- /dev/null
+++ b/tinyc/win32/tools/tiny_impdef.c
@@ -0,0 +1,393 @@
+/* -------------------------------------------------------------- */
+/*
+ * tiny_impdef creates an export definition file (.def) from a dll
+ * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
+ * 
+ *  Copyright (c) 2005,2007 grischka
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+
+/* Offset to PE file signature */
+#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a                +  \
+                        ((PIMAGE_DOS_HEADER)a)->e_lfanew))
+
+/* MS-OS header identifies the NT PEFile signature dword;
+   the PEFILE header exists just after that dword. */
+#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
+                         ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
+                             SIZE_OF_NT_SIGNATURE))
+
+/* PE optional header is immediately after PEFile header. */
+#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
+                         ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
+                           SIZE_OF_NT_SIGNATURE           +  \
+                           sizeof (IMAGE_FILE_HEADER)))
+
+/* Section headers are immediately after PE optional header. */
+#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a               +  \
+                         ((PIMAGE_DOS_HEADER)a)->e_lfanew +  \
+                           SIZE_OF_NT_SIGNATURE           +  \
+                           sizeof (IMAGE_FILE_HEADER)     +  \
+                           sizeof (IMAGE_OPTIONAL_HEADER)))
+
+
+#define SIZE_OF_NT_SIGNATURE 4
+
+/* -------------------------------------------------------------- */
+
+int WINAPI NumOfSections (
+    LPVOID lpFile)
+{
+    /* Number of sections is indicated in file header. */
+    return (int)
+        ((PIMAGE_FILE_HEADER)
+            PEFHDROFFSET(lpFile))->NumberOfSections;
+}
+
+
+/* -------------------------------------------------------------- */
+
+LPVOID WINAPI ImageDirectoryOffset (
+    LPVOID lpFile,
+    DWORD dwIMAGE_DIRECTORY)
+{
+    PIMAGE_OPTIONAL_HEADER poh;
+    PIMAGE_SECTION_HEADER psh;
+    int nSections = NumOfSections (lpFile);
+    int i = 0;
+    LPVOID VAImageDir;
+
+    /* Retrieve offsets to optional and section headers. */
+    poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
+    psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
+
+    /* Must be 0 thru (NumberOfRvaAndSizes-1). */
+    if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
+        return NULL;
+
+    /* Locate image directory's relative virtual address. */
+    VAImageDir = (LPVOID)poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress;
+
+    /* Locate section containing image directory. */
+    while (i++<nSections)
+    {
+        if (psh->VirtualAddress <= (DWORD)VAImageDir
+         && psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImageDir)
+            break;
+        psh++;
+    }
+
+    if (i > nSections)
+        return NULL;
+
+    /* Return image import directory offset. */
+    return (LPVOID)(((int)lpFile +
+                     (int)VAImageDir - psh->VirtualAddress) +
+                    (int)psh->PointerToRawData);
+}
+
+/* -------------------------------------------------------------- */
+
+BOOL WINAPI GetSectionHdrByName (
+    LPVOID lpFile,
+    IMAGE_SECTION_HEADER *sh,
+    char *szSection)
+{
+    PIMAGE_SECTION_HEADER psh;
+    int nSections = NumOfSections (lpFile);
+    int i;
+
+    if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) != NULL)
+    {
+        /* find the section by name */
+        for (i=0; i<nSections; i++)
+        {
+            if (!strcmp (psh->Name, szSection))
+            {
+                /* copy data to header */
+                memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER));
+                return TRUE;
+            }
+            else
+                psh++;
+        }
+    }
+    return FALSE;
+}
+
+/* -------------------------------------------------------------- */
+
+BOOL WINAPI GetSectionHdrByAddress (
+    LPVOID lpFile,
+    IMAGE_SECTION_HEADER *sh,
+    DWORD addr)
+{
+    PIMAGE_SECTION_HEADER psh;
+    int nSections = NumOfSections (lpFile);
+    int i;
+
+    if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) != NULL)
+    {
+        /* find the section by name */
+        for (i=0; i<nSections; i++)
+        {
+            if (addr >= psh->VirtualAddress
+             && addr < psh->VirtualAddress + psh->SizeOfRawData)
+            {
+                /* copy data to header */
+                memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER));
+                return TRUE;
+            }
+            else
+                psh++;
+        }
+    }
+    return FALSE;
+}
+
+/* -------------------------------------------------------------- */
+
+int  WINAPI GetExportFunctionNames (
+    LPVOID lpFile,
+    HANDLE hHeap,
+    char **pszFunctions)
+{
+    IMAGE_SECTION_HEADER sh;
+    PIMAGE_EXPORT_DIRECTORY ped;
+    int *pNames, *pCnt;
+    char *pSrc, *pDest;
+    int i, nCnt;
+    DWORD VAImageDir;
+    PIMAGE_OPTIONAL_HEADER poh;
+    char *pOffset;
+
+    /* Get section header and pointer to data directory
+       for .edata section. */
+    if (NULL == (ped = (PIMAGE_EXPORT_DIRECTORY)
+        ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT)))
+        return 0;
+
+    poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
+    VAImageDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+
+    if (FALSE == GetSectionHdrByAddress (lpFile, &sh, VAImageDir))
+        return 0;
+
+    pOffset = (char *)lpFile + (sh.PointerToRawData -  sh.VirtualAddress);
+
+    pNames = (int *)(pOffset + (DWORD)ped->AddressOfNames);
+
+    /* Figure out how much memory to allocate for all strings. */
+    nCnt = 1;
+    for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
+    {
+        pSrc = (pOffset + *pCnt++);
+        if (pSrc)
+            nCnt += strlen(pSrc)+1;
+    }
+
+    /* Allocate memory off heap for function names. */
+    pDest = *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
+
+    /* Copy all strings to buffer. */
+    for (i=0, pCnt = pNames; i<(int)ped->NumberOfNames; i++)
+    {
+        pSrc = (pOffset + *pCnt++);
+        if (pSrc) {
+            strcpy(pDest, pSrc);
+            pDest += strlen(pSrc)+1;
+        }
+    }
+    *pDest = 0;
+
+    return ped->NumberOfNames;
+}
+
+/* -------------------------------------------------------------- */
+/* extract the basename of a file */
+
+static char *file_basename(const char *name)
+{
+    const char *p = strchr(name, 0);
+    while (p > name
+        && p[-1] != '/'
+        && p[-1] != '\\'
+        )
+        --p;
+    return (char*)p;
+}
+
+/* -------------------------------------------------------------- */
+
+int main(int argc, char **argv)
+{
+    HANDLE hHeap;
+    HANDLE hFile;
+    HANDLE hMapObject;
+    VOID *pMem;
+
+    int nCnt, ret, n;
+    char *pNames;
+    char infile[MAX_PATH];
+    char buffer[MAX_PATH];
+    char outfile[MAX_PATH];
+    FILE *op;
+    char *p;
+
+    hHeap = NULL;
+    hFile = NULL;
+    hMapObject = NULL;
+    pMem = NULL;
+    infile[0] = 0;
+    outfile[0] = 0;
+    ret = 1;
+
+    for (n = 1; n < argc; ++n)
+    {
+        const char *a = argv[n];
+        if ('-' == a[0]) {
+            if (0 == strcmp(a, "-o")) {
+                if (++n == argc)
+                    goto usage;
+                strcpy(outfile, argv[n]);
+            }
+            else
+                goto usage;
+
+        } else if (0 == infile[0])
+            strcpy(infile, a);
+        else
+            goto usage;
+    }
+
+    if (0 == infile[0])
+    {
+usage:
+        fprintf(stderr,
+            "tiny_impdef creates an export definition file (.def) from a dll\n"
+            "Usage: tiny_impdef library.dll [-o outputfile]\n"
+            );
+        goto the_end;
+    }
+
+    if (SearchPath(NULL, infile, ".dll", sizeof buffer, buffer, NULL))
+        strcpy(infile, buffer);
+
+    if (0 == outfile[0])
+    {
+        char *p;
+        strcpy(outfile, file_basename(infile));
+        p = strrchr(outfile, '.');
+        if (NULL == p)
+            p = strchr(outfile, 0);
+        strcpy(p, ".def");
+    }
+
+    hFile = CreateFile(
+        infile,
+        GENERIC_READ,
+        FILE_SHARE_READ,
+        NULL,
+        OPEN_EXISTING,
+        0,
+        NULL
+        );
+
+    if (hFile == INVALID_HANDLE_VALUE)
+    {
+        fprintf(stderr, "No such file: %s\n", infile);
+        goto the_end;
+    }
+
+
+    hMapObject = CreateFileMapping(
+        hFile,
+        NULL,
+        PAGE_READONLY,
+        0, 0,
+        NULL
+        );
+
+    if (NULL == hMapObject)
+    {
+        fprintf(stderr, "Could not create file mapping: %s\n", infile);
+        goto the_end;
+    }
+
+    pMem = MapViewOfFile(
+        hMapObject,     // object to map view of
+        FILE_MAP_READ,  // read access
+        0,              // high offset:  map from
+        0,              // low offset:   beginning
+        0);             // default: map entire file
+
+    if (NULL == pMem)
+    {
+        fprintf(stderr, "Could not map view of file: %s\n", infile);
+        goto the_end;
+    }
+
+    if (0 != strncmp(NTSIGNATURE(pMem), "PE", 2))
+    {
+        fprintf(stderr, "Not a PE file: %s\n", infile);
+        goto the_end;
+    }
+
+
+    hHeap = GetProcessHeap();
+    nCnt = GetExportFunctionNames(pMem, hHeap, &pNames);
+    if (0 == nCnt) {
+        fprintf(stderr, "Could not get exported function names: %s\n", infile);
+        goto the_end;
+    }
+
+    printf("--> %s\n", infile);
+
+    op = fopen(outfile, "w");
+    if (NULL == op)
+    {
+        fprintf(stderr, "Could not create file: %s\n", outfile);
+        goto the_end;
+    }
+
+    printf("<-- %s\n", outfile);
+
+    fprintf(op, "LIBRARY %s\n\nEXPORTS\n", file_basename(infile));
+    for (n = 0, p = pNames; n < nCnt; ++n)
+    {
+        fprintf(op, "%s\n", p);
+        while (*p++);
+    }
+    ret = 0;
+
+the_end:
+    if (pMem)
+        UnmapViewOfFile(pMem);
+
+    if (hMapObject)
+        CloseHandle(hMapObject);
+
+    if (hFile)
+        CloseHandle(hFile);
+
+    return ret;
+}
+
+/* -------------------------------------------------------------- */
diff --git a/tinyc/win32/tools/tiny_libmaker.c b/tinyc/win32/tools/tiny_libmaker.c
new file mode 100755
index 000000000..cf9ac67bc
--- /dev/null
+++ b/tinyc/win32/tools/tiny_libmaker.c
@@ -0,0 +1,310 @@
+/*
+ * This program is for making libtcc1.a without ar
+ * tiny_libmaker - tiny elf lib maker
+ * usage: tiny_libmaker [lib] files...
+ * Copyright (c) 2007 Timppa
+ *
+ * This program is free software but WITHOUT ANY WARRANTY
+ */ 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <io.h> /* for mktemp */
+#endif
+
+/* #include "ar-elf.h" */
+/*  "ar-elf.h" */
+/* ELF_v1.2.pdf */
+typedef unsigned short int Elf32_Half;
+typedef int Elf32_Sword;
+typedef unsigned int Elf32_Word;
+typedef unsigned int Elf32_Addr;
+typedef unsigned int Elf32_Off;
+typedef unsigned short int Elf32_Section;
+
+#define EI_NIDENT 16
+typedef struct {
+    unsigned char e_ident[EI_NIDENT];
+    Elf32_Half e_type;
+    Elf32_Half e_machine;
+    Elf32_Word e_version;
+    Elf32_Addr e_entry;
+    Elf32_Off e_phoff;
+    Elf32_Off e_shoff;
+    Elf32_Word e_flags;
+    Elf32_Half e_ehsize;
+    Elf32_Half e_phentsize;
+    Elf32_Half e_phnum;
+    Elf32_Half e_shentsize;
+    Elf32_Half e_shnum;
+    Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+    Elf32_Word sh_name;
+    Elf32_Word sh_type;
+    Elf32_Word sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off sh_offset;
+    Elf32_Word sh_size;
+    Elf32_Word sh_link;
+    Elf32_Word sh_info;
+    Elf32_Word sh_addralign;
+    Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+
+typedef struct {
+    Elf32_Word st_name;
+    Elf32_Addr st_value;
+    Elf32_Word st_size;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf32_Half st_shndx;
+} Elf32_Sym;
+
+#define ELF32_ST_BIND(i) ((i)>>4)
+#define ELF32_ST_TYPE(i) ((i)&0xf)
+#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+#define STB_LOPROC 13
+#define STB_HIPROC 15
+
+typedef struct {
+    Elf32_Word p_type;
+    Elf32_Off p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf32_Word p_filesz;
+    Elf32_Word p_memsz;
+    Elf32_Word p_flags;
+    Elf32_Word p_align;
+} Elf32_Phdr;
+/* "ar-elf.h" ends */
+
+#define ARMAG  "!<arch>\n"
+#define ARFMAG "`\n"
+
+typedef struct ArHdr {
+    char ar_name[16];
+    char ar_date[12];
+    char ar_uid[6];
+    char ar_gid[6];
+    char ar_mode[8];
+    char ar_size[10];
+    char ar_fmag[2];
+} ArHdr;
+
+
+unsigned long le2belong(unsigned long ul) {
+    return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
+        ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
+}
+
+ArHdr arhdr = {
+    "/               ",
+    "            ",
+    "0     ",
+    "0     ",
+    "0       ",
+    "          ",
+    ARFMAG
+    };
+
+ArHdr arhdro = {
+    "                ",
+    "            ",
+    "0     ",
+    "0     ",
+    "0       ",
+    "          ",
+    ARFMAG
+    };
+
+int main(int argc, char **argv)
+{
+    FILE *fi, *fh, *fo;
+    Elf32_Ehdr *ehdr;
+    Elf32_Shdr *shdr;
+    Elf32_Sym *sym;
+    int i, fsize, iarg;
+    char *buf, *shstr, *symtab = NULL, *strtab = NULL;
+    int symtabsize = 0, strtabsize = 0;
+    char *anames = NULL;
+    int *afpos = NULL;
+    int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
+    char afile[260], tfile[260], stmp[20];
+
+
+    strcpy(afile, "ar_test.a");
+    iarg = 1;
+
+    if (argc < 2)
+    {
+        printf("usage: tiny_libmaker [lib] file...\n");
+        return 1;
+    }
+    for (i=1; i<argc; i++) {
+        istrlen = strlen(argv[i]);
+        if (argv[i][istrlen-2] == '.') {
+            if(argv[i][istrlen-1] == 'a')
+                strcpy(afile, argv[i]);
+            else if(argv[i][istrlen-1] == 'o') {
+                iarg = i;
+                break;
+            }
+        }
+    }
+
+    strcpy(tfile, "./XXXXXX");
+    if (!mktemp(tfile) || (fo = fopen(tfile, "wb+")) == NULL)
+    {
+        fprintf(stderr, "Can't open temporary file %s\n", tfile);
+        return 2;
+    }
+
+    if ((fh = fopen(afile, "wb")) == NULL)
+    {
+        fprintf(stderr, "Can't open file %s \n", afile);
+        remove(tfile);
+        return 2;
+    }
+
+    funcmax = 250;
+    afpos = realloc(NULL, funcmax * sizeof *afpos); // 250 func
+    memcpy(&arhdro.ar_mode, "100666", 6);
+
+    //iarg = 1;
+    while (iarg < argc)
+    {
+        if (!strcmp(argv[iarg], "rcs")) {
+            iarg++;
+            continue;
+        }
+        if ((fi = fopen(argv[iarg], "rb")) == NULL)
+        {
+            fprintf(stderr, "Can't open  file %s \n", argv[iarg]);
+            remove(tfile);
+            return 2;
+        }
+        fseek(fi, 0, SEEK_END);
+        fsize = ftell(fi);
+        fseek(fi, 0, SEEK_SET);
+        buf = malloc(fsize + 1);
+        fread(buf, fsize, 1, fi);
+        fclose(fi);
+
+        printf("%s:\n", argv[iarg]);
+        // elf header
+        ehdr = (Elf32_Ehdr *)buf;
+        shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
+        shstr = (char *)(buf + shdr->sh_offset);
+        for (i = 0; i < ehdr->e_shnum; i++)
+        {
+            shdr = (Elf32_Shdr *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
+            if (!shdr->sh_offset) continue;
+            if (shdr->sh_type == SHT_SYMTAB)
+            {
+                symtab = (char *)(buf + shdr->sh_offset);
+                symtabsize = shdr->sh_size;
+            }
+            if (shdr->sh_type == SHT_STRTAB)
+            {
+                if (!strcmp(shstr + shdr->sh_name, ".strtab"))
+                {
+                    strtab = (char *)(buf + shdr->sh_offset);
+                    strtabsize = shdr->sh_size;
+                }
+            }
+        }
+
+        if (symtab && symtabsize)
+        {
+            int nsym = symtabsize / sizeof(Elf32_Sym);
+            //printf("symtab: info size shndx name\n");
+            for (i = 1; i < nsym; i++)
+            {
+                sym = (Elf32_Sym *) (symtab + i * sizeof(Elf32_Sym));
+                if (sym->st_shndx && (sym->st_info == 0x11 || sym->st_info == 0x12)) {
+                    //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
+                    istrlen = strlen(strtab + sym->st_name)+1;
+                    anames = realloc(anames, strpos+istrlen);
+                    strcpy(anames + strpos, strtab + sym->st_name);
+                    strpos += istrlen;
+                    if (++funccnt >= funcmax) {
+                        funcmax += 250;
+                        afpos = realloc(afpos, funcmax * sizeof *afpos); // 250 func more
+                    }
+                    afpos[funccnt] = fpos;
+                }
+            }
+        }
+        memset(&arhdro.ar_name, ' ', sizeof(arhdr.ar_name));
+        strcpy(arhdro.ar_name, argv[iarg]);
+        arhdro.ar_name[strlen(argv[iarg])] = '/';
+        sprintf(stmp, "%-10d", fsize);
+        memcpy(&arhdro.ar_size, stmp, 10);
+        fwrite(&arhdro, sizeof(arhdro), 1, fo);
+        fwrite(buf, fsize, 1, fo);
+        free(buf);
+        iarg++;
+        fpos += (fsize + sizeof(arhdro));
+    }
+    hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
+    if ((hofs & 1)) {   // align
+        hofs++;
+        fpos = 1;
+    } else fpos = 0;
+    // write header
+    fwrite("!<arch>\n", 8, 1, fh);
+    sprintf(stmp, "%-10d", strpos + (funccnt+1) * sizeof(int));
+    memcpy(&arhdr.ar_size, stmp, 10);
+    fwrite(&arhdr, sizeof(arhdr), 1, fh);
+    afpos[0] = le2belong(funccnt);
+    for (i=1; i<=funccnt; i++) {
+        afpos[i] = le2belong(afpos[i] + hofs);
+    }
+    fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
+    fwrite(anames, strpos, 1, fh);
+    if (fpos) fwrite("", 1, 1, fh);
+    // write objects
+    fseek(fo, 0, SEEK_END);
+    fsize = ftell(fo);
+    fseek(fo, 0, SEEK_SET);
+    buf = malloc(fsize + 1);
+    fread(buf, fsize, 1, fo);
+    fclose(fo);
+    fwrite(buf, fsize, 1, fh);
+    fclose(fh);
+    free(buf);
+    if (anames)
+        free(anames);
+    if (afpos)
+        free(afpos);
+    remove(tfile);
+    return 0;
+}
diff --git a/tinyc/x86_64-gen.c b/tinyc/x86_64-gen.c
new file mode 100755
index 000000000..1227f41f0
--- /dev/null
+++ b/tinyc/x86_64-gen.c
@@ -0,0 +1,1419 @@
+/*
+ *  x86-64 code generator for TCC
+ *
+ *  Copyright (c) 2008 Shinichiro Hamaji
+ *
+ *  Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <assert.h>
+
+/* number of available registers */
+#define NB_REGS             5
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_RAX     0x0004
+#define RC_RCX     0x0008
+#define RC_RDX     0x0010
+#define RC_XMM0    0x0020
+#define RC_ST0     0x0040 /* only for long double */
+#define RC_IRET    RC_RAX /* function return: integer register */
+#define RC_LRET    RC_RDX /* function return: second integer register */
+#define RC_FRET    RC_XMM0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_RAX = 0,
+    TREG_RCX = 1,
+    TREG_RDX = 2,
+    TREG_RSI = 6,
+    TREG_RDI = 7,
+    TREG_R8  = 8,
+    TREG_R9  = 9,
+    TREG_R10 = 10,
+    TREG_R11 = 11,
+
+    TREG_XMM0 = 3,
+    TREG_ST0 = 4,
+
+    TREG_MEM = 0x10,
+};
+
+#define REX_BASE(reg) (((reg) >> 3) & 1)
+#define REG_VALUE(reg) ((reg) & 7)
+
+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) */
+#define REG_FRET TREG_XMM0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* pointer size, in bytes */
+#define PTR_SIZE 8
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  16
+#define LDOUBLE_ALIGN 8
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+/******************************************************/
+/* ELF defines */
+
+#define EM_TCC_TARGET EM_X86_64
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_X86_64_64
+#define R_JMP_SLOT  R_X86_64_JUMP_SLOT
+#define R_COPY      R_X86_64_COPY
+
+#define ELF_START_ADDR 0x08048000
+#define ELF_PAGE_SIZE  0x1000
+
+/******************************************************/
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+/* XXX: make it faster ? */
+void g(int c)
+{
+    int ind1;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+void o(unsigned int c)
+{
+    while (c) {
+        g(c);
+        c = c >> 8;
+    }
+}
+
+void gen_le32(int c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+}
+
+void gen_le64(int64_t c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+    g(c >> 32);
+    g(c >> 40);
+    g(c >> 48);
+    g(c >> 56);
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+    int n, *ptr;
+    while (t) {
+        ptr = (int *)(cur_text_section->data + t);
+        n = *ptr; /* next value */
+        *ptr = a - t - 4;
+        t = n;
+    }
+}
+
+void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+/* psym is used to put an instruction with a data field which is a
+   reference to a symbol. It is in fact the same as oad ! */
+#define psym oad
+
+static int is64_type(int t)
+{
+    return ((t & VT_BTYPE) == VT_PTR ||
+            (t & VT_BTYPE) == VT_FUNC ||
+            (t & VT_BTYPE) == VT_LLONG);
+}
+
+static int is_sse_float(int t) {
+    int bt;
+    bt = t & VT_BTYPE;
+    return bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+    int ind1;
+
+    o(c);
+    ind1 = ind + 4;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    *(int *)(cur_text_section->data + ind) = s;
+    s = ind;
+    ind = ind1;
+    return s;
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+static void gen_addr64(int r, Sym *sym, int64_t c)
+{
+    if (r & VT_SYM)
+        greloc(cur_text_section, sym, ind, R_X86_64_64);
+    gen_le64(c);
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+static void gen_addrpc32(int r, Sym *sym, int c)
+{
+    if (r & VT_SYM)
+        greloc(cur_text_section, sym, ind, R_X86_64_PC32);
+    gen_le32(c-4);
+}
+
+/* output got address with relocation */
+static void gen_gotpcrel(int r, Sym *sym, int c)
+{
+    Section *sr;
+    ElfW(Rela) *rel;
+    greloc(cur_text_section, sym, ind, R_X86_64_GOTPCREL);
+    sr = cur_text_section->reloc;
+    rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela)));
+    rel->r_addend = -4;
+    gen_le32(0);
+
+    if (c) {
+        /* we use add c, %xxx for displacement */
+        o(0x48 + REX_BASE(r));
+        o(0x81);
+        o(0xc0 + REG_VALUE(r));
+        gen_le32(c);
+    }
+}
+
+static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got)
+{
+    op_reg = REG_VALUE(op_reg) << 3;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        /* constant memory reference */
+        o(0x05 | op_reg);
+        if (is_got) {
+            gen_gotpcrel(r, sym, c);
+        } else {
+            gen_addrpc32(r, sym, c);
+        }
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+        /* currently, we use only ebp as base */
+        if (c == (char)c) {
+            /* short reference */
+            o(0x45 | op_reg);
+            g(c);
+        } else {
+            oad(0x85 | op_reg, c);
+        }
+    } else if ((r & VT_VALMASK) >= TREG_MEM) {
+        if (c) {
+            g(0x80 | op_reg | REG_VALUE(r));
+            gen_le32(c);
+        } else {
+            g(0x00 | op_reg | REG_VALUE(r));
+        }
+    } else {
+        g(0x00 | op_reg | (r & VT_VALMASK));
+    }
+}
+
+/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+   opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+    gen_modrm_impl(op_reg, r, sym, c, 0);
+}
+
+/* generate a modrm reference. 'op_reg' contains the addtionnal 3
+   opcode bits */
+static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c)
+{
+    int is_got;
+    int rex = 0x48 | (REX_BASE(op_reg) << 2);
+    if ((r & VT_VALMASK) != VT_CONST &&
+        (r & VT_VALMASK) != VT_LOCAL) {
+        rex |= REX_BASE(VT_VALMASK & r);
+    }
+    o(rex);
+    o(opcode);
+    is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC);
+    gen_modrm_impl(op_reg, r, sym, c, is_got);
+}
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+    int v, t, ft, fc, fr;
+    SValue v1;
+
+    fr = sv->r;
+    ft = sv->type.t;
+    fc = sv->c.ul;
+
+    /* we use indirect access via got */
+    if ((fr & VT_VALMASK) == VT_CONST && (fr & VT_SYM) &&
+        (fr & VT_LVAL) && !(sv->sym->type.t & VT_STATIC)) {
+        /* use the result register as a temporal register */
+        int tr = r | TREG_MEM;
+        if (is_float(ft)) {
+            /* we cannot use float registers as a temporal register */
+            tr = get_reg(RC_INT) | TREG_MEM;
+        }
+        gen_modrm64(0x8b, tr, fr, sv->sym, 0);
+
+        /* load from the temporal register */
+        fr = tr | VT_LVAL;
+    }
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+        if (v == VT_LLOCAL) {
+            v1.type.t = VT_PTR;
+            v1.r = VT_LOCAL | VT_LVAL;
+            v1.c.ul = fc;
+            load(r, &v1);
+            fr = r;
+        }
+        if ((ft & VT_BTYPE) == VT_FLOAT) {
+            o(0x6e0f66); /* movd */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+            o(0x7e0ff3); /* movq */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            o(0xdb); /* fldt */
+            r = 5;
+        } else if ((ft & VT_TYPE) == VT_BYTE) {
+            o(0xbe0f);   /* movsbl */
+        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+            o(0xb60f);   /* movzbl */
+        } else if ((ft & VT_TYPE) == VT_SHORT) {
+            o(0xbf0f);   /* movswl */
+        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+            o(0xb70f);   /* movzwl */
+        } else if (is64_type(ft)) {
+            gen_modrm64(0x8b, r, fr, sv->sym, fc);
+            return;
+        } else {
+            o(0x8b);   /* movl */
+        }
+        gen_modrm(r, fr, sv->sym, fc);
+    } else {
+        if (v == VT_CONST) {
+            if ((ft & VT_BTYPE) == VT_LLONG) {
+                assert(!(fr & VT_SYM));
+                o(0x48);
+                o(0xb8 + REG_VALUE(r)); /* mov $xx, r */
+                gen_addr64(fr, sv->sym, sv->c.ull);
+            } else {
+                if (fr & VT_SYM) {
+                    if (sv->sym->type.t & VT_STATIC) {
+                        o(0x8d48);
+                        o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
+                        gen_addrpc32(fr, sv->sym, fc);
+                    } else {
+                        o(0x8b48);
+                        o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
+                        gen_gotpcrel(r, sv->sym, fc);
+                    }
+                } else {
+                    o(0xb8 + REG_VALUE(r)); /* mov $xx, r */
+                    gen_le32(fc);
+                }
+            }
+        } else if (v == VT_LOCAL) {
+            o(0x48 | REX_BASE(r));
+            o(0x8d); /* lea xxx(%ebp), r */
+            gen_modrm(r, VT_LOCAL, sv->sym, fc);
+        } else if (v == VT_CMP) {
+            oad(0xb8 + r, 0); /* mov $0, r */
+            o(0x0f); /* setxx %br */
+            o(fc);
+            o(0xc0 + r);
+        } else if (v == VT_JMP || v == VT_JMPI) {
+            t = v & 1;
+            oad(0xb8 + r, t); /* mov $1, r */
+            o(0x05eb); /* jmp after */
+            gsym(fc);
+            oad(0xb8 + r, t ^ 1); /* mov $0, r */
+        } else if (v != r) {
+            if (r == TREG_XMM0) {
+                assert(v == TREG_ST0);
+                /* gen_cvt_ftof(VT_DOUBLE); */
+                o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+                /* movsd -0x10(%rsp),%xmm0 */
+                o(0x44100ff2);
+                o(0xf024);
+            } else if (r == TREG_ST0) {
+                assert(v == TREG_XMM0);
+                /* gen_cvt_ftof(VT_LDOUBLE); */
+                /* movsd %xmm0,-0x10(%rsp) */
+                o(0x44110ff2);
+                o(0xf024);
+                o(0xf02444dd); /* fldl -0x10(%rsp) */
+            } else {
+                o(0x48 | REX_BASE(r) | (REX_BASE(v) << 2));
+                o(0x89);
+                o(0xc0 + r + v * 8); /* mov v, r */
+            }
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *v)
+{
+    int fr, bt, ft, fc;
+    int op64 = 0;
+    /* store the REX prefix in this variable when PIC is enabled */
+    int pic = 0;
+
+    ft = v->type.t;
+    fc = v->c.ul;
+    fr = v->r & VT_VALMASK;
+    bt = ft & VT_BTYPE;
+
+    /* we need to access the variable via got */
+    if (fr == VT_CONST && (v->r & VT_SYM)) {
+        /* mov xx(%rip), %r11 */
+        o(0x1d8b4c);
+        gen_gotpcrel(TREG_R11, v->sym, v->c.ul);
+        pic = is64_type(bt) ? 0x49 : 0x41;
+    }
+
+    /* XXX: incorrect if float reg to reg */
+    if (bt == VT_FLOAT) {
+        o(0x66);
+        o(pic);
+        o(0x7e0f); /* movd */
+        r = 0;
+    } else if (bt == VT_DOUBLE) {
+        o(0x66);
+        o(pic);
+        o(0xd60f); /* movq */
+        r = 0;
+    } else if (bt == VT_LDOUBLE) {
+        o(0xc0d9); /* fld %st(0) */
+        o(pic);
+        o(0xdb); /* fstpt */
+        r = 7;
+    } else {
+        if (bt == VT_SHORT)
+            o(0x66);
+        o(pic);
+        if (bt == VT_BYTE || bt == VT_BOOL)
+            o(0x88);
+        else if (is64_type(bt))
+            op64 = 0x89;
+        else
+            o(0x89);
+    }
+    if (pic) {
+        /* xxx r, (%r11) where xxx is mov, movq, fld, or etc */
+        if (op64)
+            o(op64);
+        o(3 + (r << 3));
+    } else if (op64) {
+        if (fr == VT_CONST ||
+            fr == VT_LOCAL ||
+            (v->r & VT_LVAL)) {
+            gen_modrm64(op64, r, v->r, v->sym, fc);
+        } else if (fr != r) {
+            /* XXX: don't we really come here? */
+            abort();
+            o(0xc0 + fr + r * 8); /* mov r, fr */
+        }
+    } else {
+        if (fr == VT_CONST ||
+            fr == VT_LOCAL ||
+            (v->r & VT_LVAL)) {
+            gen_modrm(r, v->r, v->sym, fc);
+        } else if (fr != r) {
+            /* XXX: don't we really come here? */
+            abort();
+            o(0xc0 + fr + r * 8); /* mov r, fr */
+        }
+    }
+}
+
+static void gadd_sp(int val)
+{
+    if (val == (char)val) {
+        o(0xc48348);
+        g(val);
+    } else {
+        oad(0xc48148, val); /* add $xxx, %rsp */
+    }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        /* constant case */
+        if (vtop->r & VT_SYM) {
+            /* relocation case */
+            greloc(cur_text_section, vtop->sym,
+                   ind + 1, R_X86_64_PC32);
+        } else {
+            /* put an empty PC32 relocation */
+            put_elf_reloc(symtab_section, cur_text_section,
+                          ind + 1, R_X86_64_PC32, 0);
+        }
+        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
+    } else {
+        /* otherwise, indirect call */
+        r = TREG_R11;
+        load(r, vtop);
+        o(0x41); /* REX */
+        o(0xff); /* call/jmp *r */
+        o(0xd0 + REG_VALUE(r) + (is_jmp << 4));
+    }
+}
+
+static uint8_t arg_regs[6] = {
+    TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9
+};
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+    int size, align, r, args_size, i, func_call;
+    Sym *func_sym;
+    SValue *orig_vtop;
+    int nb_reg_args = 0;
+    int nb_sse_args = 0;
+    int sse_reg, gen_reg;
+
+    /* calculate the number of integer/float arguments */
+    args_size = 0;
+    for(i = 0; i < nb_args; i++) {
+        if ((vtop[-i].type.t & VT_BTYPE) == VT_STRUCT) {
+            args_size += type_size(&vtop->type, &align);
+        } else if ((vtop[-i].type.t & VT_BTYPE) == VT_LDOUBLE) {
+            args_size += 16;
+        } else if (is_sse_float(vtop[-i].type.t)) {
+            nb_sse_args++;
+            if (nb_sse_args > 8) args_size += 8;
+        } else {
+            nb_reg_args++;
+            if (nb_reg_args > 6) args_size += 8;
+        }
+    }
+
+    /* for struct arguments, we need to call memcpy and the function
+       call breaks register passing arguments we are preparing.
+       So, we process arguments which will be passed by stack first. */
+    orig_vtop = vtop;
+    gen_reg = nb_reg_args;
+    sse_reg = nb_sse_args;
+    /* adjust stack to align SSE boundary */
+    if (args_size &= 8) {
+        o(0x50); /* push $rax */
+    }
+    for(i = 0; i < nb_args; i++) {
+        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+            size = type_size(&vtop->type, &align);
+            /* align to stack align size */
+            size = (size + 3) & ~3;
+            /* allocate the necessary size on stack */
+            o(0x48);
+            oad(0xec81, size); /* sub $xxx, %rsp */
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            o(0x48 + REX_BASE(r));
+            o(0x89); /* mov %rsp, r */
+            o(0xe0 + r);
+            {
+                /* following code breaks vtop[1] */
+                SValue tmp = vtop[1];
+                vset(&vtop->type, r | VT_LVAL, 0);
+                vswap();
+                vstore();
+                vtop[1] = tmp;
+            }
+            args_size += size;
+        } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+            gv(RC_ST0);
+            size = LDOUBLE_SIZE;
+            oad(0xec8148, size); /* sub $xxx, %rsp */
+            o(0x7cdb); /* fstpt 0(%rsp) */
+            g(0x24);
+            g(0x00);
+            args_size += size;
+        } else if (is_sse_float(vtop->type.t)) {
+            int j = --sse_reg;
+            if (j >= 8) {
+                gv(RC_FLOAT);
+                o(0x50); /* push $rax */
+                /* movq %xmm0, (%rsp) */
+                o(0x04d60f66);
+                o(0x24);
+                args_size += 8;
+            }
+        } else {
+            int j = --gen_reg;
+            /* simple type */
+            /* XXX: implicit cast ? */
+            if (j >= 6) {
+                r = gv(RC_INT);
+                o(0x50 + r); /* push r */
+                args_size += 8;
+            }
+        }
+        vtop--;
+    }
+    vtop = orig_vtop;
+
+    /* then, we prepare register passing arguments.
+       Note that we cannot set RDX and RCX in this loop because gv()
+       may break these temporary registers. Let's use R10 and R11
+       instead of them */
+    gen_reg = nb_reg_args;
+    sse_reg = nb_sse_args;
+    for(i = 0; i < nb_args; i++) {
+        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT ||
+            (vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+        } else if (is_sse_float(vtop->type.t)) {
+            int j = --sse_reg;
+            if (j < 8) {
+                gv(RC_FLOAT); /* only one float register */
+                /* movaps %xmm0, %xmmN */
+                o(0x280f);
+                o(0xc0 + (sse_reg << 3));
+            }
+        } else {
+            int j = --gen_reg;
+            /* simple type */
+            /* XXX: implicit cast ? */
+            if (j < 6) {
+                r = gv(RC_INT);
+                if (j < 2) {
+                    o(0x8948); /* mov */
+                    o(0xc0 + r * 8 + arg_regs[j]);
+                } else if (j < 4) {
+                    o(0x8949); /* mov */
+                    /* j=2: r10, j=3: r11 */
+                    o(0xc0 + r * 8 + j);
+                } else {
+                    o(0x8949); /* mov */
+                    /* j=4: r8, j=5: r9 */
+                    o(0xc0 + r * 8 + j - 4);
+                }
+            }
+        }
+        vtop--;
+    }
+
+    save_regs(0); /* save used temporary registers */
+
+    /* Copy R10 and R11 into RDX and RCX, respectively */
+    if (nb_reg_args > 2) {
+        o(0xd2894c); /* mov %r10, %rdx */
+        if (nb_reg_args > 3) {
+            o(0xd9894c); /* mov %r11, %rcx */
+        }
+    }
+
+    func_sym = vtop->type.ref;
+    func_call = FUNC_CALL(func_sym->r);
+    oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
+    gcall_or_jmp(0);
+    if (args_size)
+        gadd_sp(args_size);
+    vtop--;
+}
+
+#ifdef TCC_TARGET_PE
+/* XXX: support PE? */
+#warning "PE isn't tested at all"
+#define FUNC_PROLOG_SIZE 12
+#else
+#define FUNC_PROLOG_SIZE 11
+#endif
+
+static void push_arg_reg(int i) {
+    loc -= 8;
+    gen_modrm64(0x89, arg_regs[i], VT_LOCAL, NULL, loc);
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+    int i, addr, align, size, func_call;
+    int param_index, param_addr, reg_param_index, sse_param_index;
+    Sym *sym;
+    CType *type;
+
+    func_ret_sub = 0;
+
+    sym = func_type->ref;
+    func_call = FUNC_CALL(sym->r);
+    addr = PTR_SIZE * 2;
+    loc = 0;
+    ind += FUNC_PROLOG_SIZE;
+    func_sub_sp_offset = ind;
+
+    if (func_type->ref->c == FUNC_ELLIPSIS) {
+        int seen_reg_num, seen_sse_num, seen_stack_size;
+        seen_reg_num = seen_sse_num = 0;
+        /* frame pointer and return address */
+        seen_stack_size = PTR_SIZE * 2;
+        /* count the number of seen parameters */
+        sym = func_type->ref;
+        while ((sym = sym->next) != NULL) {
+            type = &sym->type;
+            if (is_sse_float(type->t)) {
+                if (seen_sse_num < 8) {
+                    seen_sse_num++;
+                } else {
+                    seen_stack_size += 8;
+                }
+            } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+                size = type_size(type, &align);
+                size = (size + 3) & ~3;
+                seen_stack_size += size;
+            } else if ((type->t & VT_BTYPE) == VT_LDOUBLE) {
+                seen_stack_size += LDOUBLE_SIZE;
+            } else {
+                if (seen_reg_num < 6) {
+                    seen_reg_num++;
+                } else {
+                    seen_stack_size += 8;
+                }
+            }
+        }
+
+        loc -= 16;
+        /* movl $0x????????, -0x10(%rbp) */
+        o(0xf045c7);
+        gen_le32(seen_reg_num * 8);
+        /* movl $0x????????, -0xc(%rbp) */
+        o(0xf445c7);
+        gen_le32(seen_sse_num * 16 + 48);
+        /* movl $0x????????, -0x8(%rbp) */
+        o(0xf845c7);
+        gen_le32(seen_stack_size);
+
+        /* save all register passing arguments */
+        for (i = 0; i < 8; i++) {
+            loc -= 16;
+            o(0xd60f66); /* movq */
+            gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+            /* movq $0, loc+8(%rbp) */
+            o(0x85c748);
+            gen_le32(loc + 8);
+            gen_le32(0);
+        }
+        for (i = 0; i < 6; i++) {
+            push_arg_reg(5 - i);
+        }
+    }
+
+    sym = func_type->ref;
+    param_index = 0;
+    reg_param_index = 0;
+    sse_param_index = 0;
+
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+        push_arg_reg(reg_param_index);
+        param_addr = loc;
+
+        func_vc = loc;
+        param_index++;
+        reg_param_index++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        type = &sym->type;
+        size = type_size(type, &align);
+        size = (size + 3) & ~3;
+        if (is_sse_float(type->t)) {
+            if (sse_param_index < 8) {
+                /* save arguments passed by register */
+                loc -= 8;
+                o(0xd60f66); /* movq */
+                gen_modrm(sse_param_index, VT_LOCAL, NULL, loc);
+                param_addr = loc;
+            } else {
+                param_addr = addr;
+                addr += size;
+            }
+            sse_param_index++;
+        } else if ((type->t & VT_BTYPE) == VT_STRUCT ||
+                   (type->t & VT_BTYPE) == VT_LDOUBLE) {
+            param_addr = addr;
+            addr += size;
+        } else {
+            if (reg_param_index < 6) {
+                /* save arguments passed by register */
+                push_arg_reg(reg_param_index);
+                param_addr = loc;
+            } else {
+                param_addr = addr;
+                addr += 8;
+            }
+            reg_param_index++;
+        }
+        sym_push(sym->v & ~SYM_FIELD, type,
+                 VT_LOCAL | VT_LVAL, param_addr);
+        param_index++;
+    }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    int v, saved_ind;
+
+    o(0xc9); /* leave */
+    if (func_ret_sub == 0) {
+        o(0xc3); /* ret */
+    } else {
+        o(0xc2); /* ret n */
+        g(func_ret_sub);
+        g(func_ret_sub >> 8);
+    }
+    /* align local size to word & save local variables */
+    v = (-loc + 15) & -16;
+    saved_ind = ind;
+    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+#ifdef TCC_TARGET_PE
+    if (v >= 4096) {
+        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
+        oad(0xb8, v); /* mov stacksize, %eax */
+        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
+        greloc(cur_text_section, sym, ind-4, R_X86_64_PC32);
+    } else
+#endif
+    {
+        o(0xe5894855);  /* push %rbp, mov %rsp, %rbp */
+        o(0xec8148);  /* sub rsp, stacksize */
+        gen_le32(v);
+#if FUNC_PROLOG_SIZE == 12
+        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
+#endif
+    }
+    ind = saved_ind;
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    return psym(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    int r;
+    r = a - ind - 2;
+    if (r == (char)r) {
+        g(0xeb);
+        g(r);
+    } else {
+        oad(0xe9, a - ind - 5);
+    }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int v, *p;
+
+    v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+        /* fast case : can jump directly since flags are set */
+        g(0x0f);
+        t = psym((vtop->c.i - 16) ^ inv, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            p = &vtop->c.i;
+            while (*p != 0)
+                p = (int *)(cur_text_section->data + *p);
+            *p = t;
+            t = vtop->c.i;
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    } else {
+        if (is_float(vtop->type.t) ||
+            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            vpushi(0);
+            gen_op(TOK_NE);
+        }
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant jmp optimization */
+            if ((vtop->c.i != 0) != inv)
+                t = gjmp(t);
+        } else {
+            v = gv(RC_INT);
+            o(0x85);
+            o(0xc0 + v * 9);
+            g(0x0f);
+            t = psym(0x85 ^ inv, t);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    int r, fr, opc, c;
+
+    switch(op) {
+    case '+':
+    case TOK_ADDC1: /* add with carry generation */
+        opc = 0;
+    gen_op8:
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST &&
+            !is64_type(vtop->type.t)) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            if (is64_type(vtop->type.t)) {
+                o(0x48 | REX_BASE(r));
+            }
+            vswap();
+            c = vtop->c.i;
+            if (c == (char)c) {
+                /* XXX: generate inc and dec for smaller code ? */
+                o(0x83);
+                o(0xc0 | (opc << 3) | REG_VALUE(r));
+                g(c);
+            } else {
+                o(0x81);
+                oad(0xc0 | (opc << 3) | REG_VALUE(r), c);
+            }
+        } else {
+            gv2(RC_INT, RC_INT);
+            r = vtop[-1].r;
+            fr = vtop[0].r;
+            if (opc != 7 ||
+                is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) ||
+                is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) {
+                o(0x48 | REX_BASE(r) | (REX_BASE(fr) << 2));
+            }
+            o((opc << 3) | 0x01);
+            o(0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8);
+        }
+        vtop--;
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        }
+        break;
+    case '-':
+    case TOK_SUBC1: /* sub with carry generation */
+        opc = 5;
+        goto gen_op8;
+    case TOK_ADDC2: /* add with carry use */
+        opc = 2;
+        goto gen_op8;
+    case TOK_SUBC2: /* sub with carry use */
+        opc = 3;
+        goto gen_op8;
+    case '&':
+        opc = 4;
+        goto gen_op8;
+    case '^':
+        opc = 6;
+        goto gen_op8;
+    case '|':
+        opc = 1;
+        goto gen_op8;
+    case '*':
+        gv2(RC_INT, RC_INT);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        if (is64_type(vtop[0].type.t) || (vtop[0].type.t & VT_UNSIGNED) ||
+            is64_type(vtop[-1].type.t) || (vtop[-1].type.t & VT_UNSIGNED)) {
+            o(0x48 | REX_BASE(fr) | (REX_BASE(r) << 2));
+        }
+        vtop--;
+        o(0xaf0f); /* imul fr, r */
+        o(0xc0 + fr + r * 8);
+        break;
+    case TOK_SHL:
+        opc = 4;
+        goto gen_shift;
+    case TOK_SHR:
+        opc = 5;
+        goto gen_shift;
+    case TOK_SAR:
+        opc = 7;
+    gen_shift:
+        opc = 0xc0 | (opc << 3);
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                o(0x48 | REX_BASE(r));
+                c = 0x3f;
+            } else {
+                c = 0x1f;
+            }
+            vswap();
+            c &= vtop->c.i;
+            o(0xc1); /* shl/shr/sar $xxx, r */
+            o(opc | r);
+            g(c);
+        } else {
+            /* we generate the shift in ecx */
+            gv2(RC_INT, RC_RCX);
+            r = vtop[-1].r;
+            if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG) {
+                o(0x48 | REX_BASE(r));
+            }
+            o(0xd3); /* shl/shr/sar %cl, r */
+            o(opc | r);
+        }
+        vtop--;
+        break;
+    case '/':
+    case TOK_UDIV:
+    case TOK_PDIV:
+    case '%':
+    case TOK_UMOD:
+    case TOK_UMULL:
+        /* first operand must be in eax */
+        /* XXX: need better constraint for second operand */
+        gv2(RC_RAX, RC_RCX);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        save_reg(TREG_RDX);
+        if (op == TOK_UMULL) {
+            o(0xf7); /* mul fr */
+            o(0xe0 + fr);
+            vtop->r2 = TREG_RDX;
+            r = TREG_RAX;
+        } else {
+            if (op == TOK_UDIV || op == TOK_UMOD) {
+                o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
+                o(0xf0 + fr);
+            } else {
+                if ((vtop->type.t & VT_BTYPE) & VT_LLONG) {
+                    o(0x9948); /* cqto */
+                    o(0x48 + REX_BASE(fr));
+                } else {
+                    o(0x99); /* cltd */
+                }
+                o(0xf7); /* idiv fr, %eax */
+                o(0xf8 + fr);
+            }
+            if (op == '%' || op == TOK_UMOD)
+                r = TREG_RDX;
+            else
+                r = TREG_RAX;
+        }
+        vtop->r = r;
+        break;
+    default:
+        opc = 7;
+        goto gen_op8;
+    }
+}
+
+void gen_opl(int op)
+{
+    gen_opi(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)
+{
+    int a, ft, fc, swapped, r;
+    int float_type =
+        (vtop->type.t & VT_BTYPE) == VT_LDOUBLE ? RC_ST0 : RC_FLOAT;
+
+    /* convert constants to memory references */
+    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        vswap();
+        gv(float_type);
+        vswap();
+    }
+    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+        gv(float_type);
+
+    /* must put at least one value in the floating point register */
+    if ((vtop[-1].r & VT_LVAL) &&
+        (vtop[0].r & VT_LVAL)) {
+        vswap();
+        gv(float_type);
+        vswap();
+    }
+    swapped = 0;
+    /* swap the stack if needed so that t1 is the register and t2 is
+       the memory reference */
+    if (vtop[-1].r & VT_LVAL) {
+        vswap();
+        swapped = 1;
+    }
+    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* load on stack second operand */
+            load(TREG_ST0, vtop);
+            save_reg(TREG_RAX); /* eax is used by FP comparison code */
+            if (op == TOK_GE || op == TOK_GT)
+                swapped = !swapped;
+            else if (op == TOK_EQ || op == TOK_NE)
+                swapped = 0;
+            if (swapped)
+                o(0xc9d9); /* fxch %st(1) */
+            o(0xe9da); /* fucompp */
+            o(0xe0df); /* fnstsw %ax */
+            if (op == TOK_EQ) {
+                o(0x45e480); /* and $0x45, %ah */
+                o(0x40fC80); /* cmp $0x40, %ah */
+            } else if (op == TOK_NE) {
+                o(0x45e480); /* and $0x45, %ah */
+                o(0x40f480); /* xor $0x40, %ah */
+                op = TOK_NE;
+            } else if (op == TOK_GE || op == TOK_LE) {
+                o(0x05c4f6); /* test $0x05, %ah */
+                op = TOK_EQ;
+            } else {
+                o(0x45c4f6); /* test $0x45, %ah */
+                op = TOK_EQ;
+            }
+            vtop--;
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        } else {
+            /* no memory reference possible for long double operations */
+            load(TREG_ST0, vtop);
+            swapped = !swapped;
+
+            switch(op) {
+            default:
+            case '+':
+                a = 0;
+                break;
+            case '-':
+                a = 4;
+                if (swapped)
+                    a++;
+                break;
+            case '*':
+                a = 1;
+                break;
+            case '/':
+                a = 6;
+                if (swapped)
+                    a++;
+                break;
+            }
+            ft = vtop->type.t;
+            fc = vtop->c.ul;
+            o(0xde); /* fxxxp %st, %st(1) */
+            o(0xc1 + (a << 3));
+            vtop--;
+        }
+    } else {
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* if saved lvalue, then we must reload it */
+            r = vtop->r;
+            fc = vtop->c.ul;
+            if ((r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_INT;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.ul = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+
+            if (op == TOK_EQ || op == TOK_NE) {
+                swapped = 0;
+            } else {
+                if (op == TOK_LE || op == TOK_LT)
+                    swapped = !swapped;
+                if (op == TOK_LE || op == TOK_GE) {
+                    op = 0x93; /* setae */
+                } else {
+                    op = 0x97; /* seta */
+                }
+            }
+
+            if (swapped) {
+                o(0x7e0ff3); /* movq */
+                gen_modrm(1, r, vtop->sym, fc);
+
+                if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+                    o(0x66);
+                }
+                o(0x2e0f); /* ucomisd %xmm0, %xmm1 */
+                o(0xc8);
+            } else {
+                if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+                    o(0x66);
+                }
+                o(0x2e0f); /* ucomisd */
+                gen_modrm(0, r, vtop->sym, fc);
+            }
+
+            vtop--;
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        } else {
+            /* no memory reference possible for long double operations */
+            if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+                load(TREG_XMM0, vtop);
+                swapped = !swapped;
+            }
+            switch(op) {
+            default:
+            case '+':
+                a = 0;
+                break;
+            case '-':
+                a = 4;
+                break;
+            case '*':
+                a = 1;
+                break;
+            case '/':
+                a = 6;
+                break;
+            }
+            ft = vtop->type.t;
+            fc = vtop->c.ul;
+            if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+                o(0xde); /* fxxxp %st, %st(1) */
+                o(0xc1 + (a << 3));
+            } else {
+                /* if saved lvalue, then we must reload it */
+                r = vtop->r;
+                if ((r & VT_VALMASK) == VT_LLOCAL) {
+                    SValue v1;
+                    r = get_reg(RC_INT);
+                    v1.type.t = VT_INT;
+                    v1.r = VT_LOCAL | VT_LVAL;
+                    v1.c.ul = fc;
+                    load(r, &v1);
+                    fc = 0;
+                }
+                if (swapped) {
+                    /* movq %xmm0,%xmm1 */
+                    o(0x7e0ff3);
+                    o(0xc8);
+                    load(TREG_XMM0, vtop);
+                    /* subsd  %xmm1,%xmm0 (f2 0f 5c c1) */
+                    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                        o(0xf2);
+                    } else {
+                        o(0xf3);
+                    }
+                    o(0x0f);
+                    o(0x58 + a);
+                    o(0xc1);
+                } else {
+                    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                        o(0xf2);
+                    } else {
+                        o(0xf3);
+                    }
+                    o(0x0f);
+                    o(0x58 + a);
+                    gen_modrm(0, r, vtop->sym, fc);
+                }
+            }
+            vtop--;
+        }
+    }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    if ((t & VT_BTYPE) == VT_LDOUBLE) {
+        save_reg(TREG_ST0);
+        gv(RC_INT);
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            /* signed long long to float/double/long double (unsigned case
+               is handled generically) */
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x242cdf); /* fildll (%rsp) */
+            o(0x08c48348); /* add $8, %rsp */
+        } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+                   (VT_INT | VT_UNSIGNED)) {
+            /* unsigned int to float/double/long double */
+            o(0x6a); /* push $0 */
+            g(0x00);
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x242cdf); /* fildll (%rsp) */
+            o(0x10c48348); /* add $16, %rsp */
+        } else {
+            /* int to float/double/long double */
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x2404db); /* fildl (%rsp) */
+            o(0x08c48348); /* add $8, %rsp */
+        }
+        vtop->r = TREG_ST0;
+    } else {
+        save_reg(TREG_XMM0);
+        gv(RC_INT);
+        o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT));
+        if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+            (VT_INT | VT_UNSIGNED) ||
+            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            o(0x48); /* REX */
+        }
+        o(0x2a0f);
+        o(0xc0 + (vtop->r & VT_VALMASK)); /* cvtsi2sd */
+        vtop->r = TREG_XMM0;
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    int ft, bt, tbt;
+
+    ft = vtop->type.t;
+    bt = ft & VT_BTYPE;
+    tbt = t & VT_BTYPE;
+
+    if (bt == VT_FLOAT) {
+        gv(RC_FLOAT);
+        if (tbt == VT_DOUBLE) {
+            o(0xc0140f); /* unpcklps */
+            o(0xc05a0f); /* cvtps2pd */
+        } else if (tbt == VT_LDOUBLE) {
+            /* movss %xmm0,-0x10(%rsp) */
+            o(0x44110ff3);
+            o(0xf024);
+            o(0xf02444d9); /* flds -0x10(%rsp) */
+            vtop->r = TREG_ST0;
+        }
+    } else if (bt == VT_DOUBLE) {
+        gv(RC_FLOAT);
+        if (tbt == VT_FLOAT) {
+            o(0xc0140f66); /* unpcklpd */
+            o(0xc05a0f66); /* cvtpd2ps */
+        } else if (tbt == VT_LDOUBLE) {
+            /* movsd %xmm0,-0x10(%rsp) */
+            o(0x44110ff2);
+            o(0xf024);
+            o(0xf02444dd); /* fldl -0x10(%rsp) */
+            vtop->r = TREG_ST0;
+        }
+    } else {
+        gv(RC_ST0);
+        if (tbt == VT_DOUBLE) {
+            o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+            /* movsd -0x10(%rsp),%xmm0 */
+            o(0x44100ff2);
+            o(0xf024);
+            vtop->r = TREG_XMM0;
+        } else if (tbt == VT_FLOAT) {
+            o(0xf0245cd9); /* fstps -0x10(%rsp) */
+            /* movss -0x10(%rsp),%xmm0 */
+            o(0x44100ff3);
+            o(0xf024);
+            vtop->r = TREG_XMM0;
+        }
+    }
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+    int ft, bt, size, r;
+    ft = vtop->type.t;
+    bt = ft & VT_BTYPE;
+    if (bt == VT_LDOUBLE) {
+        gen_cvt_ftof(VT_DOUBLE);
+        bt = VT_DOUBLE;
+    }
+
+    gv(RC_FLOAT);
+    if (t != VT_INT)
+        size = 8;
+    else
+        size = 4;
+
+    r = get_reg(RC_INT);
+    if (bt == VT_FLOAT) {
+        o(0xf3);
+    } else if (bt == VT_DOUBLE) {
+        o(0xf2);
+    } else {
+        assert(0);
+    }
+    if (size == 8) {
+        o(0x48 + REX_BASE(r));
+    }
+    o(0x2c0f); /* cvttss2si or cvttsd2si */
+    o(0xc0 + (REG_VALUE(r) << 3));
+    vtop->r = r;
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* end of x86-64 code generator */
+/*************************************************************/