X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCsymt.c;h=172acf8060459d5e42d30cf370a5eed597a3d2f6;hb=c7669c4c702bdd4d3a05678a825ac81d9cfd28ca;hp=fe796ebb42610ae515a405b50d78189337eb7596;hpb=a1c6a8c341f0ddb164e3f0bb2723c6a1b86c7065;p=fw%2Fsdcc diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index fe796ebb..172acf80 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -43,10 +43,11 @@ char *nounName(sym_link *sl) { { case V_INT: { if (SPEC_LONG(sl)) return "long"; - if (sl->select.s._short) return "short"; + if (SPEC_SHORT(sl)) return "short"; return "int"; } case V_FLOAT: return "float"; + case V_FIXED16X16: return "fixed16x16"; case V_CHAR: return "char"; case V_VOID: return "void"; case V_STRUCT: return "struct"; @@ -541,24 +542,26 @@ void checkTypeSanity(sym_link *etype, char *name) { if ((SPEC_NOUN(etype)==V_CHAR || SPEC_NOUN(etype)==V_FLOAT || + SPEC_NOUN(etype)==V_FIXED16X16 || SPEC_NOUN(etype)==V_DOUBLE || SPEC_NOUN(etype)==V_VOID) && - (etype->select.s._short || SPEC_LONG(etype))) { + (SPEC_SHORT(etype) || SPEC_LONG(etype))) { // long or short for char float double or void werror (E_LONG_OR_SHORT_INVALID, noun, name); } if ((SPEC_NOUN(etype)==V_FLOAT || + SPEC_NOUN(etype)==V_FIXED16X16 || SPEC_NOUN(etype)==V_DOUBLE || SPEC_NOUN(etype)==V_VOID) && - (etype->select.s._signed || SPEC_USIGN(etype))) { + (etype->select.s.b_signed || SPEC_USIGN(etype))) { // signed or unsigned for float double or void werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name); } // special case for "short" - if (etype->select.s._short) { + if (SPEC_SHORT(etype)) { SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT; - etype->select.s._short = 0; + SPEC_SHORT(etype) = 0; } /* if no noun e.g. @@ -572,15 +575,15 @@ void checkTypeSanity(sym_link *etype, char *name) { /* a "plain" int bitfield is unsigned */ if (SPEC_NOUN(etype)==V_BIT || SPEC_NOUN(etype)==V_SBIT) { - if (!etype->select.s._signed) + if (!etype->select.s.b_signed) SPEC_USIGN(etype) = 1; } - if (etype->select.s._signed && SPEC_USIGN(etype)) { + if (etype->select.s.b_signed && SPEC_USIGN(etype)) { // signed AND unsigned werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name); } - if (etype->select.s._short && SPEC_LONG(etype)) { + if (SPEC_SHORT(etype) && SPEC_LONG(etype)) { // short AND long werror (E_LONG_AND_SHORT_INVALID, noun, name); } @@ -642,9 +645,9 @@ mergeSpec (sym_link * dest, sym_link * src, char *name) // but there are more important thing right now SPEC_LONG (dest) |= SPEC_LONG (src); - dest->select.s._short|=src->select.s._short; + SPEC_SHORT(dest) |= SPEC_SHORT(src); SPEC_USIGN (dest) |= SPEC_USIGN (src); - dest->select.s._signed|=src->select.s._signed; + dest->select.s.b_signed|=src->select.s.b_signed; SPEC_STAT (dest) |= SPEC_STAT (src); SPEC_EXTR (dest) |= SPEC_EXTR (src); SPEC_CONST(dest) |= SPEC_CONST (src); @@ -735,6 +738,20 @@ newFloatLink () return p; } +/*------------------------------------------------------------------*/ +/* newFixed16x16Link - a new Float type */ +/*------------------------------------------------------------------*/ +sym_link * +newFixed16x16Link () +{ + sym_link *p; + + p = newLink (SPECIFIER); + SPEC_NOUN (p) = V_FIXED16X16; + + return p; +} + /*------------------------------------------------------------------*/ /* newLongLink() - new long type */ /*------------------------------------------------------------------*/ @@ -765,7 +782,21 @@ newIntLink () } /*------------------------------------------------------------------*/ -/* getSize - returns size of a type chain in bits */ +/* newBoolLink() - creates an bool type */ +/*------------------------------------------------------------------*/ +sym_link * +newBoolLink () +{ + sym_link *p; + + p = newLink (SPECIFIER); + SPEC_NOUN (p) = V_BIT; + + return p; +} + +/*------------------------------------------------------------------*/ +/* getSize - returns size of a type chain in bytes */ /*------------------------------------------------------------------*/ unsigned int getSize (sym_link * p) @@ -781,6 +812,8 @@ getSize (sym_link * p) return (IS_LONG (p) ? LONGSIZE : INTSIZE); case V_FLOAT: return FLOATSIZE; + case V_FIXED16X16: + return (4); case V_CHAR: return CHARSIZE; case V_VOID: @@ -818,7 +851,7 @@ getSize (sym_link * p) case FPOINTER: case CPOINTER: case FUNCTION: - return (FPTRSIZE); + return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE); case GPOINTER: return (GPTRSIZE); @@ -827,29 +860,41 @@ getSize (sym_link * p) } } -/*---------------------------------------------------------------------*/ -/* getAllocSize - returns size of a type chain in bytes for allocation */ -/*---------------------------------------------------------------------*/ -unsigned int -getAllocSize (sym_link *p) +/*------------------------------------------------------------------*/ +/* checkStructFlexArray - check tree behind a struct */ +/*------------------------------------------------------------------*/ +static bool +checkStructFlexArray (symbol *sym, sym_link *p) { - if (IS_STRUCT (p) && SPEC_STRUCT (p)->type == STRUCT) - { - /* if this is a struct specifier then */ - /* calculate the size as it could end */ - /* with an array of unspecified length */ - symbol *sflds = SPEC_STRUCT (p)->fields; + /* if nothing return FALSE */ + if (!p) + return FALSE; - while (sflds && sflds->next) - sflds = sflds->next; + if (IS_SPEC (p)) + { + /* (nested) struct with flexible array member? */ + if (IS_STRUCT (p) && SPEC_STRUCT (p)->b_flexArrayMember) + { + werror (W_INVALID_FLEXARRAY); + return FALSE; + } + return FALSE; + } - if (sflds && !IS_BITFIELD (sflds->type)) - return sflds->offset + getAllocSize (sflds->type); - else - return SPEC_STRUCT (p)->size; + /* this is a declarator */ + if (IS_ARRAY (p)) + { + /* flexible array member? */ + if (!DCL_ELEM(p)) + { + if (!options.std_c99) + werror (W_C89_NO_FLEXARRAY); + return TRUE; + } + /* walk tree */ + return checkStructFlexArray (sym, p->next); } - else - return getSize (p); + return FALSE; } /*------------------------------------------------------------------*/ @@ -871,6 +916,8 @@ bitsForType (sym_link * p) return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8); case V_FLOAT: return FLOATSIZE * 8; + case V_FIXED16X16: + return (32); case V_CHAR: return CHARSIZE * 8; case V_VOID: @@ -1198,7 +1245,11 @@ compStructSize (int su, structdef * sdef) /* change it to a unsigned bit */ SPEC_NOUN (loop->etype) = V_BITFIELD; - SPEC_USIGN (loop->etype) = 1; + /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */ + /* a "plain" int bitfield is unsigned */ + if (!loop->etype->select.s.b_signed) + SPEC_USIGN(loop->etype) = 1; + SPEC_BLEN (loop->etype) = loop->bitVar; if (loop->bitVar == BITVAR_PAD) { @@ -1253,6 +1304,21 @@ compStructSize (int su, structdef * sdef) loop->offset = sum; checkDecl (loop, 1); sum += getSize (loop->type); + + /* search for "flexibel array members" */ + /* and do some syntax checks */ + if ( su == STRUCT + && checkStructFlexArray (loop, loop->type)) + { + /* found a "flexible array member" */ + sdef->b_flexArrayMember = TRUE; + /* is another struct-member following? */ + if (loop->next) + werror (E_FLEXARRAY_NOTATEND); + /* is it the first struct-member? */ + else if (loop == sdef->fields) + werror (E_FLEXARRAY_INEMPTYSTRCT); + } } loop = loop->next; @@ -1457,16 +1523,18 @@ checkSClass (symbol * sym, int isProto) /* if this is an automatic symbol */ if (sym->level && (options.stackAuto || reentrant)) { - if ((SPEC_SCLS (sym->etype) == S_AUTO || - SPEC_SCLS (sym->etype) == S_FIXED || - SPEC_SCLS (sym->etype) == S_REGISTER || - SPEC_SCLS (sym->etype) == S_STACK || - SPEC_SCLS (sym->etype) == S_XSTACK)) { - SPEC_SCLS (sym->etype) = S_AUTO; - } else { - /* storage class may only be specified for statics */ - if (!IS_STATIC(sym->etype)) { - werror (E_AUTO_ASSUMED, sym->name); + if (SPEC_SCLS (sym->etype) != S_BIT) { + if ((SPEC_SCLS (sym->etype) == S_AUTO || + SPEC_SCLS (sym->etype) == S_FIXED || + SPEC_SCLS (sym->etype) == S_REGISTER || + SPEC_SCLS (sym->etype) == S_STACK || + SPEC_SCLS (sym->etype) == S_XSTACK)) { + SPEC_SCLS (sym->etype) = S_AUTO; + } else { + /* storage class may only be specified for statics */ + if (!IS_STATIC(sym->etype)) { + werror (E_AUTO_ASSUMED, sym->name); + } } } } @@ -1484,6 +1552,7 @@ checkSClass (symbol * sym, int isProto) /* arrays & pointers cannot be defined for bits */ /* SBITS or SFRs or BIT */ if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) && + !IS_FUNCPTR (sym->type) && (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT || SPEC_NOUN (sym->etype) == V_BITFIELD || @@ -1545,13 +1614,14 @@ changePointer (sym_link * p) /* go thru the chain of declarations */ /* if we find a pointer to a function */ - /* unconditionally change it to a ptr */ - /* to code area */ + /* change it to a ptr to code area */ + /* unless the function is banked. */ for (; p; p = p->next) { if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER) DCL_TYPE (p) = port->unqualified_pointer; if (IS_PTR (p) && IS_FUNC (p->next)) + if (!IFFUNC_BANKED(p->next)) DCL_TYPE (p) = CPOINTER; } } @@ -1582,6 +1652,7 @@ copyLinkChain (sym_link * p) { sym_link *head, *curr, *loop; + /* note: v_struct and v_struct->fields are not copied! */ curr = p; head = loop = (curr ? newLink (p->class) : (void *) NULL); while (curr) @@ -1729,15 +1800,20 @@ computeType (sym_link * type1, sym_link * type2, /* which ever is greater in size */ if (IS_FLOAT (etype1) || IS_FLOAT (etype2)) rType = newFloatLink (); - else - /* if both are bitvars choose the larger one */ - if (IS_BITVAR (etype1) && IS_BITVAR (etype2)) - { - rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ? - copyLinkChain (type1) : copyLinkChain (type1); - } - /* if only one of them is a bit variable - then the other one prevails */ + /* if both are fixed16x16 then result is float */ + else if (IS_FIXED16X16(etype1) && IS_FIXED16X16(etype2)) + rType = newFixed16x16Link(); + else if (IS_FIXED16X16(etype1) && IS_FLOAT (etype2)) + rType = newFloatLink (); + else if (IS_FLOAT (etype1) && IS_FIXED16X16 (etype2) ) + rType = newFloatLink (); + + /* if both are bitvars choose the larger one */ + else if (IS_BITVAR (etype1) && IS_BITVAR (etype2)) + rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ? + copyLinkChain (type1) : copyLinkChain (type1); + + /* if only one of them is a bit variable then the other one prevails */ else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2)) { rType = copyLinkChain (type2); @@ -1752,10 +1828,9 @@ computeType (sym_link * type1, sym_link * type2, if (getSize (etype2) > 1) SPEC_NOUN (getSpec (rType)) = V_INT; } - else - /* if one of them is a pointer or array then that - prevails */ - if (IS_PTR (type1) || IS_ARRAY (type1)) + /* if one of them is a pointer or array then that + prevails */ + else if (IS_PTR (type1) || IS_ARRAY (type1)) rType = copyLinkChain (type1); else if (IS_PTR (type2) || IS_ARRAY (type2)) rType = copyLinkChain (type2); @@ -1767,7 +1842,7 @@ computeType (sym_link * type1, sym_link * type2, reType = getSpec (rType); /* avoid conflicting types */ - reType->select.s._signed = 0; + reType->select.s.b_signed = 0; /* if result is a literal then make not so */ if (IS_LITERAL (reType)) @@ -1914,6 +1989,16 @@ compareType (sym_link * dest, sym_link * src) { if (IS_DECL (src)) { + /* banked function pointer */ + if (IS_GENPTR (dest) && IS_GENPTR (src)) + { + if (IS_FUNC (src->next) && IS_VOID(dest->next)) + return -1; + if (IS_FUNC (dest->next) && IS_VOID(src->next)) + return -1; + return compareType (dest->next, src->next); + } + if (DCL_TYPE (src) == DCL_TYPE (dest)) { if (IS_FUNC(src)) { //checkFunction(src,dest); @@ -2300,13 +2385,6 @@ checkFunction (symbol * sym, symbol *csym) return 0; } - /* function cannot return bit */ - if (IS_BITVAR (sym->type->next)) - { - werror (E_FUNC_BIT, sym->name); - return 0; - } - /* check if this function is defined as calleeSaves then mark it as such */ FUNC_CALLEESAVES(sym->type) = inCalleeSaveList (sym->name); @@ -2537,7 +2615,7 @@ processFuncArgs (symbol * func) the function does not have VA_ARG and as port dictates */ if (!IFFUNC_HASVARARGS(funcType) && - (argreg = (*port->reg_parm) (val->type))) + (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType)))) { SPEC_REGPARM (val->etype) = 1; SPEC_ARGREG(val->etype) = argreg; @@ -2608,7 +2686,7 @@ processFuncArgs (symbol * func) SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit; else SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = - (options.model != MODEL_SMALL ? xdata : data); + port->mem.default_local_map; #if 0 /* ?? static functions shouldn't imply static parameters - EEP */ @@ -2618,6 +2696,8 @@ processFuncArgs (symbol * func) } #endif } + if (SPEC_OCLS (val->sym->etype) == pdata) + val->sym->iaccess = 1; if (!isinSet(operKeyReset, val->sym)) { addSet (&operKeyReset, val->sym); applyToSet (operKeyReset, resetParmKey); @@ -2793,6 +2873,10 @@ printTypeChain (sym_link * start, FILE * of) fprintf (of, "float"); break; + case V_FIXED16X16: + fprintf (of, "fixed16x16"); + break; + case V_STRUCT: fprintf (of, "struct %s", SPEC_STRUCT (type)->tag); break; @@ -2964,6 +3048,10 @@ printTypeChainRaw (sym_link * start, FILE * of) fprintf (of, "float"); break; + case V_FIXED16X16: + fprintf (of, "fixed16x16"); + break; + case V_STRUCT: fprintf (of, "struct %s", SPEC_STRUCT (type)->tag); break; @@ -3018,7 +3106,7 @@ powof2 (TYPE_UDWORD num) } if (n1s > 1 || nshifts == 0) - return 0; + return -1; return nshifts - 1; } @@ -3033,16 +3121,30 @@ symbol *__fslteq; symbol *__fsgt; symbol *__fsgteq; +symbol *__fps16x16_add; +symbol *__fps16x16_sub; +symbol *__fps16x16_mul; +symbol *__fps16x16_div; +symbol *__fps16x16_eq; +symbol *__fps16x16_neq; +symbol *__fps16x16_lt; +symbol *__fps16x16_lteq; +symbol *__fps16x16_gt; +symbol *__fps16x16_gteq; + /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ symbol *__muldiv[3][3][2]; /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */ sym_link *__multypes[3][2]; /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */ symbol *__conv[2][3][2]; +/* Dims: to/from fixed16x16, BYTE/WORD/DWORD/FLOAT, SIGNED/USIGNED */ +symbol *__fp16x16conv[2][4][2]; /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ symbol *__rlrr[2][3][2]; sym_link *floatType; +sym_link *fixed16x16Type; static char * _mangleFunctionName(char *in) @@ -3064,6 +3166,7 @@ _mangleFunctionName(char *in) /* 'i' - int */ /* 'l' - long */ /* 'f' - float */ +/* 'q' - fixed16x16 */ /* 'v' - void */ /* '*' - pointer - default (GPOINTER) */ /* modifiers - 'u' - unsigned */ @@ -3107,6 +3210,10 @@ sym_link *typeFromStr (char *s) r->class = SPECIFIER; SPEC_NOUN(r) = V_FLOAT; break; + case 'q': + r->class = SPECIFIER; + SPEC_NOUN(r) = V_FIXED16X16; + break; case 'v': r->class = SPECIFIER; SPEC_NOUN(r) = V_VOID; @@ -3172,7 +3279,11 @@ initCSupport () }; const char *sbwd[] = { - "char", "int", "long" + "char", "int", "long", "fixed16x16", + }; + const char *fp16x16sbwd[] = + { + "char", "int", "long", "float", }; const char *ssu[] = { @@ -3191,6 +3302,7 @@ initCSupport () } floatType = newFloatLink (); + fixed16x16Type = newFixed16x16Link (); for (bwd = 0; bwd < 3; bwd++) { @@ -3225,6 +3337,18 @@ initCSupport () __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent); __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent); + __fps16x16_add = funcOfType ("__fps16x16_add", fixed16x16Type, fixed16x16Type, 2, options.float_rent); + __fps16x16_sub = funcOfType ("__fps16x16_sub", fixed16x16Type, fixed16x16Type, 2, options.float_rent); + __fps16x16_mul = funcOfType ("__fps16x16_mul", fixed16x16Type, fixed16x16Type, 2, options.float_rent); + __fps16x16_div = funcOfType ("__fps16x16_div", fixed16x16Type, fixed16x16Type, 2, options.float_rent); + __fps16x16_eq = funcOfType ("__fps16x16_eq", CHARTYPE, fixed16x16Type, 2, options.float_rent); + __fps16x16_neq = funcOfType ("__fps16x16_neq", CHARTYPE, fixed16x16Type, 2, options.float_rent); + __fps16x16_lt = funcOfType ("__fps16x16_lt", CHARTYPE, fixed16x16Type, 2, options.float_rent); + __fps16x16_lteq = funcOfType ("__fps16x16_lteq", CHARTYPE, fixed16x16Type, 2, options.float_rent); + __fps16x16_gt = funcOfType ("__fps16x16_gt", CHARTYPE, fixed16x16Type, 2, options.float_rent); + __fps16x16_gteq = funcOfType ("__fps16x16_gteq", CHARTYPE, fixed16x16Type, 2, options.float_rent); + + for (tofrom = 0; tofrom < 2; tofrom++) { for (bwd = 0; bwd < 3; bwd++) @@ -3245,6 +3369,32 @@ initCSupport () } } + for (tofrom = 0; tofrom < 2; tofrom++) + { + for (bwd = 0; bwd < 4; bwd++) + { + for (su = 0; su < 2; su++) + { + if (tofrom) + { + SNPRINTF (buffer, sizeof(buffer), "__fps16x162%s%s", ssu[su], fp16x16sbwd[bwd]); + if(bwd == 3) { + __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, floatType, fixed16x16Type, 1, options.float_rent); + } else + __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], fixed16x16Type, 1, options.float_rent); + } + else + { + SNPRINTF (buffer, sizeof(buffer), "__%s%s2fps16x16", ssu[su], fp16x16sbwd[bwd]); + if(bwd == 3) { + __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, floatType, 1, options.float_rent); + } else + __fp16x16conv[tofrom][bwd][su] = funcOfType (buffer, fixed16x16Type, __multypes[bwd][su], 1, options.float_rent); + } + } + } + } + /* for (muldivmod = 0; muldivmod < 3; muldivmod++) {