changeset 510:f304c7e3de8d

Teach tcc.c to handle colon separated paths (semicolon separated on a win32 host) and teach make to produce libtinycc.a, and more fallout from regularizing the names.
author Rob Landley <rob@landley.net>
date Sun, 11 Nov 2007 03:45:57 -0600
parents 95fd7f30f7e3
children 374af493d0ac
files i386/asm.c libtcc1.c libtinycc1.c make tcc.c tcc.h tcctok.h
diffstat 7 files changed, 646 insertions(+), 638 deletions(-) [+]
line wrap: on
line diff
--- a/i386/asm.c	Sun Nov 11 03:31:05 2007 -0600
+++ b/i386/asm.c	Sun Nov 11 03:45:57 2007 -0600
@@ -155,7 +155,7 @@
 #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"
+#include "asm.h"
 
     /* last operation */
     { 0, },
@@ -168,7 +168,7 @@
 #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"
+#include "asm.h"
 };
 
 static inline int get_reg_shift(TCCState *s1)
--- a/libtcc1.c	Sun Nov 11 03:31:05 2007 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,602 +0,0 @@
-/* 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 long lower;
-        long upper;
-    } l;
-#else
-    struct {
-        long upper;
-        unsigned long lower;
-    } l;
-#endif
-    long long ll;
-};
-
-union float_long {
-    float f;
-    long l;
-};
-
-/* 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, &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 __sardi3(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) | ((unsigned)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 __shrdi3(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) | ((unsigned)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 __shldi3(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
-
-/* XXX: fix tcc's code generator to do this instead */
-float __ulltof(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 __ulltod(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 __ulltold(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;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtinycc1.c	Sun Nov 11 03:45:57 2007 -0600
@@ -0,0 +1,602 @@
+/* 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 long lower;
+        long upper;
+    } l;
+#else
+    struct {
+        long upper;
+        unsigned long lower;
+    } l;
+#endif
+    long long ll;
+};
+
+union float_long {
+    float f;
+    long l;
+};
+
+/* 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, &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 __sardi3(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) | ((unsigned)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 __shrdi3(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) | ((unsigned)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 __shldi3(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
+
+/* XXX: fix tcc's code generator to do this instead */
+float __ulltof(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 __ulltod(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 __ulltold(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;
+}
+
--- a/make	Sun Nov 11 03:31:05 2007 -0600
+++ b/make	Sun Nov 11 03:45:57 2007 -0600
@@ -11,7 +11,8 @@
 [ -z "$CFLAGS" ] && CFLAGS="-g -Wall -fsigned-char -Os -fno-strict-aliasing"
 [ -z "$LIBS" ] && LIBS="-lm -ldl"
 [ -z "$ARCH" ] && ARCH="i386 arm c67 win32"
-[ -z "$TINYCC_LIBS" ] && TINYCC_LIBS=/lib
+[ -z "$CC_LIB_PATH" ] && CC_LIB_PATH=/usr/lib/tcc
+[ -z "$TINYCC_LIBS" ] && TINYCC_LIBS="/usr/local/lib:/usr/lib:/lib"
 [ -z "$TINYCC_INCLUDES" ] && TINYCC_INCLUDES=/usr/include
 
 TINYCC_VERSION=1.2.3
@@ -53,7 +54,8 @@
   [ "$1" == "--fast" ] && [ "$i" != "$HOST" ] && continue
 
   $CC $CFLAGS $LIBS -DTCC_TARGET_$i \
-    '-DCC_LIB_PATH="'"$TINYCC_LIBS"'"' \
+    '-DCC_LIB_PATH="'"$CC_LIB_PATH"'"' \
+    '-DTINYCC_LIBS="'"$TINYCC_LIBS"'"' \
     '-DTINYCC_INCLUDES="'"$TINYCC_INCLUDES"'"' \
     '-DTINYCC_VERSION="'"$TINYCC_VERSION"'"' \
     -o ${i}-tinycc_unstripped tcc.c &&
@@ -70,10 +72,10 @@
 
   if [ -f $i/alloca.S ]
   then
-    ./$i-tinycc TCC=./tcc -B. -I./include -I. -c -o libtinycc1.o libtinycc1.c &&
-    $CC -c -o alloca.o $i/alloca.S &&
-    $CC -c -o bound-alloca.o $i/bound-alloca.S &&
-    $AR rcs libtcc-${i}.a libtcc1.o alloca.o bound-alloca.o
+    ./$i-tinycc $DOLOCAL -o libtinycc1.o -c libtinycc1.c &&
+    ./$i-tinycc $DOLOCAL -o alloca.o -c $i/alloca.S &&
+    ./$i-tinycc $DOLOCAL -o bound-alloca.o -c $i/bound-alloca.S &&
+    $AR rcs libtinycc-${i}.a libtinycc1.o alloca.o bound-alloca.o
   fi
 done
 
--- a/tcc.c	Sun Nov 11 03:31:05 2007 -0600
+++ b/tcc.c	Sun Nov 11 03:45:57 2007 -0600
@@ -27,11 +27,11 @@
 static int do_bounds_check = 0;
 
 #ifdef TCC_TARGET_I386
-#include "i386/i386-gen.c"
+#include "i386/gen.c"
 #endif
 
 #ifdef TCC_TARGET_ARM
-#include "arm-gen.c"
+#include "arm/gen.c"
 #endif
 
 #ifdef TCC_TARGET_C67
@@ -8628,7 +8628,7 @@
 #ifdef CONFIG_TCC_ASM
 
 #ifdef TCC_TARGET_I386
-#include "i386/i386-asm.c"
+#include "i386/asm.c"
 #endif
 #include "tccasm.c"
 
@@ -8748,6 +8748,25 @@
     return (*prog_main)(argc, argv);
 }
 
+int add_library_path(TCCState *s, const char *pathname)
+{
+    const char *c = pathname;
+
+    for (;;) {
+        if (!*c || *c==LIB_PATH_SEPCHAR) {
+            int len = c-pathname;
+            char *c2 = xmalloc(len+1);
+
+            strncpy(c2, pathname, len);
+            c2[len] = 0;
+            pathname += len+1;
+            dynarray_add((void ***)&s->library_paths, &s->nb_library_paths, c2);
+        }
+        if (!*c++) break;
+    }
+    return 0;
+}
+
 // Initialize tcc state
 
 TCCState *tcc_new(void)
@@ -8815,23 +8834,19 @@
     /* tiny C & gcc defines */
     tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
     tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
+
+    /* wchar type and default library paths */
 #ifdef TCC_TARGET_PE
     tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
-#else
-    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
-#endif
     
-    /* default library paths */
-#ifdef TCC_TARGET_PE
     {
         char buf[1024];
         snprintf(buf, sizeof(buf), "%s/lib", cc_lib_path);
-        tcc_add_library_path(s, buf);
+        add_library_path(s, buf);
     }
 #else
-    tcc_add_library_path(s, "/usr/local/lib");
-    tcc_add_library_path(s, "/usr/lib");
-    tcc_add_library_path(s, "/lib");
+    add_library_path(s, TINYCC_LIBS);
+    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
 #endif
 
     /* no section zero */
@@ -9053,15 +9068,6 @@
     return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR);
 }
 
-int tcc_add_library_path(TCCState *s, const char *pathname)
-{
-    char *pathname1;
-    
-    pathname1 = xstrdup(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)
@@ -9125,13 +9131,11 @@
 #ifndef TCC_TARGET_PE
         tcc_add_sysinclude_path(s, "/usr/local/include");
         tcc_add_sysinclude_path(s, "/usr/include");
+        snprintf(buf, sizeof(buf), "%s/include/winapi", cc_lib_path);
+        tcc_add_sysinclude_path(s, buf);
 #endif
         snprintf(buf, sizeof(buf), "%s/include", cc_lib_path);
         tcc_add_sysinclude_path(s, buf);
-#ifdef TCC_TARGET_PE
-        snprintf(buf, sizeof(buf), "%s/include/winapi", cc_lib_path);
-        tcc_add_sysinclude_path(s, buf);
-#endif
     }
 
     /* if bound checking, then add corresponding sections */
@@ -9517,7 +9521,7 @@
                 tcc_undefine_symbol(s, optarg);
                 break;
             case TCC_OPTION_L:
-                tcc_add_library_path(s, optarg);
+                add_library_path(s, optarg);
                 break;
             case TCC_OPTION_B:
                 /* set tcc utilities path (mainly for tcc development) */
--- a/tcc.h	Sun Nov 11 03:31:05 2007 -0600
+++ b/tcc.h	Sun Nov 11 03:45:57 2007 -0600
@@ -122,8 +122,10 @@
 
 #ifdef TCC_TARGET_PE
 typedef unsigned short nwchar_t;
+#define LIB_PATH_SEPCHAR ';'
 #else
 typedef int nwchar_t;
+#define LIB_PATH_SEPCHAR ':'
 #endif
 
 typedef struct CString {
--- a/tcctok.h	Sun Nov 11 03:31:05 2007 -0600
+++ b/tcctok.h	Sun Nov 11 03:45:57 2007 -0600
@@ -444,7 +444,7 @@
 #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/i386-asm.h"
+#include "i386/asm.h"
 
 #define ALT(x)
 #define DEF_ASM_OP0(name, opcode)
@@ -452,6 +452,6 @@
 #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/i386-asm.h"
+#include "i386/asm.h"
 
 #endif