added runtime library - fixed more relocations
This commit is contained in:
		
							parent
							
								
									3d902af1a9
								
							
						
					
					
						commit
						6cdecbe4e6
					
				
					 4 changed files with 678 additions and 132 deletions
				
			
		
							
								
								
									
										41
									
								
								i386-gen.c
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								i386-gen.c
									
										
									
									
									
								
							| 
						 | 
					@ -822,27 +822,33 @@ void gen_cvt_ftof(int t)
 | 
				
			||||||
/* generate a bounded pointer addition */
 | 
					/* generate a bounded pointer addition */
 | 
				
			||||||
void gen_bounded_ptr_add(void)
 | 
					void gen_bounded_ptr_add(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int addr;
 | 
					    Sym *sym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* prepare fast i386 function call (args in eax and edx) */
 | 
					    /* prepare fast i386 function call (args in eax and edx) */
 | 
				
			||||||
    gv2(RC_EAX, RC_EDX);
 | 
					    gv2(RC_EAX, RC_EDX);
 | 
				
			||||||
    /* save all temporary registers */
 | 
					    /* save all temporary registers */
 | 
				
			||||||
    vtop -= 2;
 | 
					    vtop -= 2;
 | 
				
			||||||
    save_regs(0);
 | 
					    save_regs(0);
 | 
				
			||||||
    /* do a fast function call */
 | 
					    /* do a fast function call */
 | 
				
			||||||
    addr = ind;
 | 
					    sym = external_sym(TOK___bound_ptr_add, func_old_type, 0);
 | 
				
			||||||
    oad(0xe8, (int)__bound_ptr_add - ind - 5);
 | 
					    greloc(cur_text_section, sym, 
 | 
				
			||||||
 | 
					           ind + 1 - (int)cur_text_section->data, R_386_PC32);
 | 
				
			||||||
 | 
					    oad(0xe8, -4);
 | 
				
			||||||
    /* returned pointer is in eax */
 | 
					    /* returned pointer is in eax */
 | 
				
			||||||
    vtop++;
 | 
					    vtop++;
 | 
				
			||||||
    vtop->r = REG_EAX | VT_BOUNDED;
 | 
					    vtop->r = REG_EAX | VT_BOUNDED;
 | 
				
			||||||
    vtop->c.ul = addr; /* address of bounding function call point */
 | 
					    /* address of bounding function call point */
 | 
				
			||||||
 | 
					    vtop->c.ptr = (cur_text_section->reloc->data_ptr - sizeof(Elf32_Rel)); 
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* patch pointer addition in vtop so that pointer dereferencing is
 | 
					/* patch pointer addition in vtop so that pointer dereferencing is
 | 
				
			||||||
   also tested */
 | 
					   also tested */
 | 
				
			||||||
void gen_bounded_ptr_deref(void)
 | 
					void gen_bounded_ptr_deref(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    void *func;
 | 
					    int func;
 | 
				
			||||||
    int size, align, addr;
 | 
					    int size, align;
 | 
				
			||||||
 | 
					    Elf32_Rel *rel;
 | 
				
			||||||
 | 
					    Sym *sym;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size = 0;
 | 
					    size = 0;
 | 
				
			||||||
    /* XXX: put that code in generic part of tcc */
 | 
					    /* XXX: put that code in generic part of tcc */
 | 
				
			||||||
| 
						 | 
					@ -855,20 +861,25 @@ void gen_bounded_ptr_deref(void)
 | 
				
			||||||
    if (!size)
 | 
					    if (!size)
 | 
				
			||||||
        size = type_size(vtop->t, &align);
 | 
					        size = type_size(vtop->t, &align);
 | 
				
			||||||
    switch(size) {
 | 
					    switch(size) {
 | 
				
			||||||
    case  1: func = __bound_ptr_indir1; break;
 | 
					    case  1: func = TOK___bound_ptr_indir1; break;
 | 
				
			||||||
    case  2: func = __bound_ptr_indir2; break;
 | 
					    case  2: func = TOK___bound_ptr_indir2; break;
 | 
				
			||||||
    case  4: func = __bound_ptr_indir4; break;
 | 
					    case  4: func = TOK___bound_ptr_indir4; break;
 | 
				
			||||||
    case  8: func = __bound_ptr_indir8; break;
 | 
					    case  8: func = TOK___bound_ptr_indir8; break;
 | 
				
			||||||
    case 12: func = __bound_ptr_indir12; break;
 | 
					    case 12: func = TOK___bound_ptr_indir12; break;
 | 
				
			||||||
    case 16: func = __bound_ptr_indir16; break;
 | 
					    case 16: func = TOK___bound_ptr_indir16; break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        error("unhandled size when derefencing bounded pointer");
 | 
					        error("unhandled size when derefencing bounded pointer");
 | 
				
			||||||
        func = NULL;
 | 
					        func = 0;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    addr = vtop->c.ul;
 | 
					    /* patch relocation */
 | 
				
			||||||
    *(int *)(addr + 1) = (int)func - addr - 5;
 | 
					    /* XXX: find a better solution ? */
 | 
				
			||||||
 | 
					    rel = vtop->c.ptr;
 | 
				
			||||||
 | 
					    sym = external_sym(func, func_old_type, 0);
 | 
				
			||||||
 | 
					    if (!sym->c)
 | 
				
			||||||
 | 
					        put_extern_sym(sym, NULL, 0);
 | 
				
			||||||
 | 
					    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										556
									
								
								libtcc1.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										556
									
								
								libtcc1.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,556 @@
 | 
				
			||||||
 | 
					/* 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: suppress that and patch tcc to do it */
 | 
				
			||||||
 | 
					long long __sardi3(long long a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return a >> b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XXX: suppress that and patch tcc to do it */
 | 
				
			||||||
 | 
					unsigned long long __shrdi3(unsigned long long a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return a >> b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XXX: suppress that and patch tcc to do it */
 | 
				
			||||||
 | 
					long long __shldi3(long long a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return a << b;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XXX: suppress that and patch tcc to do it */
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										172
									
								
								tcc.c
									
										
									
									
									
								
							
							
						
						
									
										172
									
								
								tcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -100,6 +100,7 @@ typedef union CValue {
 | 
				
			||||||
    unsigned long long ull;
 | 
					    unsigned long long ull;
 | 
				
			||||||
    struct TokenSym *ts;
 | 
					    struct TokenSym *ts;
 | 
				
			||||||
    struct Sym *sym;
 | 
					    struct Sym *sym;
 | 
				
			||||||
 | 
					    void *ptr;
 | 
				
			||||||
    int tab[1];
 | 
					    int tab[1];
 | 
				
			||||||
} CValue;
 | 
					} CValue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -284,6 +285,7 @@ int ifdef_stack[IFDEF_STACK_SIZE], *ifdef_stack_ptr;
 | 
				
			||||||
char **include_paths;
 | 
					char **include_paths;
 | 
				
			||||||
int nb_include_paths;
 | 
					int nb_include_paths;
 | 
				
			||||||
int char_pointer_type;
 | 
					int char_pointer_type;
 | 
				
			||||||
 | 
					int func_old_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* compile with debug symbol (and use them if error during execution) */
 | 
					/* compile with debug symbol (and use them if error during execution) */
 | 
				
			||||||
int do_debug = 0;
 | 
					int do_debug = 0;
 | 
				
			||||||
| 
						 | 
					@ -493,21 +495,9 @@ enum {
 | 
				
			||||||
    /* special identifiers */
 | 
					    /* special identifiers */
 | 
				
			||||||
    TOK___FUNC__,
 | 
					    TOK___FUNC__,
 | 
				
			||||||
    TOK_MAIN,
 | 
					    TOK_MAIN,
 | 
				
			||||||
    /* attribute identifiers */
 | 
					#define DEF(id, str) id,
 | 
				
			||||||
    TOK_SECTION,
 | 
					#include "tcctok.h"
 | 
				
			||||||
    TOK___SECTION__,
 | 
					#undef DEF
 | 
				
			||||||
    TOK_ALIGNED,
 | 
					 | 
				
			||||||
    TOK___ALIGNED__,
 | 
					 | 
				
			||||||
    TOK_UNUSED,
 | 
					 | 
				
			||||||
    TOK___UNUSED__,
 | 
					 | 
				
			||||||
    TOK_CDECL,
 | 
					 | 
				
			||||||
    TOK___CDECL,
 | 
					 | 
				
			||||||
    TOK___CDECL__,
 | 
					 | 
				
			||||||
    TOK_STDCALL,
 | 
					 | 
				
			||||||
    TOK___STDCALL,
 | 
					 | 
				
			||||||
    TOK___STDCALL__,
 | 
					 | 
				
			||||||
    TOK_NORETURN,
 | 
					 | 
				
			||||||
    TOK___NORETURN__,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *tcc_keywords = 
 | 
					char *tcc_keywords = 
 | 
				
			||||||
| 
						 | 
					@ -521,10 +511,10 @@ char *tcc_keywords =
 | 
				
			||||||
"defined\0undef\0error\0line\0"
 | 
					"defined\0undef\0error\0line\0"
 | 
				
			||||||
"__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
 | 
					"__LINE__\0__FILE__\0__DATE__\0__TIME__\0__VA_ARGS__\0"
 | 
				
			||||||
"__func__\0main\0"
 | 
					"__func__\0main\0"
 | 
				
			||||||
/* attributes */
 | 
					/* builtin functions */
 | 
				
			||||||
"section\0__section__\0aligned\0__aligned__\0unused\0__unused__\0"
 | 
					#define DEF(id, str) str "\0"
 | 
				
			||||||
"cdecl\0__cdecl\0__cdecl__\0stdcall\0__stdcall\0__stdcall__\0"
 | 
					#include "tcctok.h"
 | 
				
			||||||
"noreturn\0__noreturn__\0"
 | 
					#undef DEF
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WIN32
 | 
					#ifdef WIN32
 | 
				
			||||||
| 
						 | 
					@ -595,6 +585,7 @@ void vset(int t, int r, int v);
 | 
				
			||||||
void type_to_str(char *buf, int buf_size, 
 | 
					void type_to_str(char *buf, int buf_size, 
 | 
				
			||||||
                 int t, const char *varstr);
 | 
					                 int t, const char *varstr);
 | 
				
			||||||
char *get_tok_str(int v, CValue *cv);
 | 
					char *get_tok_str(int v, CValue *cv);
 | 
				
			||||||
 | 
					Sym *external_sym(int v, int u, int r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* section generation */
 | 
					/* section generation */
 | 
				
			||||||
void put_extern_sym(Sym *sym, Section *section, unsigned long value);
 | 
					void put_extern_sym(Sym *sym, Section *section, unsigned long value);
 | 
				
			||||||
| 
						 | 
					@ -680,77 +671,6 @@ void *dlsym(void *handle, const char *symbol)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********************************************************/
 | 
					 | 
				
			||||||
/* runtime library is there */
 | 
					 | 
				
			||||||
/* XXX: we suppose that the host compiler handles 'long long'. It
 | 
					 | 
				
			||||||
   would not be difficult to suppress this assumption */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __divll(long long a, long long b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a / b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __modll(long long a, long long b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a % b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __divull(unsigned long long a, unsigned long long b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a / b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __modull(unsigned long long a, unsigned long long b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a % b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __sardi3(long long a, int b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a >> b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __shrdi3(unsigned long long a, int b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a >> b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __shldi3(long long a, int b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return a << b;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float __ulltof(unsigned long long a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (float)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
double __ulltod(unsigned long long a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (double)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long double __ulltold(unsigned long long a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (long double)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __ftoull(float a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (unsigned long long)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __dtoull(double a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (unsigned long long)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
unsigned long long __ldtoull(long double a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return (unsigned long long)a;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/********************************************************/
 | 
					/********************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* we use our own 'finite' function to avoid potential problems with
 | 
					/* we use our own 'finite' function to avoid potential problems with
 | 
				
			||||||
| 
						 | 
					@ -2589,6 +2509,17 @@ void vpush_ref(int t, Section *sec, unsigned long offset)
 | 
				
			||||||
    vsetc(t, VT_CONST | VT_SYM, &cval);
 | 
					    vsetc(t, VT_CONST | VT_SYM, &cval);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* push a reference to symbol v */
 | 
				
			||||||
 | 
					void vpush_sym(int t, int v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Sym *sym;
 | 
				
			||||||
 | 
					    CValue cval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sym = external_sym(v, t, 0);
 | 
				
			||||||
 | 
					    cval.sym = sym;
 | 
				
			||||||
 | 
					    vsetc(t, VT_CONST | VT_SYM, &cval);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void vset(int t, int r, int v)
 | 
					void vset(int t, int r, int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CValue cval;
 | 
					    CValue cval;
 | 
				
			||||||
| 
						 | 
					@ -3019,29 +2950,29 @@ void gv_dup(void)
 | 
				
			||||||
void gen_opl(int op)
 | 
					void gen_opl(int op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int t, a, b, op1, c, i;
 | 
					    int t, a, b, op1, c, i;
 | 
				
			||||||
    void *func;
 | 
					    int func;
 | 
				
			||||||
    GFuncContext gf;
 | 
					    GFuncContext gf;
 | 
				
			||||||
    SValue tmp;
 | 
					    SValue tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch(op) {
 | 
					    switch(op) {
 | 
				
			||||||
    case '/':
 | 
					    case '/':
 | 
				
			||||||
    case TOK_PDIV:
 | 
					    case TOK_PDIV:
 | 
				
			||||||
        func = __divll;
 | 
					        func = TOK___divdi3;
 | 
				
			||||||
        goto gen_func;
 | 
					        goto gen_func;
 | 
				
			||||||
    case TOK_UDIV:
 | 
					    case TOK_UDIV:
 | 
				
			||||||
        func = __divull;
 | 
					        func = TOK___udivdi3;
 | 
				
			||||||
        goto gen_func;
 | 
					        goto gen_func;
 | 
				
			||||||
    case '%':
 | 
					    case '%':
 | 
				
			||||||
        func = __modll;
 | 
					        func = TOK___moddi3;
 | 
				
			||||||
        goto gen_func;
 | 
					        goto gen_func;
 | 
				
			||||||
    case TOK_UMOD:
 | 
					    case TOK_UMOD:
 | 
				
			||||||
        func = __modull;
 | 
					        func = TOK___umoddi3;
 | 
				
			||||||
    gen_func:
 | 
					    gen_func:
 | 
				
			||||||
        /* call generic long long function */
 | 
					        /* call generic long long function */
 | 
				
			||||||
        gfunc_start(&gf, FUNC_CDECL);
 | 
					        gfunc_start(&gf, FUNC_CDECL);
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        vpushi((int)func);
 | 
					        vpush_sym(func_old_type, func);
 | 
				
			||||||
        gfunc_call(&gf);
 | 
					        gfunc_call(&gf);
 | 
				
			||||||
        vpushi(0);
 | 
					        vpushi(0);
 | 
				
			||||||
        vtop->r = REG_IRET;
 | 
					        vtop->r = REG_IRET;
 | 
				
			||||||
| 
						 | 
					@ -3166,13 +3097,13 @@ void gen_opl(int op)
 | 
				
			||||||
            /* XXX: should provide a faster fallback on x86 ? */
 | 
					            /* XXX: should provide a faster fallback on x86 ? */
 | 
				
			||||||
            switch(op) {
 | 
					            switch(op) {
 | 
				
			||||||
            case TOK_SAR:
 | 
					            case TOK_SAR:
 | 
				
			||||||
                func = __sardi3;
 | 
					                func = TOK___sardi3;
 | 
				
			||||||
                goto gen_func;
 | 
					                goto gen_func;
 | 
				
			||||||
            case TOK_SHR:
 | 
					            case TOK_SHR:
 | 
				
			||||||
                func = __shrdi3;
 | 
					                func = TOK___shrdi3;
 | 
				
			||||||
                goto gen_func;
 | 
					                goto gen_func;
 | 
				
			||||||
            case TOK_SHL:
 | 
					            case TOK_SHL:
 | 
				
			||||||
                func = __shldi3;
 | 
					                func = TOK___shldi3;
 | 
				
			||||||
                goto gen_func;
 | 
					                goto gen_func;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -3561,11 +3492,11 @@ void gen_cvt_itof1(int t)
 | 
				
			||||||
        gfunc_start(&gf, FUNC_CDECL);
 | 
					        gfunc_start(&gf, FUNC_CDECL);
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        if (t == VT_FLOAT)
 | 
					        if (t == VT_FLOAT)
 | 
				
			||||||
            vpushi((int)&__ulltof);
 | 
					            vpush_sym(func_old_type, TOK___ulltof);
 | 
				
			||||||
        else if (t == VT_DOUBLE)
 | 
					        else if (t == VT_DOUBLE)
 | 
				
			||||||
            vpushi((int)&__ulltod);
 | 
					            vpush_sym(func_old_type, TOK___ulltod);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            vpushi((int)&__ulltold);
 | 
					            vpush_sym(func_old_type, TOK___ulltold);
 | 
				
			||||||
        gfunc_call(&gf);
 | 
					        gfunc_call(&gf);
 | 
				
			||||||
        vpushi(0);
 | 
					        vpushi(0);
 | 
				
			||||||
        vtop->r = REG_FRET;
 | 
					        vtop->r = REG_FRET;
 | 
				
			||||||
| 
						 | 
					@ -3586,11 +3517,11 @@ void gen_cvt_ftoi1(int t)
 | 
				
			||||||
        st = vtop->t & VT_BTYPE;
 | 
					        st = vtop->t & VT_BTYPE;
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        if (st == VT_FLOAT)
 | 
					        if (st == VT_FLOAT)
 | 
				
			||||||
            vpushi((int)&__ftoull);
 | 
					            vpush_sym(func_old_type, TOK___fixunssfdi);
 | 
				
			||||||
        else if (st == VT_DOUBLE)
 | 
					        else if (st == VT_DOUBLE)
 | 
				
			||||||
            vpushi((int)&__dtoull);
 | 
					            vpush_sym(func_old_type, TOK___fixunsdfdi);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            vpushi((int)&__ldtoull);
 | 
					            vpush_sym(func_old_type, TOK___fixunsxfdi);
 | 
				
			||||||
        gfunc_call(&gf);
 | 
					        gfunc_call(&gf);
 | 
				
			||||||
        vpushi(0);
 | 
					        vpushi(0);
 | 
				
			||||||
        vtop->r = REG_IRET;
 | 
					        vtop->r = REG_IRET;
 | 
				
			||||||
| 
						 | 
					@ -4049,7 +3980,7 @@ void vstore(void)
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        save_regs(0);
 | 
					        save_regs(0);
 | 
				
			||||||
        vpushi((int)&memcpy);
 | 
					        vpush_sym(func_old_type, TOK_memcpy);
 | 
				
			||||||
        gfunc_call(&gf);
 | 
					        gfunc_call(&gf);
 | 
				
			||||||
        /* leave source on stack */
 | 
					        /* leave source on stack */
 | 
				
			||||||
    } else if (ft & VT_BITFIELD) {
 | 
					    } else if (ft & VT_BITFIELD) {
 | 
				
			||||||
| 
						 | 
					@ -4697,7 +4628,7 @@ void gfunc_param_typed(GFuncContext *gf, Sym *func, Sym *arg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void unary(void)
 | 
					void unary(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int n, t, ft, fc, p, align, size, r, data_offset;
 | 
					    int n, t, ft, fc, align, size, r, data_offset;
 | 
				
			||||||
    Sym *s;
 | 
					    Sym *s;
 | 
				
			||||||
    GFuncContext gf;
 | 
					    GFuncContext gf;
 | 
				
			||||||
    AttributeDef ad;
 | 
					    AttributeDef ad;
 | 
				
			||||||
| 
						 | 
					@ -4847,11 +4778,8 @@ void unary(void)
 | 
				
			||||||
                if (tok != '(')
 | 
					                if (tok != '(')
 | 
				
			||||||
                    error("'%s' undeclared", get_tok_str(t, NULL));
 | 
					                    error("'%s' undeclared", get_tok_str(t, NULL));
 | 
				
			||||||
                /* for simple function calls, we tolerate undeclared
 | 
					                /* for simple function calls, we tolerate undeclared
 | 
				
			||||||
                   external reference */
 | 
					                   external reference to int() function */
 | 
				
			||||||
                p = anon_sym++;
 | 
					                s = external_sym(t, func_old_type, 0); 
 | 
				
			||||||
                sym_push1(&global_stack, p, 0, FUNC_OLD);
 | 
					 | 
				
			||||||
                /* int() function */
 | 
					 | 
				
			||||||
                s = external_sym(t, VT_FUNC | (p << VT_STRUCT_SHIFT), 0); 
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            vset(s->t, s->r, s->c);
 | 
					            vset(s->t, s->r, s->c);
 | 
				
			||||||
            /* if forward reference, we must point to s */
 | 
					            /* if forward reference, we must point to s */
 | 
				
			||||||
| 
						 | 
					@ -5633,7 +5561,7 @@ void init_putz(int t, Section *sec, unsigned long c, int size)
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        vset(VT_INT, VT_LOCAL, c);
 | 
					        vset(VT_INT, VT_LOCAL, c);
 | 
				
			||||||
        gfunc_param(&gf);
 | 
					        gfunc_param(&gf);
 | 
				
			||||||
        vpushi((int)&memset);
 | 
					        vpush_sym(func_old_type, TOK_memset);
 | 
				
			||||||
        gfunc_call(&gf);
 | 
					        gfunc_call(&gf);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6190,6 +6118,7 @@ static int tcc_compile(TCCState *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *define_start;
 | 
					    Sym *define_start;
 | 
				
			||||||
    char buf[512];
 | 
					    char buf[512];
 | 
				
			||||||
 | 
					    int p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    funcname = "";
 | 
					    funcname = "";
 | 
				
			||||||
    include_stack_ptr = include_stack;
 | 
					    include_stack_ptr = include_stack;
 | 
				
			||||||
| 
						 | 
					@ -6215,6 +6144,10 @@ static int tcc_compile(TCCState *s)
 | 
				
			||||||
    /* define common 'char *' type because it is often used internally
 | 
					    /* define common 'char *' type because it is often used internally
 | 
				
			||||||
       for arrays and struct dereference */
 | 
					       for arrays and struct dereference */
 | 
				
			||||||
    char_pointer_type = mk_pointer(VT_BYTE);
 | 
					    char_pointer_type = mk_pointer(VT_BYTE);
 | 
				
			||||||
 | 
					    /* define an old type function 'int func()' */
 | 
				
			||||||
 | 
					    p = anon_sym++;
 | 
				
			||||||
 | 
					    sym_push1(&global_stack, p, 0, FUNC_OLD);
 | 
				
			||||||
 | 
					    func_old_type = VT_FUNC | (p << VT_STRUCT_SHIFT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    define_start = define_stack.top;
 | 
					    define_start = define_stack.top;
 | 
				
			||||||
    inp();
 | 
					    inp();
 | 
				
			||||||
| 
						 | 
					@ -6807,8 +6740,6 @@ static void put32(unsigned char *p, unsigned int val)
 | 
				
			||||||
static void build_got(void)
 | 
					static void build_got(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* if no got, then create it */
 | 
					    /* if no got, then create it */
 | 
				
			||||||
    /* a got is needed even if static link for the symbol
 | 
					 | 
				
			||||||
       _GLOBAL_OFFSET_TABLE_ */
 | 
					 | 
				
			||||||
    got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
 | 
					    got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
 | 
				
			||||||
    got->sh_entsize = 4;
 | 
					    got->sh_entsize = 4;
 | 
				
			||||||
    add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 
 | 
					    add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 
 | 
				
			||||||
| 
						 | 
					@ -6933,6 +6864,12 @@ static void put_dt(Section *dynamic, int dt, unsigned long val)
 | 
				
			||||||
    dynamic->data_ptr += sizeof(Elf32_Dyn);
 | 
					    dynamic->data_ptr += sizeof(Elf32_Dyn);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* add tcc runtime libraries */
 | 
				
			||||||
 | 
					static void tcc_add_runtime(TCCState *s1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    tcc_add_file(s1, CONFIG_TCC_PREFIX "/lib/tcc/libtcc1.o");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* add dynamic sections so that the executable is dynamically linked */
 | 
					/* add dynamic sections so that the executable is dynamically linked */
 | 
				
			||||||
static char elf_interp[] = "/lib/ld-linux.so.2";
 | 
					static char elf_interp[] = "/lib/ld-linux.so.2";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6963,8 +6900,9 @@ int tcc_output_file(TCCState *s1, const char *filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* add libc crtn object */
 | 
					    /* add libc crtn object */
 | 
				
			||||||
    if (file_type != TCC_OUTPUT_OBJ) {
 | 
					    if (file_type != TCC_OUTPUT_OBJ) {
 | 
				
			||||||
        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
 | 
					        tcc_add_runtime(s1);
 | 
				
			||||||
        tcc_add_library(s1, "c");
 | 
					        tcc_add_library(s1, "c");
 | 
				
			||||||
 | 
					        tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    interp = NULL;
 | 
					    interp = NULL;
 | 
				
			||||||
| 
						 | 
					@ -8076,6 +8014,8 @@ int tcc_run(TCCState *s1, int argc, char **argv)
 | 
				
			||||||
    int (*prog_main)(int, char **);
 | 
					    int (*prog_main)(int, char **);
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tcc_add_runtime(s1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    relocate_common_syms();
 | 
					    relocate_common_syms();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* compute relocation address : section are relocated in place */
 | 
					    /* compute relocation address : section are relocated in place */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										39
									
								
								tcctok.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								tcctok.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					/* attribute identifiers */
 | 
				
			||||||
 | 
					DEF(TOK_SECTION, "section")
 | 
				
			||||||
 | 
					DEF(TOK___SECTION__, "__section__")
 | 
				
			||||||
 | 
					DEF(TOK_ALIGNED, "aligned")
 | 
				
			||||||
 | 
					DEF(TOK___ALIGNED__, "__aligned__")
 | 
				
			||||||
 | 
					DEF(TOK_UNUSED, "unused")
 | 
				
			||||||
 | 
					DEF(TOK___UNUSED__, "__unused__")
 | 
				
			||||||
 | 
					DEF(TOK_CDECL, "cdecl")
 | 
				
			||||||
 | 
					DEF(TOK___CDECL, "__cdecl")
 | 
				
			||||||
 | 
					DEF(TOK___CDECL__, "__cdecl__")
 | 
				
			||||||
 | 
					DEF(TOK_STDCALL, "stdcall")
 | 
				
			||||||
 | 
					DEF(TOK___STDCALL, "__stdcall")
 | 
				
			||||||
 | 
					DEF(TOK___STDCALL__, "__stdcall__")
 | 
				
			||||||
 | 
					DEF(TOK_NORETURN, "noreturn")
 | 
				
			||||||
 | 
					DEF(TOK___NORETURN__, "__noreturn__")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* builtin functions */
 | 
				
			||||||
 | 
					DEF(TOK_memcpy, "memcpy")
 | 
				
			||||||
 | 
					DEF(TOK_memset, "memset")
 | 
				
			||||||
 | 
					DEF(TOK___divdi3, "__divdi3")
 | 
				
			||||||
 | 
					DEF(TOK___moddi3, "__moddi3")
 | 
				
			||||||
 | 
					DEF(TOK___udivdi3, "__udivdi3")
 | 
				
			||||||
 | 
					DEF(TOK___umoddi3, "__umoddi3")
 | 
				
			||||||
 | 
					DEF(TOK___sardi3, "__sardi3")
 | 
				
			||||||
 | 
					DEF(TOK___shrdi3, "__shrdi3")
 | 
				
			||||||
 | 
					DEF(TOK___shldi3, "__shldi3")
 | 
				
			||||||
 | 
					DEF(TOK___ulltof, "__ulltof")
 | 
				
			||||||
 | 
					DEF(TOK___ulltod, "__ulltod")
 | 
				
			||||||
 | 
					DEF(TOK___ulltold, "__ulltold")
 | 
				
			||||||
 | 
					DEF(TOK___fixunssfdi, "__fixunssfdi")
 | 
				
			||||||
 | 
					DEF(TOK___fixunsdfdi, "__fixunsdfdi")
 | 
				
			||||||
 | 
					DEF(TOK___fixunsxfdi, "__fixunsxfdi")
 | 
				
			||||||
 | 
					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")
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue