tiny C support; cosmetic improvements for the docs

This commit is contained in:
Araq
2010-08-28 22:33:07 +02:00
parent b2075302b1
commit 47886978c7
151 changed files with 63611 additions and 43 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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:

View File

@@ -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.

View File

@@ -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

View File

@@ -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) =

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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!)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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])

View File

@@ -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)

1734
tinyc/arm-gen.c Executable file

File diff suppressed because it is too large Load Diff

2548
tinyc/c67-gen.c Executable file

File diff suppressed because it is too large Load Diff

446
tinyc/coff.h Executable file
View File

@@ -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"

15
tinyc/config.h Executable file
View File

@@ -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

20
tinyc/config.mak Executable file
View File

@@ -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

1
tinyc/config.texi Executable file
View File

@@ -0,0 +1 @@
@set VERSION 0.9.25

15
tinyc/config_edited.h Executable file
View File

@@ -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

1714
tinyc/elf.h Executable file

File diff suppressed because it is too large Load Diff

8
tinyc/examples/ex1.c Executable file
View File

@@ -0,0 +1,8 @@
#! /usr/local/bin/tcc -run
#include <tcclib.h>
int main()
{
printf("Hello World\n");
return 0;
}

98
tinyc/examples/ex2.c Executable file
View File

@@ -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;
}
}

24
tinyc/examples/ex3.c Executable file
View File

@@ -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;
}

26
tinyc/examples/ex4.c Executable file
View File

@@ -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;
}

8
tinyc/examples/ex5.c Executable file
View File

@@ -0,0 +1,8 @@
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}

1211
tinyc/i386-asm.c Executable file

File diff suppressed because it is too large Load Diff

446
tinyc/i386-asm.h Executable file
View File

@@ -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

1034
tinyc/i386-gen.c Executable file

File diff suppressed because it is too large Load Diff

667
tinyc/il-gen.c Executable file
View File

@@ -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 */
/*************************************************************/

251
tinyc/il-opcodes.h Executable file
View File

@@ -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)

57
tinyc/include/float.h Executable file
View File

@@ -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_ */

67
tinyc/include/stdarg.h Executable file
View File

@@ -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 */

10
tinyc/include/stdbool.h Executable file
View File

@@ -0,0 +1,10 @@
#ifndef _STDBOOL_H
#define _STDBOOL_H
/* ISOC99 boolean */
#define bool _Bool
#define true 1
#define false 0
#endif /* _STDBOOL_H */

20
tinyc/include/stddef.h Executable file
View File

@@ -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

78
tinyc/include/tcclib.h Executable file
View File

@@ -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 */

11
tinyc/include/varargs.h Executable file
View File

@@ -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

45
tinyc/lib/alloca86-bt.S Executable file
View File

@@ -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
/* ---------------------------------------------- */

33
tinyc/lib/alloca86.S Executable file
View File

@@ -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
/* ---------------------------------------------- */

868
tinyc/lib/bcheck.c Executable file
View File

@@ -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);
}

607
tinyc/lib/libtcc1.c Executable file
View File

@@ -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;
}

2259
tinyc/libtcc.c Executable file

File diff suppressed because it is too large Load Diff

108
tinyc/libtcc.h Executable file
View File

@@ -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

234
tinyc/stab.def Executable file
View File

@@ -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.
*/

17
tinyc/stab.h Executable file
View File

@@ -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_ */

2241
tinyc/tcc-doc.html Executable file

File diff suppressed because it is too large Load Diff

1227
tinyc/tcc-doc.texi Executable file

File diff suppressed because it is too large Load Diff

553
tinyc/tcc.c Executable file
View File

@@ -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;
}

766
tinyc/tcc.h Executable file
View File

@@ -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';
}

1021
tinyc/tccasm.c Executable file

File diff suppressed because it is too large Load Diff

957
tinyc/tcccoff.c Executable file
View File

@@ -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;
}

2732
tinyc/tccelf.c Executable file

File diff suppressed because it is too large Load Diff

5122
tinyc/tccgen.c Executable file

File diff suppressed because it is too large Load Diff

1559
tinyc/tccpe.c Executable file

File diff suppressed because it is too large Load Diff

2935
tinyc/tccpp.c Executable file

File diff suppressed because it is too large Load Diff

469
tinyc/tcctok.h Executable file
View File

@@ -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

558
tinyc/tests/asmtest.S Executable file
View File

@@ -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

214
tinyc/tests/boundtest.c Executable file
View File

@@ -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
*/

33
tinyc/tests/gcctestsuite.sh Executable file
View File

@@ -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."

84
tinyc/tests/libtcc_test.c Executable file
View File

@@ -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;
}

2202
tinyc/tests/tcctest.c Executable file

File diff suppressed because it is too large Load Diff

427
tinyc/texi2pod.pl Executable file
View File

@@ -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;
}
}

28
tinyc/win32/build-tcc.bat Executable file
View File

@@ -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

15
tinyc/win32/examples/dll.c Executable file
View File

@@ -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);
}

24
tinyc/win32/examples/fib.c Executable file
View File

@@ -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;
}

View File

@@ -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;
}

159
tinyc/win32/examples/hello_win.c Executable file
View File

@@ -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
);
}
//+---------------------------------------------------------------------------

54
tinyc/win32/include/_mingw.h Executable file
View File

@@ -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 */

71
tinyc/win32/include/assert.h Executable file
View File

@@ -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_ */

159
tinyc/win32/include/conio.h Executable file
View File

@@ -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_ */

232
tinyc/win32/include/ctype.h Executable file
View File

@@ -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_ */

26
tinyc/win32/include/dir.h Executable file
View File

@@ -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>

95
tinyc/win32/include/direct.h Executable file
View File

@@ -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__ */

96
tinyc/win32/include/dirent.h Executable file
View File

@@ -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__ */

110
tinyc/win32/include/dos.h Executable file
View File

@@ -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__ */

117
tinyc/win32/include/errno.h Executable file
View File

@@ -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_ */

20
tinyc/win32/include/excpt.h Executable file
View File

@@ -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

135
tinyc/win32/include/fcntl.h Executable file
View File

@@ -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__ */

85
tinyc/win32/include/fenv.h Executable file
View File

@@ -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 */

224
tinyc/win32/include/float.h Executable file
View File

@@ -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_ */

275
tinyc/win32/include/inttypes.h Executable file
View File

@@ -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 */

296
tinyc/win32/include/io.h Executable file
View File

@@ -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 */

115
tinyc/win32/include/limits.h Executable file
View File

@@ -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_ */

100
tinyc/win32/include/locale.h Executable file
View File

@@ -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_ */

87
tinyc/win32/include/malloc.h Executable file
View File

@@ -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__ */

438
tinyc/win32/include/math.h Executable file
View File

@@ -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_ */

8
tinyc/win32/include/mem.h Executable file
View File

@@ -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

9
tinyc/win32/include/memory.h Executable file
View File

@@ -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

158
tinyc/win32/include/process.h Executable file
View File

@@ -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__ */

72
tinyc/win32/include/setjmp.h Executable file
View File

@@ -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_ */

44
tinyc/win32/include/share.h Executable file
View File

@@ -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__ */

111
tinyc/win32/include/signal.h Executable file
View File

@@ -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_ */

16
tinyc/win32/include/stdarg.h Executable file
View File

@@ -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

10
tinyc/win32/include/stdbool.h Executable file
View File

@@ -0,0 +1,10 @@
#ifndef _STDBOOL_H
#define _STDBOOL_H
/* ISOC99 boolean */
#define bool _Bool
#define true 1
#define false 0
#endif /* _STDBOOL_H */

23
tinyc/win32/include/stddef.h Executable file
View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More