⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcc.c

📁 Tiny C&C++,看看吧,也许用的着
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* see cached_includes */    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];};/* 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_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/* WARNING: the content of this string encodes token numbers */static char tok_two_chars[] = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";#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_INTenum tcc_token {    TOK_LAST = TOK_IDENT - 1,#define DEF(id, str) id,#include "tcctok.h"#undef DEF};static const char tcc_keywords[] = #define DEF(id, str) str "\0"#include "tcctok.h"#undef DEF;#define TOK_UIDENT TOK_DEFINE#ifdef WIN32#define snprintf _snprintf#define vsnprintf _vsnprintf#endif#if defined(WIN32) || defined(TCC_UCLIBC) || defined(__FreeBSD__)/* 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);#endifstatic char *pstrcpy(char *buf, int buf_size, const char *s);static char *pstrcat(char *buf, int buf_size, const char *s);static void next(void);static void next_nomacro(void);static void parse_expr_type(CType *type);static void expr_type(CType *type);static void unary_type(CType *type);static void block(int *bsym, int *csym, int *case_sym, int *def_sym,                   int case_reg, int is_expr);static int expr_const(void);static void expr_eq(void);static void gexpr(void);static void gen_inline_functions(void);static void decl(int l);static void decl_initializer(CType *type, Section *sec, unsigned long c,                              int first, int size_only);static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,                                    int has_init, int v, int scope);int gv(int rc);void gv2(int rc1, int rc2);void move_reg(int r, int s);void save_regs(int n);void save_reg(int r);void vpop(void);void vswap(void);void vdup(void);int get_reg(int rc);int get_reg_ex(int rc,int rc2);static void macro_subst(TokenString *tok_str, Sym **nested_list,                         const int *macro_str, int can_read_stream);void gen_op(int op);void force_charshort_cast(int t);static void gen_cast(CType *type);void vstore(void);static Sym *sym_find(int v);static Sym *sym_push(int v, CType *type, int r, int c);/* type handling */static int type_size(CType *type, int *a);static inline CType *pointed_type(CType *type);static int pointed_size(CType *type);static int lvalue_type(int t);static int parse_btype(CType *type, AttributeDef *ad);static void type_decl(CType *type, AttributeDef *ad, int *v, int td);static int is_compatible_types(CType *type1, CType *type2);int ieee_finite(double d);void error(const char *fmt, ...);void vpushi(int v);void vrott(int n);void vnrott(int n);void lexpand_nr(void);static void vpush_global_sym(CType *type, int v);void vset(CType *type, int r, int v);void type_to_str(char *buf, int buf_size,                  CType *type, const char *varstr);char *get_tok_str(int v, CValue *cv);static Sym *get_sym_ref(CType *type, Section *sec,                         unsigned long offset, unsigned long size);static Sym *external_global_sym(int v, CType *type, int r);/* section generation */static void section_realloc(Section *sec, unsigned long new_size);static void *section_ptr_add(Section *sec, unsigned long size);static void put_extern_sym(Sym *sym, Section *section,                            unsigned long value, unsigned long size);static void greloc(Section *s, Sym *sym, unsigned long addr, int type);static int put_elf_str(Section *s, const char *sym);static int put_elf_sym(Section *s,                        unsigned long value, unsigned long size,                       int info, int other, int shndx, const char *name);static int add_elf_sym(Section *s, unsigned long value, unsigned long size,                       int info, int sh_num, const char *name);static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,                          int type, int symbol);static void put_stabs(const char *str, int type, int other, int desc,                       unsigned long value);static void put_stabs_r(const char *str, int type, int other, int desc,                         unsigned long value, Section *sec, int sym_index);static void put_stabn(int type, int other, int desc, int value);static void put_stabd(int type, int other, int desc);static int tcc_add_dll(TCCState *s, const char *filename, int flags);#define AFF_PRINT_ERROR     0x0001 /* print error if file not found */#define AFF_REFERENCED_DLL  0x0002 /* load a referenced dll from another dll */static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);/* tcccoff.c */int tcc_output_coff(TCCState *s1, FILE *f);/* tccasm.c */#ifdef CONFIG_TCC_ASMtypedef struct ExprValue {    uint32_t v;    Sym *sym;} ExprValue;#define MAX_ASM_OPERANDS 30typedef 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;static void asm_expr(TCCState *s1, ExprValue *pe);static int asm_int_expr(TCCState *s1);static int find_constraint(ASMOperand *operands, int nb_operands,                            const char *name, const char **pp);static int tcc_assemble(TCCState *s1, int do_preprocess);#endifstatic void asm_instr(void);static void asm_global_instr(void);/* 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;}#ifdef TCC_TARGET_I386#include "i386-gen.c"#endif#ifdef TCC_TARGET_ARM#include "arm-gen.c"#endif#ifdef TCC_TARGET_C67#include "c67-gen.c"#endif#ifdef CONFIG_TCC_STATIC#define RTLD_LAZY       0x001#define RTLD_NOW        0x002#define RTLD_GLOBAL     0x100#define RTLD_DEFAULT    NULL/* dummy function for profiling */void *dlopen(const char *filename, int flag){    return NULL;}const char *dlerror(void){    return "error";}typedef struct TCCSyms {    char *str;    void *ptr;} TCCSyms;#define TCCSYM(a) { #a, &a, },/* add the symbol you want here if no dynamic linking is done */static TCCSyms tcc_syms[] = {#if !defined(CONFIG_TCCBOOT)    TCCSYM(printf)    TCCSYM(fprintf)    TCCSYM(fopen)    TCCSYM(fclose)#endif    { NULL, NULL },};void *dlsym(void *handle, const char *symbol){    TCCSyms *p;    p = tcc_syms;    while (p->str != NULL) {        if (!strcmp(p->str, symbol))            return p->ptr;        p++;    }    return NULL;}#endif/********************************************************//* we use our own 'finite' function to avoid potential problems with   non standard math libs *//* XXX: endianness dependent */int ieee_finite(double d){    int *p = (int *)&d;    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;}/* copy a string and truncate it. */static char *pstrcpy(char *buf, int buf_size, const char *s){    char *q, *q_end;    int c;    if (buf_size > 0) {        q = buf;        q_end = buf + buf_size - 1;        while (q < q_end) {            c = *s++;            if (c == '\0')                break;            *q++ = c;        }        *q = '\0';    }    return buf;}/* strcat and truncate. */static char *pstrcat(char *buf, int buf_size, const char *s){    int len;    len = strlen(buf);    if (len < buf_size)         pstrcpy(buf + len, buf_size - len, s);    return buf;}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++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -