1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value */
37 /*-----------------------------------------------------------------*/
43 val = Safe_alloc (sizeof (value));
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list */
50 /*-----------------------------------------------------------------*/
52 newiList (int type, void *ilist)
57 nilist = Safe_alloc (sizeof (initList));
60 nilist->lineno = lineno;
61 nilist->filename = filename;
66 nilist->init.node = (struct ast *) ilist;
70 nilist->init.deep = (struct initList *) ilist;
77 /*------------------------------------------------------------------*/
78 /* revinit - reverses the initial values for a value chain */
79 /*------------------------------------------------------------------*/
81 revinit (initList * val)
83 initList *prev, *curr, *next;
98 val->next = (void *) NULL;
103 convertIListToConstList(initList *src, literalList **lList)
106 literalList *head, *last, *newL;
110 if (!src || src->type != INIT_DEEP)
115 iLoop = src->init.deep;
119 if (iLoop->type != INIT_NODE)
124 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
131 // We've now established that the initializer list contains only literal values.
133 iLoop = src->init.deep;
136 double val = AST_LIT_VALUE(iLoop->init.node);
138 if (last && last->literalValue == val)
144 newL = Safe_alloc(sizeof(literalList));
145 newL->literalValue = val;
172 copyLiteralList(literalList *src)
174 literalList *head, *prev, *newL;
180 newL = Safe_alloc(sizeof(literalList));
182 newL->literalValue = src->literalValue;
183 newL->count = src->count;
203 /*------------------------------------------------------------------*/
204 /* copyIlist - copy initializer list */
205 /*------------------------------------------------------------------*/
207 copyIlist (initList * src)
209 initList *dest = NULL;
217 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
220 dest = newiList (INIT_NODE, copyAst (src->init.node));
225 dest->next = copyIlist (src->next);
230 /*------------------------------------------------------------------*/
231 /* list2int - converts the first element of the list to value */
232 /*------------------------------------------------------------------*/
234 list2int (initList * val)
238 if (i->type == INIT_DEEP)
239 return list2int (val->init.deep);
241 return floatFromVal (constExprValue (val->init.node, TRUE));
244 /*------------------------------------------------------------------*/
245 /* list2val - converts the first element of the list to value */
246 /*------------------------------------------------------------------*/
248 list2val (initList * val)
253 if (val->type == INIT_DEEP)
254 return list2val (val->init.deep);
256 return constExprValue (val->init.node, TRUE);
259 /*------------------------------------------------------------------*/
260 /* list2expr - returns the first expression in the initializer list */
261 /*------------------------------------------------------------------*/
263 list2expr (initList * ilist)
265 if (ilist->type == INIT_DEEP)
266 return list2expr (ilist->init.deep);
267 return ilist->init.node;
270 /*------------------------------------------------------------------*/
271 /* resolveIvalSym - resolve symbols in initial values */
272 /*------------------------------------------------------------------*/
274 resolveIvalSym (initList * ilist, sym_link * type)
276 RESULT_TYPE resultType;
281 if (ilist->type == INIT_NODE)
284 resultType = RESULT_TYPE_INT;
286 resultType = getResultTypeFromType (getSpec (type));
287 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
291 if (ilist->type == INIT_DEEP)
292 resolveIvalSym (ilist->init.deep, type);
294 resolveIvalSym (ilist->next, type);
297 /*-----------------------------------------------------------------*/
298 /* symbolVal - creates a value for a symbol */
299 /*-----------------------------------------------------------------*/
301 symbolVal (symbol * sym)
313 val->type = sym->type;
314 val->etype = getSpec (val->type);
319 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
323 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
329 /*--------------------------------------------------------------------*/
330 /* cheapestVal - try to reduce 'signed int' to 'char' */
331 /*--------------------------------------------------------------------*/
333 cheapestVal (value *val)
335 /* only int can be reduced */
336 if (!IS_INT(val->type))
339 /* long must not be changed */
340 if (SPEC_LONG(val->type))
343 /* unsigned must not be changed */
344 if (SPEC_USIGN(val->type))
347 /* the only possible reduction is from signed int to (un)signed char,
348 because it's automatically promoted back to signed int.
350 a reduction from unsigned int to unsigned char is a bug,
351 because an _unsigned_ char is promoted to _signed_ int! */
352 if (SPEC_CVAL(val->type).v_int < -128 ||
353 SPEC_CVAL(val->type).v_int > 255)
355 /* not in the range of (un)signed char */
359 SPEC_NOUN(val->type) = V_CHAR;
361 /* 'unsigned char' promotes to 'signed int', so that we can
362 reduce it the other way */
363 if (SPEC_CVAL(val->type).v_int >= 0)
365 SPEC_USIGN(val->type) = 1;
370 /*--------------------------------------------------------------------*/
371 /* checkConstantRange - check if constant fits in numeric range of */
372 /* var type in comparisons and assignments */
373 /*--------------------------------------------------------------------*/
375 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
381 litVal = floatFromVal (valFromType (lit));
382 varBits = bitsForType (var);
389 return CCR_ALWAYS_FALSE;
391 return CCR_ALWAYS_TRUE;
393 /* special: assignment */
399 if (getenv ("SDCC_VERY_PEDANTIC"))
401 if (SPEC_USIGN (var))
403 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
412 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
413 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
423 /* ignore signedness, e.g. allow everything
424 from -127...+255 for (unsigned) char */
425 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
426 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
435 if (exchangeLeftRight)
440 case '>': op = '<'; break;
441 case GE_OP: op = LE_OP; break;
442 case '<': op = '>'; break;
443 case LE_OP: op = GE_OP; break;
444 default: return CCR_ALWAYS_FALSE;
447 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
449 if (SPEC_USIGN (reType))
451 /* unsigned operation */
452 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
453 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
455 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
457 /* both operands are unsigned, this is easy */
459 maxValP = 0xffffffffu >> (32 - varBits);
460 /* there's only range, just copy it to 2nd set */
464 else if (SPEC_USIGN (var))
466 /* lit is casted from signed to unsigned, e.g.:
472 maxValP = 0xffffffffu >> (32 - varBits);
473 /* there's only one range, just copy it to 2nd set */
477 /* it's an unsigned operation */
478 if ( IS_CHAR (reType)
481 /* make signed literal unsigned and
482 limit no of bits to size of return type */
483 litVal = (TYPE_TARGET_ULONG) litVal & opBitsMask;
486 else /* SPEC_USIGN (lit) */
488 /* var is casted from signed to unsigned, e.g.:
493 The possible values after casting var
494 split up in two, nonconsecutive ranges:
496 minValP = 0; positive range: 0...127
498 minValM = 0xff80; negative range: -128...-1
504 maxValP = 0x7fffffffu >> (32 - varBits);
507 minValM = 0xffffffff << (varBits - 1);
508 maxValM = 0xffffffffu; /* -1 */
509 /* limit no of bits to size of return type */
510 minValM &= opBitsMask;
511 maxValM &= opBitsMask;
516 case EQ_OP: /* var == lit */
517 if ( litVal <= maxValP
518 && litVal >= minValP) /* 0 */
520 if ( litVal <= maxValM
521 && litVal >= minValM)
523 return CCR_ALWAYS_FALSE;
524 case NE_OP: /* var != lit */
525 if ( litVal <= maxValP
526 && litVal >= minValP) /* 0 */
528 if ( litVal <= maxValM
529 && litVal >= minValM)
531 return CCR_ALWAYS_TRUE;
532 case '>': /* var > lit */
533 if (litVal >= maxValM)
534 return CCR_ALWAYS_FALSE;
535 if (litVal < minValP) /* 0 */
536 return CCR_ALWAYS_TRUE;
538 case GE_OP: /* var >= lit */
539 if (litVal > maxValM)
540 return CCR_ALWAYS_FALSE;
541 if (litVal <= minValP) /* 0 */
542 return CCR_ALWAYS_TRUE;
544 case '<': /* var < lit */
545 if (litVal > maxValM)
546 return CCR_ALWAYS_TRUE;
547 if (litVal <= minValP) /* 0 */
548 return CCR_ALWAYS_FALSE;
550 case LE_OP: /* var <= lit */
551 if (litVal >= maxValM)
552 return CCR_ALWAYS_TRUE;
553 if (litVal < minValP) /* 0 */
554 return CCR_ALWAYS_FALSE;
557 return CCR_ALWAYS_FALSE;
562 /* signed operation */
563 TYPE_TARGET_LONG minVal, maxVal;
565 if (SPEC_USIGN (var))
567 /* unsigned var, but signed operation. This happens
568 when var is promoted to signed int.
569 Set actual min/max values of var. */
571 maxVal = 0xffffffff >> (32 - varBits);
576 minVal = 0xffffffff << (varBits - 1);
577 maxVal = 0x7fffffff >> (32 - varBits);
582 case EQ_OP: /* var == lit */
585 return CCR_ALWAYS_FALSE;
587 case NE_OP: /* var != lit */
590 return CCR_ALWAYS_TRUE;
592 case '>': /* var > lit */
593 if (litVal >= maxVal)
594 return CCR_ALWAYS_FALSE;
596 return CCR_ALWAYS_TRUE;
598 case GE_OP: /* var >= lit */
600 return CCR_ALWAYS_FALSE;
601 if (litVal <= minVal)
602 return CCR_ALWAYS_TRUE;
604 case '<': /* var < lit */
606 return CCR_ALWAYS_TRUE;
607 if (litVal <= minVal)
608 return CCR_ALWAYS_FALSE;
610 case LE_OP: /* var <= lit */
611 if (litVal >= maxVal)
612 return CCR_ALWAYS_TRUE;
614 return CCR_ALWAYS_FALSE;
617 return CCR_ALWAYS_FALSE;
622 /*-----------------------------------------------------------------*/
623 /* valueFromLit - creates a value from a literal */
624 /*-----------------------------------------------------------------*/
626 valueFromLit (double lit)
630 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
632 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
633 return constVal (buffer);
636 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
637 return constFloatVal (buffer);
640 /*-----------------------------------------------------------------*/
641 /* constFloatVal - converts a FLOAT constant to value */
642 /*-----------------------------------------------------------------*/
644 constFloatVal (char *s)
646 value *val = newValue ();
649 if (sscanf (s, "%lf", &sval) != 1)
651 werror (E_INVALID_FLOAT_CONST, s);
652 return constVal ("0");
655 val->type = val->etype = newLink (SPECIFIER);
656 SPEC_NOUN (val->type) = V_FLOAT;
657 SPEC_SCLS (val->type) = S_LITERAL;
658 SPEC_CVAL (val->type).v_float = sval;
663 /*-----------------------------------------------------------------*/
664 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
665 /*-----------------------------------------------------------------*/
667 constFixed16x16Val (char *s)
669 value *val = newValue ();
672 if (sscanf (s, "%lf", &sval) != 1)
674 werror (E_INVALID_FLOAT_CONST, s);
675 return constVal ("0");
678 val->type = val->etype = newLink (SPECIFIER);
679 SPEC_NOUN (val->type) = V_FLOAT;
680 SPEC_SCLS (val->type) = S_LITERAL;
681 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
686 /*-----------------------------------------------------------------*/
687 /* constVal - converts an INTEGER constant into a cheapest value */
688 /*-----------------------------------------------------------------*/
689 value *constVal (const char *s)
692 short hex = 0, octal = 0;
695 val = newValue (); /* alloc space for value */
697 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
698 SPEC_SCLS (val->type) = S_LITERAL;
699 // let's start with a signed char
700 SPEC_NOUN (val->type) = V_CHAR;
701 SPEC_USIGN (val->type) = 0;
703 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
705 /* set the octal flag */
706 if (!hex && *s == '0' && *(s + 1))
712 sval = strtoul (s, NULL, 0);
716 werror (W_INVALID_INT_CONST, s, dval);
719 sscanf (s, "%lf", &dval);
722 /* Setup the flags first */
723 /* set the unsigned flag if 'uU' is found */
724 if (strchr (s, 'u') || strchr (s, 'U')) {
725 SPEC_USIGN (val->type) = 1;
728 /* set the b_long flag if 'lL' is found */
729 if (strchr (s, 'l') || strchr (s, 'L')) {
730 SPEC_NOUN (val->type) = V_INT;
731 SPEC_LONG (val->type) = 1;
733 if (dval<0) { // "-28u" will still be signed and negative
734 if (dval<-128) { // check if we have to promote to int
735 SPEC_NOUN (val->type) = V_INT;
737 if (dval<-32768) { // check if we have to promote to long int
738 SPEC_LONG (val->type) = 1;
741 if (dval>0xff || /* check if we have to promote to int */
742 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
743 char. After an integral promotion it will
744 be a signed int; this certainly isn't what
745 the programer wants */
746 SPEC_NOUN (val->type) = V_INT;
748 else { /* store char's always as unsigned; this helps other optimizations */
749 SPEC_USIGN (val->type) = 1;
751 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
752 SPEC_LONG (val->type) = 1;
754 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
755 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
757 SPEC_USIGN (val->type) = 1;
759 SPEC_LONG (val->type) = 1;
760 if (dval>0x7fffffff) {
761 SPEC_USIGN (val->type) = 1;
768 /* check for out of range */
769 if (dval<-2147483648.0) {
770 dval = -2147483648.0;
771 werror (W_INVALID_INT_CONST, s, dval);
773 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
775 werror (W_INVALID_INT_CONST, s, dval);
777 if (dval>4294967295.0) {
779 werror (W_INVALID_INT_CONST, s, dval);
782 if (SPEC_LONG (val->type))
784 if (SPEC_USIGN (val->type))
786 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG)dval;
790 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG)dval;
795 if (SPEC_USIGN (val->type))
797 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT)dval;
801 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT)dval;
808 /*! /fn char hexEscape(char **src)
810 /param src Pointer to 'x' from start of hex character value
813 unsigned char hexEscape(const char **src)
816 unsigned long value ;
818 (*src)++ ; /* Skip over the 'x' */
820 value = strtol (*src, &s, 16);
823 // no valid hex found
824 werror(E_INVALID_HEX);
827 werror(W_ESC_SEQ_OOR_FOR_CHAR);
833 /*------------------------------------------------------------------*/
834 /* octalEscape - process an octal constant of max three digits */
835 /* return the octal value, throw a warning for illegal octal */
836 /* adjust src to point at the last proccesed char */
837 /*------------------------------------------------------------------*/
839 unsigned char octalEscape (const char **str) {
843 for (digits=0; digits<3; digits++) {
844 if (**str>='0' && **str<='7') {
845 value = value*8 + (**str-'0');
852 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
853 werror (W_ESC_SEQ_OOR_FOR_CHAR);
860 /fn int copyStr (char *dest, char *src)
862 Copies a source string to a dest buffer interpreting escape sequences
863 and special characters
865 /param dest Buffer to receive the resultant string
866 /param src Buffer containing the source string with escape sequecnes
867 /return Number of characters in output string
872 copyStr (char *dest, const char *src)
875 char *OriginalDest = dest ;
881 else if (*src == '\\')
916 *dest++ = octalEscape(&src);
921 *dest++ = hexEscape(&src) ;
948 return dest - OriginalDest ;
951 /*------------------------------------------------------------------*/
952 /* strVal - converts a string constant to a value */
953 /*------------------------------------------------------------------*/
955 strVal (const char *s)
959 val = newValue (); /* get a new one */
961 /* get a declarator */
962 val->type = newLink (DECLARATOR);
963 DCL_TYPE (val->type) = ARRAY;
964 val->type->next = val->etype = newLink (SPECIFIER);
965 SPEC_NOUN (val->etype) = V_CHAR;
966 SPEC_SCLS (val->etype) = S_LITERAL;
968 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
969 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
975 /*------------------------------------------------------------------*/
976 /* reverseValWithType - reverses value chain with type & etype */
977 /*------------------------------------------------------------------*/
979 reverseValWithType (value * val)
987 /* save the type * etype chains */
991 /* set the current one 2b null */
992 val->type = val->etype = NULL;
993 val = reverseVal (val);
995 /* restore type & etype */
1002 /*------------------------------------------------------------------*/
1003 /* reverseVal - reverses the values for a value chain */
1004 /*------------------------------------------------------------------*/
1006 reverseVal (value * val)
1008 value *prev, *curr, *next;
1023 val->next = (void *) NULL;
1027 /*------------------------------------------------------------------*/
1028 /* copyValueChain - will copy a chain of values */
1029 /*------------------------------------------------------------------*/
1031 copyValueChain (value * src)
1038 dest = copyValue (src);
1039 dest->next = copyValueChain (src->next);
1044 /*------------------------------------------------------------------*/
1045 /* copyValue - copies contents of a value to a fresh one */
1046 /*------------------------------------------------------------------*/
1048 copyValue (value * src)
1053 dest->sym = copySymbol (src->sym);
1054 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1055 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1056 dest->etype = (src->type ? getSpec (dest->type) : NULL);
1061 /*------------------------------------------------------------------*/
1062 /* charVal - converts a character constant to a value */
1063 /*------------------------------------------------------------------*/
1065 charVal (const char *s)
1071 val->type = val->etype = newLink (SPECIFIER);
1072 SPEC_NOUN (val->type) = V_CHAR;
1073 SPEC_USIGN(val->type) = 1;
1074 SPEC_SCLS (val->type) = S_LITERAL;
1076 s++; /* get rid of quotation */
1077 /* if \ then special processing */
1080 s++; /* go beyond the backslash */
1084 SPEC_CVAL (val->type).v_uint = '\n';
1087 SPEC_CVAL (val->type).v_uint = '\t';
1090 SPEC_CVAL (val->type).v_uint = '\v';
1093 SPEC_CVAL (val->type).v_uint = '\b';
1096 SPEC_CVAL (val->type).v_uint = '\r';
1099 SPEC_CVAL (val->type).v_uint = '\f';
1102 SPEC_CVAL (val->type).v_uint = '\a';
1105 SPEC_CVAL (val->type).v_uint = '\\';
1108 SPEC_CVAL (val->type).v_uint = '\?';
1111 SPEC_CVAL (val->type).v_uint = '\'';
1114 SPEC_CVAL (val->type).v_uint = '\"';
1125 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
1129 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
1133 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1137 else /* not a backslash */
1138 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1143 /*------------------------------------------------------------------*/
1144 /* valFromType - creates a value from type given */
1145 /*------------------------------------------------------------------*/
1147 valFromType (sym_link * type)
1149 value *val = newValue ();
1150 val->type = copyLinkChain (type);
1151 val->etype = getSpec (val->type);
1155 /*------------------------------------------------------------------*/
1156 /* floatFromVal - value to double float conversion */
1157 /*------------------------------------------------------------------*/
1159 floatFromVal (value * val)
1164 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1166 werror (E_CONST_EXPECTED, val->name);
1170 /* if it is not a specifier then we can assume that */
1171 /* it will be an unsigned long */
1172 if (!IS_SPEC (val->type))
1173 return (double) SPEC_CVAL (val->etype).v_ulong;
1175 if (SPEC_NOUN (val->etype) == V_FLOAT)
1176 return (double) SPEC_CVAL (val->etype).v_float;
1178 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1179 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1181 if (SPEC_LONG (val->etype))
1183 if (SPEC_USIGN (val->etype))
1184 return (double) SPEC_CVAL (val->etype).v_ulong;
1186 return (double) SPEC_CVAL (val->etype).v_long;
1189 if (SPEC_NOUN (val->etype) == V_INT) {
1190 if (SPEC_USIGN (val->etype))
1191 return (double) SPEC_CVAL (val->etype).v_uint;
1193 return (double) SPEC_CVAL (val->etype).v_int;
1196 if (SPEC_NOUN (val->etype) == V_CHAR) {
1197 if (SPEC_USIGN (val->etype))
1198 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1200 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1203 if (IS_BITVAR(val->etype)) {
1204 return (double) SPEC_CVAL (val->etype).v_uint;
1207 if (SPEC_NOUN (val->etype) == V_VOID) {
1208 return (double) SPEC_CVAL (val->etype).v_ulong;
1212 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1213 "floatFromVal: unknown value");
1217 /*-----------------------------------------------------------------*/
1218 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1219 /*-----------------------------------------------------------------*/
1220 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1223 /* This version is incorrect negative values. */
1224 double tmp=0, exp=2;
1226 tmp = (value & 0xffff0000) >> 16;
1230 if(value & 0x8000)tmp += 1/exp;
1237 return ((double)(value * 1.0) / (double)(1UL << 16));
1241 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1244 /* This version is incorrect negative values. */
1245 unsigned int tmp=0, pos=16;
1246 TYPE_TARGET_ULONG res;
1248 tmp = floor( value );
1255 if(value >= 1.0)tmp |= (1 << pos);
1256 value -= floor( value );
1263 return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
1267 /*------------------------------------------------------------------*/
1268 /* valUnaryPM - does the unary +/- operation on a constant */
1269 /*------------------------------------------------------------------*/
1271 valUnaryPM (value * val)
1273 /* depending on type */
1274 if (SPEC_NOUN (val->etype) == V_FLOAT)
1275 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1276 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1277 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1280 if (SPEC_LONG (val->etype))
1282 if (SPEC_USIGN (val->etype))
1283 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1285 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1289 if (SPEC_USIGN (val->etype))
1290 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1292 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1294 if (SPEC_NOUN(val->etype) == V_CHAR)
1296 /* promote to 'signed int', cheapestVal() might reduce it again */
1297 SPEC_USIGN(val->etype) = 0;
1298 SPEC_NOUN(val->etype) = V_INT;
1300 return cheapestVal (val);
1306 /*------------------------------------------------------------------*/
1307 /* valueComplement - complements a constant */
1308 /*------------------------------------------------------------------*/
1310 valComplement (value * val)
1312 /* depending on type */
1313 if (SPEC_LONG (val->etype))
1315 if (SPEC_USIGN (val->etype))
1316 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1318 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1322 if (SPEC_USIGN (val->etype))
1323 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1325 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1327 if (SPEC_NOUN(val->etype) == V_CHAR)
1329 /* promote to 'signed int', cheapestVal() might reduce it again */
1330 SPEC_USIGN(val->etype) = 0;
1331 SPEC_NOUN(val->etype) = V_INT;
1333 return cheapestVal (val);
1338 /*------------------------------------------------------------------*/
1339 /* valueNot - complements a constant */
1340 /*------------------------------------------------------------------*/
1342 valNot (value * val)
1344 /* depending on type */
1345 if (SPEC_LONG (val->etype))
1347 if (SPEC_USIGN (val->etype))
1348 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1350 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1354 if (SPEC_USIGN (val->etype))
1355 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1357 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1360 /* ANSI: result type is int, value is 0 or 1 */
1361 /* sdcc will hold this in an 'unsigned char' */
1362 SPEC_USIGN(val->etype) = 1;
1363 SPEC_LONG (val->etype) = 0;
1364 SPEC_NOUN(val->etype) = V_CHAR;
1368 /*------------------------------------------------------------------*/
1369 /* valMult - multiply constants */
1370 /*------------------------------------------------------------------*/
1372 valMult (value * lval, value * rval)
1376 /* create a new value */
1378 val->type = val->etype = computeType (lval->etype,
1382 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1384 if (IS_FLOAT (val->type))
1385 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1387 if (IS_FIXED16X16 (val->type))
1388 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1389 /* signed and unsigned mul are the same, as long as the precision of the
1390 result isn't bigger than the precision of the operands. */
1391 else if (SPEC_LONG (val->type))
1392 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
1393 (TYPE_TARGET_ULONG) floatFromVal (rval);
1394 else if (SPEC_USIGN (val->type)) /* unsigned int */
1396 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
1397 (TYPE_TARGET_UINT) floatFromVal (rval);
1399 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1400 if (ul != (TYPE_TARGET_UINT) ul)
1403 else /* signed int */
1405 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1406 (TYPE_TARGET_INT) floatFromVal (rval);
1408 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1409 if (l != (TYPE_TARGET_INT) l)
1412 return cheapestVal (val);
1415 /*------------------------------------------------------------------*/
1416 /* valDiv - Divide constants */
1417 /*------------------------------------------------------------------*/
1419 valDiv (value * lval, value * rval)
1423 if (floatFromVal (rval) == 0)
1425 werror (E_DIVIDE_BY_ZERO);
1429 /* create a new value */
1431 val->type = val->etype = computeType (lval->etype,
1435 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1437 if (IS_FLOAT (val->type))
1438 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1440 if (IS_FIXED16X16 (val->type))
1441 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1442 else if (SPEC_LONG (val->type))
1444 if (SPEC_USIGN (val->type))
1445 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
1446 (TYPE_TARGET_ULONG) floatFromVal (rval);
1448 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
1449 (TYPE_TARGET_LONG) floatFromVal (rval);
1453 if (SPEC_USIGN (val->type))
1454 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
1455 (TYPE_TARGET_UINT) floatFromVal (rval);
1457 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
1458 (TYPE_TARGET_INT) floatFromVal (rval);
1460 return cheapestVal (val);
1463 /*------------------------------------------------------------------*/
1464 /* valMod - Modulus constants */
1465 /*------------------------------------------------------------------*/
1467 valMod (value * lval, value * rval)
1471 /* create a new value */
1473 val->type = val->etype = computeType (lval->etype,
1477 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1479 if (SPEC_LONG (val->type))
1481 if (SPEC_USIGN (val->type))
1482 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
1483 (TYPE_TARGET_ULONG) floatFromVal (rval);
1485 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
1486 (TYPE_TARGET_LONG) floatFromVal (rval);
1490 if (SPEC_USIGN (val->type))
1491 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
1492 (TYPE_TARGET_UINT) floatFromVal (rval);
1494 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
1495 (TYPE_TARGET_INT) floatFromVal (rval);
1497 return cheapestVal (val);
1500 /*------------------------------------------------------------------*/
1501 /* valPlus - Addition constants */
1502 /*------------------------------------------------------------------*/
1504 valPlus (value * lval, value * rval)
1508 /* create a new value */
1510 val->type = val->etype = computeType (lval->etype,
1514 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1516 if (IS_FLOAT (val->type))
1517 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1519 if (IS_FIXED16X16 (val->type))
1520 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1521 else if (SPEC_LONG (val->type))
1523 if (SPEC_USIGN (val->type))
1524 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
1525 (TYPE_TARGET_ULONG) floatFromVal (rval);
1527 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
1528 (TYPE_TARGET_LONG) floatFromVal (rval);
1532 if (SPEC_USIGN (val->type))
1533 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
1534 (TYPE_TARGET_UINT) floatFromVal (rval);
1536 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
1537 (TYPE_TARGET_INT) floatFromVal (rval);
1539 return cheapestVal (val);
1542 /*------------------------------------------------------------------*/
1543 /* valMinus - Addition constants */
1544 /*------------------------------------------------------------------*/
1546 valMinus (value * lval, value * rval)
1550 /* create a new value */
1552 val->type = val->etype = computeType (lval->etype,
1556 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1558 if (IS_FLOAT (val->type))
1559 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1561 if (IS_FIXED16X16 (val->type))
1562 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1563 else if (SPEC_LONG (val->type))
1565 if (SPEC_USIGN (val->type))
1566 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
1567 (TYPE_TARGET_ULONG) floatFromVal (rval);
1569 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
1570 (TYPE_TARGET_LONG) floatFromVal (rval);
1574 if (SPEC_USIGN (val->type))
1575 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
1576 (TYPE_TARGET_UINT) floatFromVal (rval);
1578 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
1579 (TYPE_TARGET_INT) floatFromVal (rval);
1581 return cheapestVal (val);
1584 /*------------------------------------------------------------------*/
1585 /* valShift - Shift left or right */
1586 /*------------------------------------------------------------------*/
1588 valShift (value * lval, value * rval, int lr)
1592 /* create a new value */
1594 val->type = val->etype = computeType (lval->etype,
1598 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1600 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
1603 /* right shift and unsigned */
1604 (!lr && SPEC_USIGN (rval->type))))
1606 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1609 if (SPEC_LONG (val->type))
1611 if (SPEC_USIGN (val->type))
1613 SPEC_CVAL (val->type).v_ulong = lr ?
1614 (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1615 (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1619 SPEC_CVAL (val->type).v_long = lr ?
1620 (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1621 (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1626 if (SPEC_USIGN (val->type))
1628 SPEC_CVAL (val->type).v_uint = lr ?
1629 (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1630 (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1634 SPEC_CVAL (val->type).v_int = lr ?
1635 (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1636 (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1639 return cheapestVal (val);
1642 /*------------------------------------------------------------------*/
1643 /* valCompare- Compares two literal */
1644 /*------------------------------------------------------------------*/
1646 valCompare (value * lval, value * rval, int ctype)
1650 /* create a new value */
1652 val->type = val->etype = newCharLink ();
1653 val->type->class = SPECIFIER;
1654 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1655 SPEC_USIGN (val->type) = 1;
1656 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1661 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1665 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1669 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1673 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1677 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1678 SPEC_NOUN(rval->type) == V_FLOAT)
1680 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1683 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1684 SPEC_NOUN(rval->type) == V_FIXED16X16)
1686 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1690 /* integrals: ignore signedness */
1691 TYPE_TARGET_ULONG l, r;
1693 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1694 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1695 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1696 neccessary to strip them to 16 bit.
1697 Literals are reduced to their cheapest type, therefore left and
1698 right might have different types. It's neccessary to find a
1699 common type: int (used for char too) or long */
1700 if (!IS_LONG (lval->etype) &&
1701 !IS_LONG (rval->etype))
1703 r = (TYPE_TARGET_UINT) r;
1704 l = (TYPE_TARGET_UINT) l;
1706 SPEC_CVAL (val->type).v_int = l == r;
1710 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1711 SPEC_NOUN(rval->type) == V_FLOAT)
1713 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1716 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1717 SPEC_NOUN(rval->type) == V_FIXED16X16)
1719 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1723 /* integrals: ignore signedness */
1724 TYPE_TARGET_ULONG l, r;
1726 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1727 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1728 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1729 neccessary to strip them to 16 bit.
1730 Literals are reduced to their cheapest type, therefore left and
1731 right might have different types. It's neccessary to find a
1732 common type: int (used for char too) or long */
1733 if (!IS_LONG (lval->etype) &&
1734 !IS_LONG (rval->etype))
1736 r = (TYPE_TARGET_UINT) r;
1737 l = (TYPE_TARGET_UINT) l;
1739 SPEC_CVAL (val->type).v_int = l != r;
1748 /*------------------------------------------------------------------*/
1749 /* valBitwise - Bitwise operation */
1750 /*------------------------------------------------------------------*/
1752 valBitwise (value * lval, value * rval, int op)
1756 /* create a new value */
1758 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1759 val->etype = getSpec (val->type);
1760 SPEC_SCLS (val->etype) = S_LITERAL;
1765 if (SPEC_LONG (val->type))
1767 if (SPEC_USIGN (val->type))
1768 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
1769 (TYPE_TARGET_ULONG) floatFromVal (rval);
1771 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
1772 (TYPE_TARGET_LONG) floatFromVal (rval);
1776 if (SPEC_USIGN (val->type))
1777 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
1778 (TYPE_TARGET_UINT) floatFromVal (rval);
1780 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
1781 (TYPE_TARGET_INT) floatFromVal (rval);
1786 if (SPEC_LONG (val->type))
1788 if (SPEC_USIGN (val->type))
1789 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
1790 (TYPE_TARGET_ULONG) floatFromVal (rval);
1792 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
1793 (TYPE_TARGET_LONG) floatFromVal (rval);
1797 if (SPEC_USIGN (val->type))
1798 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
1799 (TYPE_TARGET_UINT) floatFromVal (rval);
1801 SPEC_CVAL (val->type).v_int =
1802 (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
1808 if (SPEC_LONG (val->type))
1810 if (SPEC_USIGN (val->type))
1811 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
1812 (TYPE_TARGET_ULONG) floatFromVal (rval);
1814 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
1815 (TYPE_TARGET_LONG) floatFromVal (rval);
1819 if (SPEC_USIGN (val->type))
1820 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
1821 (TYPE_TARGET_UINT) floatFromVal (rval);
1823 SPEC_CVAL (val->type).v_int =
1824 (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
1829 return cheapestVal(val);
1832 /*------------------------------------------------------------------*/
1833 /* valAndOr - Generates code for and / or operation */
1834 /*------------------------------------------------------------------*/
1836 valLogicAndOr (value * lval, value * rval, int op)
1840 /* create a new value */
1842 val->type = val->etype = newCharLink ();
1843 val->type->class = SPECIFIER;
1844 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1845 SPEC_USIGN (val->type) = 1;
1850 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1854 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1862 /*------------------------------------------------------------------*/
1863 /* valCastLiteral - casts a literal value to another type */
1864 /*------------------------------------------------------------------*/
1866 valCastLiteral (sym_link * dtype, double fval)
1869 TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
1876 val->etype = getSpec (val->type = copyLinkChain (dtype));
1879 val->etype = val->type = newLink (SPECIFIER);
1880 SPEC_NOUN (val->etype) = V_VOID;
1882 SPEC_SCLS (val->etype) = S_LITERAL;
1884 /* if it is not a specifier then we can assume that */
1885 /* it will be an unsigned long */
1886 if (!IS_SPEC (val->type)) {
1887 SPEC_CVAL (val->etype).v_ulong = l;
1891 if (SPEC_NOUN (val->etype) == V_FLOAT)
1892 SPEC_CVAL (val->etype).v_float = fval;
1893 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1894 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1895 else if (SPEC_NOUN (val->etype) == V_BIT ||
1896 SPEC_NOUN (val->etype) == V_SBIT)
1897 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1898 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1899 SPEC_CVAL (val->etype).v_uint = l &
1900 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1901 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1902 if (SPEC_USIGN (val->etype))
1903 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1905 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1907 if (SPEC_LONG (val->etype)) {
1908 if (SPEC_USIGN (val->etype))
1909 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1911 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1913 if (SPEC_USIGN (val->etype))
1914 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
1916 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
1922 /*------------------------------------------------------------------*/
1923 /* getNelements - determines # of elements from init list */
1924 /*------------------------------------------------------------------*/
1926 getNelements (sym_link * type, initList * ilist)
1933 if (ilist->type == INIT_DEEP)
1934 ilist = ilist->init.deep;
1936 /* if type is a character array and there is only one
1937 (string) initialiser then get the length of the string */
1938 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1940 ast *iast = ilist->init.node;
1941 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1944 werror (E_CONST_EXPECTED);
1948 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1949 // yep, it's a string
1951 return DCL_ELEM (v->type);
1959 ilist = ilist->next;
1964 /*-----------------------------------------------------------------*/
1965 /* valForArray - returns a value with name of array index */
1966 /*-----------------------------------------------------------------*/
1968 valForArray (ast * arrExpr)
1970 value *val, *lval = NULL;
1972 int size = getSize (arrExpr->left->ftype->next);
1973 /* if the right or left is an array
1975 if (IS_AST_OP (arrExpr->left))
1977 if (arrExpr->left->opval.op == '[')
1978 lval = valForArray (arrExpr->left);
1979 else if (arrExpr->left->opval.op == '.')
1980 lval = valForStructElem (arrExpr->left->left,
1981 arrExpr->left->right);
1982 else if (arrExpr->left->opval.op == PTR_OP &&
1983 IS_ADDRESS_OF_OP (arrExpr->left->left))
1984 lval = valForStructElem (arrExpr->left->left->left,
1985 arrExpr->left->right);
1990 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1993 if (!IS_AST_LIT_VALUE (arrExpr->right))
1999 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
2003 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2006 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2007 (int) AST_LIT_VALUE (arrExpr->right) * size);
2009 val->type = newLink (DECLARATOR);
2010 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
2011 DCL_TYPE (val->type) = CPOINTER;
2012 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
2013 DCL_TYPE (val->type) = FPOINTER;
2014 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
2015 DCL_TYPE (val->type) = PPOINTER;
2016 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
2017 DCL_TYPE (val->type) = IPOINTER;
2018 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
2019 DCL_TYPE (val->type) = EEPPOINTER;
2021 DCL_TYPE (val->type) = POINTER;
2022 val->type->next = arrExpr->left->ftype->next;
2023 val->etype = getSpec (val->type);
2027 /*-----------------------------------------------------------------*/
2028 /* valForStructElem - returns value with name of struct element */
2029 /*-----------------------------------------------------------------*/
2031 valForStructElem (ast * structT, ast * elemT)
2033 value *val, *lval = NULL;
2037 /* left could be furthur derefed */
2038 if (IS_AST_OP (structT))
2040 if (structT->opval.op == '[')
2041 lval = valForArray (structT);
2042 else if (structT->opval.op == '.')
2043 lval = valForStructElem (structT->left, structT->right);
2044 else if (structT->opval.op == PTR_OP &&
2045 IS_ADDRESS_OF_OP (structT->left))
2046 lval = valForStructElem (structT->left->left,
2052 if (!IS_AST_SYM_VALUE (elemT))
2055 if (!IS_STRUCT (structT->etype))
2058 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2059 AST_SYMBOL (elemT))) == NULL)
2067 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2071 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2074 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2077 val->type = newLink (DECLARATOR);
2078 if (SPEC_SCLS (structT->etype) == S_CODE)
2079 DCL_TYPE (val->type) = CPOINTER;
2080 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2081 DCL_TYPE (val->type) = FPOINTER;
2082 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2083 DCL_TYPE (val->type) = PPOINTER;
2084 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2085 DCL_TYPE (val->type) = IPOINTER;
2086 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2087 DCL_TYPE (val->type) = EEPPOINTER;
2089 DCL_TYPE (val->type) = POINTER;
2090 val->type->next = sym->type;
2091 val->etype = getSpec (val->type);
2095 /*-----------------------------------------------------------------*/
2096 /* valForCastAggr - will return value for a cast of an aggregate */
2097 /* plus minus a constant */
2098 /*-----------------------------------------------------------------*/
2100 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2104 if (!IS_AST_SYM_VALUE (aexpr))
2106 if (!IS_AST_LIT_VALUE (cnst))
2111 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2112 AST_SYMBOL (aexpr)->rname, op,
2113 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2116 val->etype = getSpec (val->type);
2120 /*-----------------------------------------------------------------*/
2121 /* valForCastAggr - will return value for a cast of an aggregate */
2122 /* with no constant */
2123 /*-----------------------------------------------------------------*/
2125 valForCastArr (ast * aexpr, sym_link * type)
2129 if (!IS_AST_SYM_VALUE (aexpr))
2134 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2135 AST_SYMBOL (aexpr)->rname);
2138 val->etype = getSpec (val->type);