X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.h;h=c85d1d6e10f0a65bf88c24e71ce687525aeee00e;hb=HEAD;hp=c24d6d99304fc7a7fc926ce1178bce390fe2d225;hpb=3d82fa71091d058893f8de85ffb2560a653be90e;p=fw%2Fsdcc diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index c24d6d99..c85d1d6e 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -1,24 +1,24 @@ /*------------------------------------------------------------------------- - SDCCsymt.h - Header file for Symbols table related structures and MACRO's. - Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) + SDCCsymt.h - Header file for Symbols table related structures and MACRO's. + Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) 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, 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #ifndef SDCCSYMT_H @@ -29,9 +29,10 @@ #define SDCC_NAME_MAX 3*SDCC_SYMNAME_MAX // big enough for ___etc #include "SDCChasht.h" #include "SDCCglobl.h" +#include "dbuf.h" -#define INTNO_MAX 255 /* maximum allowed interrupt number */ -#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ +#define INTNO_MAX 255 /* maximum allowed interrupt number */ +#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ #define BITVAR_PAD -1 @@ -41,6 +42,7 @@ enum { TYPEOF_CHAR, TYPEOF_LONG, TYPEOF_FLOAT, + TYPEOF_FIXED16X16, TYPEOF_BIT, TYPEOF_BITFIELD, TYPEOF_SBIT, @@ -58,35 +60,42 @@ enum { TYPEOF_EEPPOINTER }; -// values for first byte of generic pointer. -#define GPTYPE_NEAR 0 -#define GPTYPE_FAR 1 -#define GPTYPE_CODE 2 -#define GPTYPE_XSTACK 3 -#define GPTYPE_GPTR 4 // Never used? -#define GPTYPE_IDATA 5 +// values for first byte (or 3 most significant bits) of generic pointer. +#if 0 +#define GPTYPE_FAR 0x00 +#define GPTYPE_NEAR 0x40 +#define GPTYPE_XSTACK 0x60 +#define GPTYPE_CODE 0x80 +#else +#define GPTYPE_FAR (port->gp_tags.tag_far) +#define GPTYPE_NEAR (port->gp_tags.tag_near) +#define GPTYPE_XSTACK (port->gp_tags.tag_xstack) +#define GPTYPE_CODE (port->gp_tags.tag_code) +#endif #define HASHTAB_SIZE 256 /* hash table bucket */ typedef struct bucket { - void *sym; /* pointer to the object */ - char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ - int level; /* nest level for this symbol */ - int block; /* belongs to which block */ - struct bucket *prev; /* ptr 2 previous bucket */ - struct bucket *next; /* ptr 2 next bucket */ + void *sym; /* pointer to the object */ + char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ + int level; /* nest level for this symbol */ + int block; /* belongs to which block */ + struct bucket *prev; /* ptr 2 previous bucket */ + struct bucket *next; /* ptr 2 next bucket */ } bucket; typedef struct structdef { - char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ - unsigned char level; /* Nesting level */ - struct symbol *fields; /* pointer to fields */ - unsigned size; /* sizeof the table in bytes */ - int type; /* STRUCT or UNION */ + char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ + unsigned char level; /* Nesting level */ + struct symbol *fields; /* pointer to fields */ + unsigned size; /* sizeof the table in bytes */ + int type; /* STRUCT or UNION */ + bool b_flexArrayMember; /* has got an flexible array member, + only needed for syntax checks */ } structdef; @@ -95,6 +104,7 @@ typedef enum { V_INT = 1, V_FLOAT, + V_FIXED16X16, V_CHAR, V_VOID, V_STRUCT, @@ -127,55 +137,66 @@ typedef enum } STORAGE_CLASS; +#define TYPE_TARGET_CHAR TYPE_BYTE +#define TYPE_TARGET_INT TYPE_WORD +#define TYPE_TARGET_LONG TYPE_DWORD +#define TYPE_TARGET_UCHAR TYPE_UBYTE +#define TYPE_TARGET_UINT TYPE_UWORD +#define TYPE_TARGET_ULONG TYPE_UDWORD + /* specifier is the last in the type-chain */ typedef struct specifier { - NOUN noun; /* CHAR INT STRUCTURE LABEL */ - STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ - struct memmap *oclass; /* output storage class */ - unsigned _long:1; /* 1=long */ - unsigned _short:1; /* 1=short int */ - unsigned _unsigned:1; /* 1=unsigned, 0=signed */ - unsigned _signed:1; /* just for sanity checks only*/ - unsigned _static:1; /* 1=static keyword found */ - unsigned _extern:1; /* 1=extern found */ - unsigned _absadr:1; /* absolute address specfied */ - unsigned _volatile:1; /* is marked as volatile */ - unsigned _const:1; /* is a constant */ - unsigned _typedef:1; /* is typedefed */ - unsigned _isregparm:1; /* is the first parameter */ - unsigned _isenum:1; /* is an enumerated type */ - unsigned _addr; /* address of symbol */ - unsigned _stack; /* stack offset for stacked v */ - unsigned _bitStart; /* bit start position */ - int _bitLength; /* bit length */ - int argreg; /* reg no for regparm */ + NOUN noun; /* CHAR INT STRUCTURE LABEL */ + STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ + struct memmap *oclass; /* output storage class */ + unsigned b_long:1; /* 1=long */ + unsigned b_short:1; /* 1=short int */ + unsigned b_unsigned:1; /* 1=unsigned, 0=signed */ + unsigned b_signed:1; /* just for sanity checks only*/ + unsigned b_static:1; /* 1=static keyword found */ + unsigned b_extern:1; /* 1=extern found */ + unsigned b_inline:1; /* inline function requested */ + unsigned b_absadr:1; /* absolute address specfied */ + unsigned b_volatile:1; /* is marked as volatile */ + unsigned b_const:1; /* is a constant */ + unsigned b_restrict:1; /* is restricted */ + unsigned b_typedef:1; /* is typedefed */ + unsigned b_isregparm:1; /* is the first parameter */ + unsigned b_isenum:1; /* is an enumerated type */ + unsigned b_bitUnnamed:1; /* is an unnamed bit-field */ + unsigned _bitStart; /* bit start position */ + int _bitLength; /* bit length */ + unsigned _addr; /* address of symbol */ + unsigned _stack; /* stack offset for stacked v */ + int argreg; /* reg no for regparm */ union - { /* Values if constant or enum */ - TYPE_WORD v_int; /* 2 bytes: int and char values */ - char *v_char; /* character string */ - TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */ - TYPE_DWORD v_long; /* 4 bytes: long constant value */ - TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant val */ - double v_float; /* floating point constant value */ - struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */ + { /* Values if constant or enum */ + TYPE_TARGET_INT v_int; /* 2 bytes: int and char values */ + char *v_char; /* character string */ + TYPE_TARGET_UINT v_uint; /* 2 bytes: unsigned int const value */ + TYPE_TARGET_LONG v_long; /* 4 bytes: long constant value */ + TYPE_TARGET_ULONG v_ulong; /* 4 bytes: unsigned long constant value */ + double v_float; /* floating point constant value */ + TYPE_TARGET_ULONG v_fixed16x16; /* 4 bytes: fixed floating point constant value */ + struct symbol *v_enum; /* ptr to enum_list if enum==1 */ } const_val; - struct structdef *v_struct; /* structure pointer */ + struct structdef *v_struct; /* structure pointer */ } specifier; /* types of declarators */ typedef enum { - POINTER = 0, /* pointer to near data */ - FPOINTER, /* pointer to far data */ - CPOINTER, /* pointer to code space */ - GPOINTER, /* _generic pointer */ - PPOINTER, /* paged area pointer */ - IPOINTER, /* pointer to upper 128 bytes */ - UPOINTER, /* unknown pointer used only when parsing */ - EEPPOINTER, /* pointer to eeprom */ + POINTER = 0, /* pointer to near data */ + FPOINTER, /* pointer to far data */ + CPOINTER, /* pointer to code space */ + GPOINTER, /* _generic pointer */ + PPOINTER, /* paged area pointer */ + IPOINTER, /* pointer to upper 128 bytes */ + UPOINTER, /* unknown pointer used only when parsing */ + EEPPOINTER, /* pointer to eeprom */ ARRAY, FUNCTION } @@ -183,11 +204,13 @@ DECLARATOR_TYPE; typedef struct declarator { - DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ - unsigned int num_elem; /* # of elems if type==array */ - unsigned ptr_const:1; /* pointer is constant */ - unsigned ptr_volatile:1; /* pointer is volatile */ - struct sym_link *tspec; /* pointer type specifier */ + DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ + unsigned int num_elem; /* # of elems if type==array, */ + /* always 0 for flexible arrays */ + unsigned ptr_const:1; /* pointer is constant */ + unsigned ptr_volatile:1; /* pointer is volatile */ + unsigned ptr_restrict:1; /* pointer is resticted */ + struct sym_link *tspec; /* pointer type specifier */ } declarator; @@ -195,149 +218,165 @@ typedef enum { DECLARATOR=1, SPECIFIER } SYM_LINK_CLASS; -#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOW") +#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOWN") typedef struct sym_link { - SYM_LINK_CLASS class; /* DECLARATOR or SPECIFIER */ - unsigned tdef:1; /* current link created by */ + SYM_LINK_CLASS class; /* DECLARATOR or SPECIFIER */ + unsigned tdef:1; /* current link created by */ /* typedef if this flag is set */ union { - specifier s; /* if CLASS == SPECIFIER */ - declarator d; /* if CLASS == DECLARATOR */ + specifier s; /* if CLASS == SPECIFIER */ + declarator d; /* if CLASS == DECLARATOR */ } select; /* function attributes */ struct { - struct value *args; /* the defined arguments */ - unsigned hasVargs:1; /* functions has varargs */ - unsigned calleeSaves:1; /* functions uses callee save */ - unsigned hasbody:1; /* function body defined */ - unsigned hasFcall:1; /* does it call other functions */ - unsigned reent:1; /* function is reentrant */ - unsigned naked:1; /* naked function */ - - unsigned nonbanked:1; /* function has the nonbanked attribute */ - unsigned banked:1; /* function has the banked attribute */ - unsigned critical:1; /* critical function */ - unsigned intrtn:1; /* this is an interrupt routin */ - unsigned rbank:1; /* seperate register bank */ - unsigned intno; /* 1=Interrupt svc routine */ - unsigned regbank; /* register bank 2b used */ - unsigned builtin; /* is a builtin function */ - unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ - unsigned overlay; /* force parameters & locals into overlay segment */ - unsigned hasStackParms; /* function has parameters on stack */ + struct value *args; /* the defined arguments */ + unsigned hasVargs:1; /* functions has varargs */ + unsigned calleeSaves:1; /* functions uses callee save */ + unsigned hasbody:1; /* function body defined */ + unsigned hasFcall:1; /* does it call other functions */ + unsigned reent:1; /* function is reentrant */ + unsigned naked:1; /* naked function */ + + unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ + unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ + unsigned nonbanked:1; /* function has the nonbanked attribute */ + unsigned banked:1; /* function has the banked attribute */ + unsigned critical:1; /* critical function */ + unsigned intrtn:1; /* this is an interrupt routine */ + unsigned rbank:1; /* seperate register bank */ + unsigned inlinereq:1; /* inlining requested */ + unsigned intno; /* 1=Interrupt svc routine */ + short regbank; /* register bank 2b used */ + unsigned builtin; /* is a builtin function */ + unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ + unsigned overlay; /* force parameters & locals into overlay segment */ + unsigned hasStackParms; /* function has parameters on stack */ } funcAttrs; - struct sym_link *next; /* next element on the chain */ + struct sym_link *next; /* next element on the chain */ } sym_link; typedef struct symbol { - char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */ - char rname[SDCC_NAME_MAX + 1]; /* internal name */ + char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */ + char rname[SDCC_NAME_MAX + 1]; /* internal name */ - short level; /* declration lev,fld offset */ - short block; /* sequential block # of defintion */ + short level; /* declaration lev,fld offset */ + short block; /* sequential block # of definition */ int key; - unsigned implicit:1; /* implicit flag */ - unsigned undefined:1; /* undefined variable */ - unsigned _isparm:1; /* is a parameter */ - unsigned ismyparm:1; /* is parameter of the function being generated */ - unsigned isitmp:1; /* is an intermediate temp */ - unsigned islbl:1; /* is a temporary label */ - unsigned isref:1; /* has been referenced */ - unsigned isind:1; /* is a induction variable */ - unsigned isinvariant:1; /* is a loop invariant */ - unsigned cdef:1; /* compiler defined symbol */ - unsigned addrtaken:1; /* address of the symbol was taken */ - unsigned isreqv:1; /* is the register quivalent of a symbol */ - unsigned udChked:1; /* use def checking has been already done */ + unsigned flexArrayLength; /* if the symbol specifies a struct + with a "flexible array member", then the additional length in bytes for + the "fam" is stored here. Because the length can be different from symbol + to symbol AND v_struct isn't copied in copyLinkChain(), it's located here + in the symbol and not in v_struct or the declarator */ + unsigned implicit:1; /* implicit flag */ + unsigned undefined:1; /* undefined variable */ + unsigned infertype:1; /* type should be inferred from first assign */ + unsigned _isparm:1; /* is a parameter */ + unsigned ismyparm:1; /* is parameter of the function being generated */ + unsigned isitmp:1; /* is an intermediate temp */ + unsigned islbl:1; /* is a temporary label */ + unsigned isref:1; /* has been referenced */ + unsigned isind:1; /* is a induction variable */ + unsigned isinvariant:1; /* is a loop invariant */ + unsigned cdef:1; /* compiler defined symbol */ + unsigned addrtaken:1; /* address of the symbol was taken */ + unsigned isreqv:1; /* is the register equivalent of a symbol */ + unsigned udChked:1; /* use def checking has been already done */ + unsigned generated:1; /* code generated (function symbols only) */ /* following flags are used by the backend for code generation and can be changed if a better scheme for backend is thought of */ - unsigned isLiveFcall:1; /* is live at or across a function call */ - unsigned isspilt:1; /* has to be spilt */ - unsigned spillA:1; /* spilt be register allocator */ - unsigned remat:1; /* can be remateriazed */ - unsigned isptr:1; /* is a pointer */ - unsigned uptr:1; /* used as a pointer */ - unsigned isFree:1; /* used by register allocator */ - unsigned islocal:1; /* is a local variable */ - unsigned blockSpil:1; /* spilt at block level */ - unsigned remainSpil:1; /* spilt because not used in remainder */ - unsigned stackSpil:1; /* has been spilt on temp stack location */ - unsigned onStack:1; /* this symbol allocated on the stack */ - unsigned iaccess:1; /* indirect access */ - unsigned ruonly:1; /* used in return statement only */ - unsigned spildir:1; /* spilt in direct space */ - unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ - unsigned noSpilLoc:1; /* cannot be assigned a spil location */ - unsigned isstrlit; /* is a string literal and it's usage count */ - unsigned accuse; /* can be left in the accumulator - On the Z80 accuse is devided into - ACCUSE_A and ACCUSE_HL as the idea - is quite similar. - */ - unsigned dptr; /* 8051 variants with multiple DPTRS - currently implemented in DS390 only - */ - int allocreq ; /* allocation is required for this variable */ - int stack; /* offset on stack */ - int xstack; /* offset on xternal stack */ - short nRegs; /* number of registers required */ - short regType; /* type of register required */ - - struct regs *regs[4]; /* can have at the most 4 registers */ - struct asmop *aop; /* asmoperand for this symbol */ - struct iCode *fuse; /* furthest use */ - struct iCode *rematiCode; /* rematerialse with which instruction */ - struct operand *reqv; /* register equivalent of a local variable */ - struct symbol *prereqv; /* symbol before register equiv. substituion */ - struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ + unsigned isLiveFcall:1; /* is live at or across a function call */ + unsigned isspilt:1; /* has to be spilt */ + unsigned spillA:1; /* spilt be register allocator */ + unsigned remat:1; /* can be remateriazed */ + unsigned isptr:1; /* is a pointer */ + unsigned uptr:1; /* used as a pointer */ + unsigned isFree:1; /* used by register allocator */ + unsigned islocal:1; /* is a local variable */ + unsigned blockSpil:1; /* spilt at block level */ + unsigned remainSpil:1; /* spilt because not used in remainder */ + unsigned stackSpil:1; /* has been spilt on temp stack location */ + unsigned onStack:1; /* this symbol allocated on the stack */ + unsigned iaccess:1; /* indirect access */ + unsigned ruonly:1; /* used in return statement only */ + unsigned spildir:1; /* spilt in direct space */ + unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ + unsigned noSpilLoc:1; /* cannot be assigned a spil location */ + unsigned isstrlit; /* is a string literal and it's usage count */ + unsigned accuse; /* can be left in the accumulator + On the Z80 accuse is divided into + ACCUSE_A and ACCUSE_HL as the idea + is quite similar. + */ + unsigned dptr; /* 8051 variants with multiple DPTRS + currently implemented in DS390 only + */ + int allocreq ; /* allocation is required for this variable */ + int stack; /* offset on stack */ + int xstack; /* offset on xternal stack */ + short nRegs; /* number of registers required */ + short regType; /* type of register required */ + + struct regs *regs[4]; /* can have at the most 4 registers */ + struct asmop *aop; /* asmoperand for this symbol */ + struct iCode *fuse; /* furthest use */ + struct iCode *rematiCode; /* rematerialise with which instruction */ + struct operand *reqv; /* register equivalent of a local variable */ + struct symbol *prereqv; /* symbol before register equiv. substitution */ + struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ union { - struct symbol *spillLoc; /* register spil location */ - struct set *itmpStack; /* symbols spilt @ this stack location */ + struct symbol *spillLoc; /* register spil location */ + struct set *itmpStack; /* symbols spilt @ this stack location */ } usl; - short bitVar; /* this is a bit variable */ - unsigned offset; /* offset from top if struct */ - - int lineDef; /* defined line number */ - char *fileDef; /* defined filename */ - int lastLine; /* for functions the last line */ - struct sym_link *type; /* 1st link to declator chain */ - struct sym_link *etype; /* last link to declarator chn */ - struct symbol *next; /* crosslink to next symbol */ - struct symbol *localof; /* local variable of which function */ - struct initList *ival; /* ptr to initializer if any */ - struct bitVect *defs; /* bit vector for definitions */ - struct bitVect *uses; /* bit vector for uses */ - struct bitVect *regsUsed; /* for functions registers used */ - int liveFrom; /* live from iCode sequence number */ - int liveTo; /* live to sequence number */ - int used; /* no. of times this was used */ - int recvSize; /* size of first argument */ - struct bitVect *clashes; /* overlaps with what other symbols */ + char bitVar; /* if bitVar != 0: this is a bit variable, bitVar is the size in bits */ + char bitUnnamed:1; /* unnamed bit variable */ + unsigned offset; /* offset from top if struct */ + + int lineDef; /* defined line number */ + char *fileDef; /* defined filename */ + int lastLine; /* for functions the last line */ + struct sym_link *type; /* 1st link to declarator chain */ + struct sym_link *etype; /* last link to declarator chain */ + struct symbol *next; /* crosslink to next symbol */ + struct symbol *localof; /* local variable of which function */ + struct initList *ival; /* ptr to initializer if any */ + struct bitVect *defs; /* bit vector for definitions */ + struct bitVect *uses; /* bit vector for uses */ + struct bitVect *regsUsed; /* for functions registers used */ + int liveFrom; /* live from iCode sequence number */ + int liveTo; /* live to sequence number */ + int used; /* no. of times this was used */ + int recvSize; /* size of first argument */ + struct bitVect *clashes; /* overlaps with what other symbols */ + struct ast * funcTree; /* function body ast if inlined */ } symbol; -extern sym_link *validateLink(sym_link *l, - const char *macro, - const char *args, - const char select, - const char *file, - unsigned line); +extern sym_link *validateLink(sym_link *l, + const char *macro, + const char *args, + const char select, + const char *file, + unsigned line); /* Easy Access Macros */ +#define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly) +#define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse) + #define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type #define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem #define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const #define DCL_PTR_VOLATILE(l) validateLink(l, "DCL_PTR_VOLATILE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_volatile +#define DCL_PTR_RESTRICT(l) validateLink(l, "DCL_PTR_RESTRICT", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_restrict #define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec #define FUNC_DEBUG //assert(IS_FUNC(x)); @@ -357,9 +396,15 @@ extern sym_link *validateLink(sym_link *l, #define FUNC_INTNO(x) (x->funcAttrs.intno) #define FUNC_REGBANK(x) (x->funcAttrs.regbank) #define FUNC_HASSTACKPARM(x) (x->funcAttrs.hasStackParms) +#define FUNC_ISINLINE(x) (x->funcAttrs.inlinereq) +#define IFFUNC_ISINLINE(x) (IS_FUNC(x) && FUNC_ISINLINE(x)) #define FUNC_ISREENT(x) (x->funcAttrs.reent) #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x)) +#define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs) +#define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x)) +#define FUNC_ISWPARAM(x) (x->funcAttrs.wparam) +#define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x)) #define FUNC_ISNAKED(x) (x->funcAttrs.naked) #define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x)) #define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked) @@ -376,79 +421,86 @@ extern sym_link *validateLink(sym_link *l, #define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x)) #define IFFUNC_ISBANKEDCALL(x) (!IFFUNC_NONBANKED(x) && \ - (options.model == MODEL_LARGE || \ - options.model == MODEL_MEDIUM || \ + (options.model == MODEL_HUGE || \ + ((options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \ + (TARGET_IS_Z80 || TARGET_IS_GBZ80)) || \ IFFUNC_BANKED(x))) #define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun -#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._long -#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._short -#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._unsigned +#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_long +#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_short +#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_unsigned #define SPEC_SCLS(x) validateLink(x, "SPEC_SCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.sclass -#define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s._isenum +#define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isenum #define SPEC_OCLS(x) validateLink(x, "SPEC_OCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.oclass -#define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s._static -#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._extern +#define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_static +#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_extern #define SPEC_CODE(x) validateLink(x, "SPEC_CODE", #x, SPECIFIER, __FILE__, __LINE__)->select.s._codesg -#define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s._absadr +#define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_absadr #define SPEC_BANK(x) validateLink(x, "SPEC_BANK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._regbank #define SPEC_ADDR(x) validateLink(x, "SPEC_ADDR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._addr #define SPEC_STAK(x) validateLink(x, "SPEC_STAK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._stack #define SPEC_CVAL(x) validateLink(x, "SPEC_CVAL", #x, SPECIFIER, __FILE__, __LINE__)->select.s.const_val #define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart #define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength +#define SPEC_BUNNAMED(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_bitUnnamed -/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on +/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on * function type symbols, which obviously cannot - * be of BIT type. Therefore, we recycle the + * be of BIT type. Therefore, we recycle the * _bitStart field instead of defining a new field. */ #define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart -#define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._volatile -#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._const +#define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_volatile +#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_const +#define SPEC_RESTRICT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_restrict #define SPEC_STRUCT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.v_struct -#define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._typedef -#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._isregparm +#define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_typedef +#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isregparm #define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg +#define SPEC_INLINE(x) validateLink(x, "SPEC_INLINE", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_inline /* type check macros */ -#define IS_DECL(x) ( x && x->class == DECLARATOR ) +#define IS_DECL(x) ( x && x->class == DECLARATOR ) #define IS_SPEC(x) ( x && x->class == SPECIFIER ) #define IS_ARRAY(x) (IS_DECL(x) && DCL_TYPE(x) == ARRAY) #define IS_DATA_PTR(x) (IS_DECL(x) && DCL_TYPE(x) == POINTER) #define IS_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \ DCL_TYPE(x) == FPOINTER || \ - DCL_TYPE(x) == GPOINTER || \ - DCL_TYPE(x) == IPOINTER || \ - DCL_TYPE(x) == PPOINTER || \ - DCL_TYPE(x) == EEPPOINTER || \ + DCL_TYPE(x) == GPOINTER || \ + DCL_TYPE(x) == IPOINTER || \ + DCL_TYPE(x) == PPOINTER || \ + DCL_TYPE(x) == EEPPOINTER || \ DCL_TYPE(x) == CPOINTER || \ DCL_TYPE(x) == UPOINTER )) #define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x)) +#define IS_PTR_RESTRICT(x) (IS_PTR(x) && DCL_PTR_RESTRICT(x)) #define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER) #define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER) #define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER) +#define IS_FUNCPTR(x) (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next)) #define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION) -#define IS_LONG(x) (IS_SPEC(x) && x->select.s._long) -#define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s._unsigned) -#define IS_TYPEDEF(x)(IS_SPEC(x) && x->select.s._typedef) +#define IS_LONG(x) (IS_SPEC(x) && x->select.s.b_long) +#define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s.b_unsigned) +#define IS_TYPEDEF(x)(IS_SPEC(x) && x->select.s.b_typedef) #define IS_CONSTANT(x) (!x ? 0 : \ IS_SPEC(x) ? \ - x->select.s._const : \ + x->select.s.b_const : \ x->select.d.ptr_const) #define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT) -#define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s._absadr ) +#define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s.b_absadr ) #define IS_REGISTER(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER) #define IS_RENT(x) (IS_SPEC(x) && x->select.s._reent ) #define IS_STATIC(x) (IS_SPEC(x) && SPEC_STAT(x)) +#define IS_INLINE(x) (IS_SPEC(x) && SPEC_INLINE(x)) #define IS_INT(x) (IS_SPEC(x) && x->select.s.noun == V_INT) #define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID) #define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR) -#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s._extern) +#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s.b_extern) #define IS_VOLATILE(x) (!x ? 0 : \ - IS_SPEC(x) ? \ - x->select.s._volatile : \ - x->select.d.ptr_volatile) + IS_SPEC(x) ? \ + x->select.s.b_volatile : \ + x->select.d.ptr_volatile) #define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \ x->select.s.noun == V_CHAR || \ x->select.s.noun == V_BITFIELD || \ @@ -456,12 +508,14 @@ extern sym_link *validateLink(sym_link *l, x->select.s.noun == V_SBIT )) #define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD)) #define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \ - x->select.s.noun == V_BIT || \ + x->select.s.noun == V_BIT || \ x->select.s.noun == V_SBIT )) #define IS_BIT(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \ x->select.s.noun == V_SBIT )) #define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT) -#define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x)) +#define IS_FIXED16X16(x) (IS_SPEC(x) && x->select.s.noun == V_FIXED16X16) +#define IS_FIXED(x) (IS_FIXED16X16(x)) +#define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x) || IS_FIXED(x)) #define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x)) #define IS_LITERAL(x) (IS_SPEC(x) && x->select.s.sclass == S_LITERAL) #define IS_CODE(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_CODE) @@ -487,36 +541,49 @@ extern symbol *__fslteq; extern symbol *__fsgt; extern symbol *__fsgteq; -/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ -extern symbol *__muldiv[3][3][2]; +extern symbol *__fps16x16_add; +extern symbol *__fps16x16_sub; +extern symbol *__fps16x16_mul; +extern symbol *__fps16x16_div; +extern symbol *__fps16x16_eq; +extern symbol *__fps16x16_neq; +extern symbol *__fps16x16_lt; +extern symbol *__fps16x16_lteq; +extern symbol *__fps16x16_gt; +extern symbol *__fps16x16_gteq; + +/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED/BOTH */ +extern symbol *__muldiv[3][3][4]; /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */ extern sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ extern symbol *__conv[2][3][2]; +/* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */ +extern symbol *__fp16x16conv[2][4][2]; /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ extern symbol *__rlrr[2][3][2]; -#define CHARTYPE __multypes[0][0] -#define UCHARTYPE __multypes[0][1] -#define INTTYPE __multypes[1][0] -#define UINTTYPE __multypes[1][1] -#define LONGTYPE __multypes[2][0] -#define ULONGTYPE __multypes[2][1] - +#define CHARTYPE __multypes[0][0] +#define UCHARTYPE __multypes[0][1] +#define INTTYPE __multypes[1][0] +#define UINTTYPE __multypes[1][1] +#define LONGTYPE __multypes[2][0] +#define ULONGTYPE __multypes[2][1] extern sym_link *floatType; +extern sym_link *fixed16x16Type; #include "SDCCval.h" typedef enum { - RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ - RESULT_CHECK = 0, /* TODO: replace all occurences with the appropriate type and remove me */ + RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ RESULT_TYPE_BIT, RESULT_TYPE_CHAR, RESULT_TYPE_INT, - RESULT_TYPE_OTHER, /* operands will be promoted to int */ + RESULT_TYPE_OTHER, /* operands will be promoted to int */ RESULT_TYPE_IFX, + RESULT_TYPE_GPTR, /* operands will be promoted to generic ptr */ } RESULT_TYPE; /* forward definitions for the symbol table related functions */ @@ -535,7 +602,6 @@ void printSymChain (symbol *, int); void printStruct (structdef *, int); char *genSymName (int); sym_link *getSpec (sym_link *); -char *genSymName (int); int compStructSize (int, structdef *); sym_link *copyLinkChain (sym_link *); int checkDecl (symbol *, int); @@ -545,24 +611,26 @@ value *checkStructIval (symbol *, value *); value *checkArrayIval (sym_link *, value *); value *checkIval (sym_link *, value *); unsigned int getSize (sym_link *); -unsigned int getAllocSize (sym_link *); unsigned int bitsForType (sym_link *); sym_link *newIntLink (); sym_link *newCharLink (); sym_link *newLongLink (); +sym_link *newBoolLink (); int compareType (sym_link *, sym_link *); int compareTypeExact (sym_link *, sym_link *, int); int checkFunction (symbol *, symbol *); void cleanUpLevel (bucket **, int); void cleanUpBlock (bucket **, int); int funcInChain (sym_link *); -void addSymChain (symbol *); +void addSymChain (symbol **); sym_link *structElemType (sym_link *, value *); symbol *getStructElement (structdef *, symbol *); sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int); +void processFuncPtrArgs (sym_link *); void processFuncArgs (symbol *); int isSymbolEqual (symbol *, symbol *); -int powof2 (TYPE_UDWORD); +int powof2 (TYPE_TARGET_ULONG); +void dbuf_printTypeChain (sym_link *, struct dbuf_s *); void printTypeChain (sym_link *, FILE *); void printTypeChainRaw (sym_link *, FILE *); void initCSupport ();