X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCval.c;h=6a0095016df7888cb417d2f73b62ae103b09f24d;hb=830f8429290c5ab30fe839957c7f62af51f482c9;hp=a0d5e15c31b90aebdb88f2112aaf271fa3f8812e;hpb=238e1b53dc1ac88bd559c93bd7f355d0887d39e1;p=fw%2Fsdcc diff --git a/src/SDCCval.c b/src/SDCCval.c index a0d5e15c..6a009501 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "newalloc.h" int cNestLevel; @@ -57,6 +58,7 @@ newiList (int type, void *ilist) nilist->type = type; nilist->lineno = mylineno; + nilist->filename = currFname; switch (type) { @@ -102,16 +104,16 @@ convertIListToConstList(initList *src, literalList **lList) { initList *iLoop; literalList *head, *last, *newL; - + head = last = NULL; - + if (!src || src->type != INIT_DEEP) { - return FALSE; + return FALSE; } - + iLoop = src->init.deep; - + while (iLoop) { if (iLoop->type != INIT_NODE) @@ -119,7 +121,7 @@ convertIListToConstList(initList *src, literalList **lList) return FALSE; } - if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_CHECK))) + if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE))) { return FALSE; } @@ -143,7 +145,7 @@ convertIListToConstList(initList *src, literalList **lList) newL->literalValue = val; newL->count = 1; newL->next = NULL; - + if (last) { last->next = newL; @@ -156,12 +158,12 @@ convertIListToConstList(initList *src, literalList **lList) } iLoop = iLoop->next; } - - if (!head) + + if (!head) { return FALSE; } - + *lList = head; return TRUE; } @@ -170,17 +172,17 @@ literalList * copyLiteralList(literalList *src) { literalList *head, *prev, *newL; - + head = prev = NULL; - + while (src) { newL = Safe_alloc(sizeof(literalList)); - + newL->literalValue = src->literalValue; newL->count = src->count; newL->next = NULL; - + if (prev) { prev->next = newL; @@ -192,7 +194,7 @@ copyLiteralList(literalList *src) prev = newL; src = src->next; } - + return head; } @@ -279,7 +281,7 @@ resolveIvalSym (initList * ilist, sym_link * type) if (ilist->type == INIT_NODE) { if (IS_PTR (type)) - resultType = RESULT_TYPE_NONE; + resultType = RESULT_TYPE_INT; else resultType = getResultTypeFromType (getSpec (type)); ilist->init.node = decorateType (resolveSymbols (ilist->init.node), @@ -332,7 +334,7 @@ static value *cheapestVal (value *val) { TYPE_DWORD sval=0; TYPE_UDWORD uval=0; - if (IS_FLOAT(val->type) || IS_CHAR(val->type)) + if (IS_FLOAT(val->type) || IS_FIXED(val->type) || IS_CHAR(val->type)) return val; if (SPEC_LONG(val->type)) { @@ -383,7 +385,7 @@ static value *cheapestVal (value *val) { static value *cheapestVal (value *val) { - if (IS_FLOAT (val->type) || IS_CHAR (val->type)) + if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type)) return val; /* - signed/unsigned must not be changed. @@ -460,6 +462,29 @@ constFloatVal (char *s) return val; } +/*-----------------------------------------------------------------*/ +/* constFixed16x16Val - converts a FIXED16X16 constant to value */ +/*-----------------------------------------------------------------*/ +value * +constFixed16x16Val (char *s) +{ + value *val = newValue (); + double sval; + + if (sscanf (s, "%lf", &sval) != 1) + { + werror (E_INVALID_FLOAT_CONST, s); + return constVal ("0"); + } + + val->type = val->etype = newLink (SPECIFIER); + SPEC_NOUN (val->type) = V_FLOAT; + SPEC_SCLS (val->type) = S_LITERAL; + SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval ); + + return val; +} + /*-----------------------------------------------------------------*/ /* constVal - converts an INTEGER constant into a cheapest value */ /*-----------------------------------------------------------------*/ @@ -467,8 +492,6 @@ value *constVal (char *s) { value *val; short hex = 0, octal = 0; - char scanFmt[10]; - int scI = 0; double dval; val = newValue (); /* alloc space for value */ @@ -485,74 +508,79 @@ value *constVal (char *s) if (!hex && *s == '0' && *(s + 1)) octal = 1; - /* create the scan string */ - scanFmt[scI++] = '%'; - - scanFmt[scI++] = 'l'; - - if (octal) - scanFmt[scI++] = 'o'; - else if (hex) - scanFmt[scI++] = 'x'; - else - scanFmt[scI++] = 'f'; - - scanFmt[scI++] = '\0'; - - if (octal || hex) { + errno = 0; + if (hex || octal) { unsigned long sval; - sscanf (s, scanFmt, &sval); + sval = strtoul (s, NULL, 0); dval=sval; + if (errno) { + dval = 4294967295.0; + werror (W_INVALID_INT_CONST, s, dval); + } } else { - sscanf (s, scanFmt, &dval); + sscanf (s, "%lf", &dval); } /* Setup the flags first */ - /* set the _long flag if 'lL' is found */ - if (strchr (s, 'l') || strchr (s, 'L')) { - SPEC_NOUN (val->type) = V_INT; - SPEC_LONG (val->type) = 1; - } - /* set the unsigned flag if 'uU' is found */ if (strchr (s, 'u') || strchr (s, 'U')) { SPEC_USIGN (val->type) = 1; } - if (dval<0) { // "-28u" will still be signed and negative - if (dval<-128) { // check if we have to promote to int - SPEC_NOUN (val->type) = V_INT; - } - if (dval<-32768) { // check if we have to promote to long int - SPEC_LONG (val->type) = 1; - } - } else { // >=0 - if (dval>0xff || /* check if we have to promote to int */ - SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned - char. After an integral promotion it will - be a signed int; this certainly isn't what - the programer wants */ - SPEC_NOUN (val->type) = V_INT; - } - else { /* store char's always as unsigned; this helps other optimizations */ - SPEC_USIGN (val->type) = 1; - } - if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long - SPEC_LONG (val->type) = 1; - } - else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int - if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */ - dval<=0xffff) { + /* set the b_long flag if 'lL' is found */ + if (strchr (s, 'l') || strchr (s, 'L')) { + SPEC_NOUN (val->type) = V_INT; + SPEC_LONG (val->type) = 1; + } else { + if (dval<0) { // "-28u" will still be signed and negative + if (dval<-128) { // check if we have to promote to int + SPEC_NOUN (val->type) = V_INT; + } + if (dval<-32768) { // check if we have to promote to long int + SPEC_LONG (val->type) = 1; + } + } else { // >=0 + if (dval>0xff || /* check if we have to promote to int */ + SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned + char. After an integral promotion it will + be a signed int; this certainly isn't what + the programer wants */ + SPEC_NOUN (val->type) = V_INT; + } + else { /* store char's always as unsigned; this helps other optimizations */ SPEC_USIGN (val->type) = 1; - } else { + } + if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long SPEC_LONG (val->type) = 1; - if (dval>0x7fffffff) { + } + else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int + if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */ + dval<=0xffff) { SPEC_USIGN (val->type) = 1; - } + } else { + SPEC_LONG (val->type) = 1; + if (dval>0x7fffffff) { + SPEC_USIGN (val->type) = 1; + } + } } } } + /* check for out of range */ + if (dval<-2147483648.0) { + dval = -2147483648.0; + werror (W_INVALID_INT_CONST, s, dval); + } + if (dval>2147483647.0 && !SPEC_USIGN (val->type)) { + dval = 2147483647.0; + werror (W_INVALID_INT_CONST, s, dval); + } + if (dval>4294967295.0) { + dval = 4294967295.0; + werror (W_INVALID_INT_CONST, s, dval); + } + if (SPEC_LONG (val->type)) { if (SPEC_USIGN (val->type)) @@ -591,9 +619,9 @@ unsigned char hexEscape(char **src) (*src)++ ; /* Skip over the 'x' */ s = *src ; /* Save for error detection */ - + value = strtol (*src, src, 16); - + if (s == *src) { // no valid hex found werror(E_INVALID_HEX); @@ -631,9 +659,9 @@ unsigned char octalEscape (char **str) { return value; } -/*! +/*! /fn int copyStr (char *dest, char *src) - + Copies a source string to a dest buffer interpreting escape sequences and special characters @@ -643,7 +671,7 @@ unsigned char octalEscape (char **str) { */ -int +int copyStr (char *dest, char *src) { @@ -692,7 +720,7 @@ copyStr (char *dest, char *src) src-- ; break; - case 'x': + case 'x': *dest++ = hexEscape(&src) ; src-- ; break ; @@ -950,6 +978,9 @@ floatFromVal (value * val) if (SPEC_NOUN (val->etype) == V_FLOAT) return (double) SPEC_CVAL (val->etype).v_float; + if (SPEC_NOUN (val->etype) == V_FIXED16X16) + return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 ); + if (SPEC_LONG (val->etype)) { if (SPEC_USIGN (val->etype)) @@ -995,6 +1026,8 @@ valUnaryPM (value * val) /* depending on type */ if (SPEC_NOUN (val->etype) == V_FLOAT) SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float; + if (SPEC_NOUN (val->etype) == V_FIXED16X16) + SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16; else { if (SPEC_LONG (val->etype)) @@ -1043,6 +1076,10 @@ valComplement (value * val) SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint; else SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int; + if (SPEC_NOUN(val->etype) == V_CHAR) + if ( SPEC_CVAL(val->etype).v_int < -128 + || SPEC_CVAL(val->etype).v_int > 127) + SPEC_NOUN(val->etype) = V_INT; } // ~(unsigned 3) now really is signed SPEC_USIGN(val->etype)=0; @@ -1083,16 +1120,17 @@ valMult (value * lval, value * rval) /* create a new value */ val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || - IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val->type = val->etype = computeType (lval->etype, + rval->etype, + RESULT_TYPE_INT, + '*'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval); + else + if (IS_FIXED16X16 (val->type)) + SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval)); /* signed and unsigned mul are the same, as long as the precision of the result isn't bigger than the precision of the operands. */ else if (SPEC_LONG (val->type)) @@ -1135,17 +1173,17 @@ valDiv (value * lval, value * rval) /* create a new value */ val = newValue (); - val->type = val->etype = newLink(SPECIFIER); - SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || - IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); - SPEC_SCLS (val->etype) = S_LITERAL; - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val->type = val->etype = computeType (lval->etype, + rval->etype, + RESULT_TYPE_INT, + '/'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval); + else + if (IS_FIXED16X16 (val->type)) + SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) ); else if (SPEC_LONG (val->type)) { if (SPEC_USIGN (val->type)) @@ -1176,14 +1214,12 @@ valMod (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - SPEC_NOUN (val->type) = V_INT; /* type is int */ - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + RESULT_TYPE_INT, + '%'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (SPEC_LONG (val->type)) { @@ -1215,17 +1251,18 @@ valPlus (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || - IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + RESULT_TYPE_INT, + '+'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval); + else + if (IS_FIXED16X16 (val->type)) + SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) ); else if (SPEC_LONG (val->type)) { if (SPEC_USIGN (val->type)) @@ -1256,17 +1293,18 @@ valMinus (value * lval, value * rval) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newLink (SPECIFIER); - SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || - IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, - rval->etype, - TRUE)); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + rval->etype, + RESULT_TYPE_INT, + '-'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ + if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval); + else + if (IS_FIXED16X16 (val->type)) + SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) ); else if (SPEC_LONG (val->type)) { if (SPEC_USIGN (val->type)) @@ -1297,14 +1335,12 @@ valShift (value * lval, value * rval, int lr) value *val; /* create a new value */ - val = newValue (); - val->type = val->etype = newIntLink (); - SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_NOUN (val->etype) = V_INT; - /* 'unsigned char' promotes to 'signed int' */ - if (!IS_CHAR (lval->etype)) - SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype); - SPEC_LONG (val->type) = SPEC_LONG (lval->etype); + val = newValue(); + val->type = val->etype = computeType (lval->etype, + NULL, + RESULT_TYPE_INT, + 'S'); + SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */ if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) && /* left shift */ @@ -1388,6 +1424,12 @@ valCompare (value * lval, value * rval, int ctype) { SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval); } + else + if (SPEC_NOUN(lval->type) == V_FIXED16X16 || + SPEC_NOUN(rval->type) == V_FIXED16X16) + { + SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval); + } else { /* integrals: ignore signedness */ @@ -1415,6 +1457,12 @@ valCompare (value * lval, value * rval, int ctype) { SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval); } + else + if (SPEC_NOUN(lval->type) == V_FIXED16X16 || + SPEC_NOUN(rval->type) == V_FIXED16X16) + { + SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval); + } else { /* integrals: ignore signedness */ @@ -1452,7 +1500,7 @@ valBitwise (value * lval, value * rval, int op) /* create a new value */ val = newValue (); - val->type = computeType (lval->etype, rval->etype, FALSE); + val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op); val->etype = getSpec (val->type); SPEC_SCLS (val->etype) = S_LITERAL; @@ -1521,7 +1569,7 @@ valBitwise (value * lval, value * rval, int op) } break; } - + return cheapestVal(val); } @@ -1568,7 +1616,13 @@ valCastLiteral (sym_link * dtype, double fval) return NULL; val = newValue (); - val->etype = getSpec (val->type = copyLinkChain (dtype)); + if (dtype) + val->etype = getSpec (val->type = copyLinkChain (dtype)); + else + { + val->etype = val->type = newLink (SPECIFIER); + SPEC_NOUN (val->etype) = V_VOID; + } SPEC_SCLS (val->etype) = S_LITERAL; /* if it is not a specifier then we can assume that */ @@ -1580,6 +1634,14 @@ valCastLiteral (sym_link * dtype, double fval) if (SPEC_NOUN (val->etype) == V_FLOAT) SPEC_CVAL (val->etype).v_float = fval; + else if (SPEC_NOUN (val->etype) == V_FIXED16X16) + SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval ); + else if (SPEC_NOUN (val->etype) == V_BIT || + SPEC_NOUN (val->etype) == V_SBIT) + SPEC_CVAL (val->etype).v_uint = l ? 1 : 0; + else if (SPEC_NOUN (val->etype) == V_BITFIELD) + SPEC_CVAL (val->etype).v_uint = l & + (0xffffu >> (16 - SPEC_BLEN (val->etype))); else if (SPEC_NOUN (val->etype) == V_CHAR) { if (SPEC_USIGN (val->etype)) SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l; @@ -1701,7 +1763,7 @@ valForArray (ast * arrExpr) DCL_TYPE (val->type) = EEPPOINTER; else DCL_TYPE (val->type) = POINTER; - val->type->next = arrExpr->left->ftype; + val->type->next = arrExpr->left->ftype->next; val->etype = getSpec (val->type); return val; }