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);
835 /*------------------------------------------------------------------*/
836 /* octalEscape - process an octal constant of max three digits */
837 /* return the octal value, throw a warning for illegal octal */
838 /* adjust src to point at the last proccesed char */
839 /*------------------------------------------------------------------*/
841 unsigned char octalEscape (const char **str) {
845 for (digits=0; digits<3; digits++) {
846 if (**str>='0' && **str<='7') {
847 value = value*8 + (**str-'0');
854 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
855 werror (W_ESC_SEQ_OOR_FOR_CHAR);
862 /fn int copyStr (char *dest, char *src)
864 Copies a source string to a dest buffer interpreting escape sequences
865 and special characters
867 /param dest Buffer to receive the resultant string
868 /param src Buffer containing the source string with escape sequecnes
869 /return Number of characters in output string
874 copyStr (char *dest, const char *src)
877 char *OriginalDest = dest ;
883 else if (*src == '\\')
918 *dest++ = octalEscape(&src);
923 *dest++ = hexEscape(&src) ;
950 return dest - OriginalDest ;
953 /*------------------------------------------------------------------*/
954 /* strVal - converts a string constant to a value */
955 /*------------------------------------------------------------------*/
957 strVal (const char *s)
961 val = newValue (); /* get a new one */
963 /* get a declarator */
964 val->type = newLink (DECLARATOR);
965 DCL_TYPE (val->type) = ARRAY;
966 val->type->next = val->etype = newLink (SPECIFIER);
967 SPEC_NOUN (val->etype) = V_CHAR;
968 SPEC_SCLS (val->etype) = S_LITERAL;
970 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
971 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
977 /*------------------------------------------------------------------*/
978 /* reverseValWithType - reverses value chain with type & etype */
979 /*------------------------------------------------------------------*/
981 reverseValWithType (value * val)
989 /* save the type * etype chains */
993 /* set the current one 2b null */
994 val->type = val->etype = NULL;
995 val = reverseVal (val);
997 /* restore type & etype */
1004 /*------------------------------------------------------------------*/
1005 /* reverseVal - reverses the values for a value chain */
1006 /*------------------------------------------------------------------*/
1008 reverseVal (value * val)
1010 value *prev, *curr, *next;
1025 val->next = (void *) NULL;
1029 /*------------------------------------------------------------------*/
1030 /* copyValueChain - will copy a chain of values */
1031 /*------------------------------------------------------------------*/
1033 copyValueChain (value * src)
1040 dest = copyValue (src);
1041 dest->next = copyValueChain (src->next);
1046 /*------------------------------------------------------------------*/
1047 /* copyValue - copies contents of a value to a fresh one */
1048 /*------------------------------------------------------------------*/
1050 copyValue (value * src)
1055 dest->sym = copySymbol (src->sym);
1056 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1057 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1058 dest->etype = (src->type ? getSpec (dest->type) : NULL);
1063 /*------------------------------------------------------------------*/
1064 /* charVal - converts a character constant to a value */
1065 /*------------------------------------------------------------------*/
1067 charVal (const char *s)
1073 val->type = val->etype = newLink (SPECIFIER);
1074 SPEC_NOUN (val->type) = V_CHAR;
1075 SPEC_USIGN(val->type) = 1;
1076 SPEC_SCLS (val->type) = S_LITERAL;
1078 s++; /* get rid of quotation */
1079 /* if \ then special processing */
1082 s++; /* go beyond the backslash */
1086 SPEC_CVAL (val->type).v_uint = '\n';
1089 SPEC_CVAL (val->type).v_uint = '\t';
1092 SPEC_CVAL (val->type).v_uint = '\v';
1095 SPEC_CVAL (val->type).v_uint = '\b';
1098 SPEC_CVAL (val->type).v_uint = '\r';
1101 SPEC_CVAL (val->type).v_uint = '\f';
1104 SPEC_CVAL (val->type).v_uint = '\a';
1107 SPEC_CVAL (val->type).v_uint = '\\';
1110 SPEC_CVAL (val->type).v_uint = '\?';
1113 SPEC_CVAL (val->type).v_uint = '\'';
1116 SPEC_CVAL (val->type).v_uint = '\"';
1127 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
1131 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
1135 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1139 else /* not a backslash */
1140 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1145 /*------------------------------------------------------------------*/
1146 /* valFromType - creates a value from type given */
1147 /*------------------------------------------------------------------*/
1149 valFromType (sym_link * type)
1151 value *val = newValue ();
1152 val->type = copyLinkChain (type);
1153 val->etype = getSpec (val->type);
1157 /*------------------------------------------------------------------*/
1158 /* floatFromVal - value to double float conversion */
1159 /*------------------------------------------------------------------*/
1161 floatFromVal (value * val)
1166 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1168 werror (E_CONST_EXPECTED, val->name);
1172 /* if it is not a specifier then we can assume that */
1173 /* it will be an unsigned long */
1174 if (!IS_SPEC (val->type))
1175 return (double) SPEC_CVAL (val->etype).v_ulong;
1177 if (SPEC_NOUN (val->etype) == V_FLOAT)
1178 return (double) SPEC_CVAL (val->etype).v_float;
1180 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1181 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1183 if (SPEC_LONG (val->etype))
1185 if (SPEC_USIGN (val->etype))
1186 return (double) SPEC_CVAL (val->etype).v_ulong;
1188 return (double) SPEC_CVAL (val->etype).v_long;
1191 if (SPEC_NOUN (val->etype) == V_INT) {
1192 if (SPEC_USIGN (val->etype))
1193 return (double) SPEC_CVAL (val->etype).v_uint;
1195 return (double) SPEC_CVAL (val->etype).v_int;
1198 if (SPEC_NOUN (val->etype) == V_CHAR) {
1199 if (SPEC_USIGN (val->etype))
1200 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1202 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1205 if (IS_BITVAR(val->etype)) {
1206 return (double) SPEC_CVAL (val->etype).v_uint;
1209 if (SPEC_NOUN (val->etype) == V_VOID) {
1210 return (double) SPEC_CVAL (val->etype).v_ulong;
1214 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1215 "floatFromVal: unknown value");
1219 /*-----------------------------------------------------------------*/
1220 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1221 /*-----------------------------------------------------------------*/
1222 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1225 /* This version is incorrect negative values. */
1226 double tmp=0, exp=2;
1228 tmp = (value & 0xffff0000) >> 16;
1232 if(value & 0x8000)tmp += 1/exp;
1239 return ((double)(value * 1.0) / (double)(1UL << 16));
1243 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1246 /* This version is incorrect negative values. */
1247 unsigned int tmp=0, pos=16;
1248 TYPE_TARGET_ULONG res;
1250 tmp = floor( value );
1257 if(value >= 1.0)tmp |= (1 << pos);
1258 value -= floor( value );
1265 return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
1269 /*------------------------------------------------------------------*/
1270 /* valUnaryPM - does the unary +/- operation on a constant */
1271 /*------------------------------------------------------------------*/
1273 valUnaryPM (value * val)
1275 /* depending on type */
1276 if (SPEC_NOUN (val->etype) == V_FLOAT)
1277 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1278 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1279 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1282 if (SPEC_LONG (val->etype))
1284 if (SPEC_USIGN (val->etype))
1285 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1287 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1291 if (SPEC_USIGN (val->etype))
1292 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1294 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1296 if (SPEC_NOUN(val->etype) == V_CHAR)
1298 /* promote to 'signed int', cheapestVal() might reduce it again */
1299 SPEC_USIGN(val->etype) = 0;
1300 SPEC_NOUN(val->etype) = V_INT;
1302 return cheapestVal (val);
1308 /*------------------------------------------------------------------*/
1309 /* valueComplement - complements a constant */
1310 /*------------------------------------------------------------------*/
1312 valComplement (value * val)
1314 /* depending on type */
1315 if (SPEC_LONG (val->etype))
1317 if (SPEC_USIGN (val->etype))
1318 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1320 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1324 if (SPEC_USIGN (val->etype))
1325 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1327 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1329 if (SPEC_NOUN(val->etype) == V_CHAR)
1331 /* promote to 'signed int', cheapestVal() might reduce it again */
1332 SPEC_USIGN(val->etype) = 0;
1333 SPEC_NOUN(val->etype) = V_INT;
1335 return cheapestVal (val);
1340 /*------------------------------------------------------------------*/
1341 /* valueNot - complements a constant */
1342 /*------------------------------------------------------------------*/
1344 valNot (value * val)
1346 /* depending on type */
1347 if (SPEC_LONG (val->etype))
1349 if (SPEC_USIGN (val->etype))
1350 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1352 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1356 if (SPEC_USIGN (val->etype))
1357 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1359 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1362 /* ANSI: result type is int, value is 0 or 1 */
1363 /* sdcc will hold this in an 'unsigned char' */
1364 SPEC_USIGN(val->etype) = 1;
1365 SPEC_LONG (val->etype) = 0;
1366 SPEC_NOUN(val->etype) = V_CHAR;
1370 /*------------------------------------------------------------------*/
1371 /* valMult - multiply constants */
1372 /*------------------------------------------------------------------*/
1374 valMult (value * lval, value * rval)
1378 /* create a new value */
1380 val->type = val->etype = computeType (lval->etype,
1384 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1386 if (IS_FLOAT (val->type))
1387 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1389 if (IS_FIXED16X16 (val->type))
1390 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1391 /* signed and unsigned mul are the same, as long as the precision of the
1392 result isn't bigger than the precision of the operands. */
1393 else if (SPEC_LONG (val->type))
1394 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
1395 (TYPE_TARGET_ULONG) floatFromVal (rval);
1396 else if (SPEC_USIGN (val->type)) /* unsigned int */
1398 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
1399 (TYPE_TARGET_UINT) floatFromVal (rval);
1401 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1402 if (ul != (TYPE_TARGET_UINT) ul)
1405 else /* signed int */
1407 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1408 (TYPE_TARGET_INT) floatFromVal (rval);
1410 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1411 if (l != (TYPE_TARGET_INT) l)
1414 return cheapestVal (val);
1417 /*------------------------------------------------------------------*/
1418 /* valDiv - Divide constants */
1419 /*------------------------------------------------------------------*/
1421 valDiv (value * lval, value * rval)
1425 if (floatFromVal (rval) == 0)
1427 werror (E_DIVIDE_BY_ZERO);
1431 /* create a new value */
1433 val->type = val->etype = computeType (lval->etype,
1437 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1439 if (IS_FLOAT (val->type))
1440 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1442 if (IS_FIXED16X16 (val->type))
1443 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1444 else if (SPEC_LONG (val->type))
1446 if (SPEC_USIGN (val->type))
1447 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
1448 (TYPE_TARGET_ULONG) floatFromVal (rval);
1450 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
1451 (TYPE_TARGET_LONG) floatFromVal (rval);
1455 if (SPEC_USIGN (val->type))
1456 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
1457 (TYPE_TARGET_UINT) floatFromVal (rval);
1459 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
1460 (TYPE_TARGET_INT) floatFromVal (rval);
1462 return cheapestVal (val);
1465 /*------------------------------------------------------------------*/
1466 /* valMod - Modulus constants */
1467 /*------------------------------------------------------------------*/
1469 valMod (value * lval, value * rval)
1473 /* create a new value */
1475 val->type = val->etype = computeType (lval->etype,
1479 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1481 if (SPEC_LONG (val->type))
1483 if (SPEC_USIGN (val->type))
1484 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
1485 (TYPE_TARGET_ULONG) floatFromVal (rval);
1487 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
1488 (TYPE_TARGET_LONG) floatFromVal (rval);
1492 if (SPEC_USIGN (val->type))
1493 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
1494 (TYPE_TARGET_UINT) floatFromVal (rval);
1496 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
1497 (TYPE_TARGET_INT) floatFromVal (rval);
1499 return cheapestVal (val);
1502 /*------------------------------------------------------------------*/
1503 /* valPlus - Addition constants */
1504 /*------------------------------------------------------------------*/
1506 valPlus (value * lval, value * rval)
1510 /* create a new value */
1512 val->type = val->etype = computeType (lval->etype,
1516 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1518 if (IS_FLOAT (val->type))
1519 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1521 if (IS_FIXED16X16 (val->type))
1522 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1523 else if (SPEC_LONG (val->type))
1525 if (SPEC_USIGN (val->type))
1526 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
1527 (TYPE_TARGET_ULONG) floatFromVal (rval);
1529 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
1530 (TYPE_TARGET_LONG) floatFromVal (rval);
1534 if (SPEC_USIGN (val->type))
1535 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
1536 (TYPE_TARGET_UINT) floatFromVal (rval);
1538 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
1539 (TYPE_TARGET_INT) floatFromVal (rval);
1541 return cheapestVal (val);
1544 /*------------------------------------------------------------------*/
1545 /* valMinus - Addition constants */
1546 /*------------------------------------------------------------------*/
1548 valMinus (value * lval, value * rval)
1552 /* create a new value */
1554 val->type = val->etype = computeType (lval->etype,
1558 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1560 if (IS_FLOAT (val->type))
1561 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1563 if (IS_FIXED16X16 (val->type))
1564 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1565 else if (SPEC_LONG (val->type))
1567 if (SPEC_USIGN (val->type))
1568 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
1569 (TYPE_TARGET_ULONG) floatFromVal (rval);
1571 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
1572 (TYPE_TARGET_LONG) floatFromVal (rval);
1576 if (SPEC_USIGN (val->type))
1577 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
1578 (TYPE_TARGET_UINT) floatFromVal (rval);
1580 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
1581 (TYPE_TARGET_INT) floatFromVal (rval);
1583 return cheapestVal (val);
1586 /*------------------------------------------------------------------*/
1587 /* valShift - Shift left or right */
1588 /*------------------------------------------------------------------*/
1590 valShift (value * lval, value * rval, int lr)
1594 /* create a new value */
1596 val->type = val->etype = computeType (lval->etype,
1600 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1602 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
1605 /* right shift and unsigned */
1606 (!lr && SPEC_USIGN (rval->type))))
1608 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1611 if (SPEC_LONG (val->type))
1613 if (SPEC_USIGN (val->type))
1615 SPEC_CVAL (val->type).v_ulong = lr ?
1616 (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1617 (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1621 SPEC_CVAL (val->type).v_long = lr ?
1622 (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1623 (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1628 if (SPEC_USIGN (val->type))
1630 SPEC_CVAL (val->type).v_uint = lr ?
1631 (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1632 (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1636 SPEC_CVAL (val->type).v_int = lr ?
1637 (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1638 (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1641 return cheapestVal (val);
1644 /*------------------------------------------------------------------*/
1645 /* valCompare- Compares two literal */
1646 /*------------------------------------------------------------------*/
1648 valCompare (value * lval, value * rval, int ctype)
1652 /* create a new value */
1654 val->type = val->etype = newCharLink ();
1655 val->type->class = SPECIFIER;
1656 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1657 SPEC_USIGN (val->type) = 1;
1658 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1663 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1667 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1671 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1675 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1679 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1680 SPEC_NOUN(rval->type) == V_FLOAT)
1682 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1685 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1686 SPEC_NOUN(rval->type) == V_FIXED16X16)
1688 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1692 /* integrals: ignore signedness */
1693 TYPE_TARGET_ULONG l, r;
1695 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1696 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1697 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1698 neccessary to strip them to 16 bit.
1699 Literals are reduced to their cheapest type, therefore left and
1700 right might have different types. It's neccessary to find a
1701 common type: int (used for char too) or long */
1702 if (!IS_LONG (lval->etype) &&
1703 !IS_LONG (rval->etype))
1705 r = (TYPE_TARGET_UINT) r;
1706 l = (TYPE_TARGET_UINT) l;
1708 SPEC_CVAL (val->type).v_int = l == r;
1712 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1713 SPEC_NOUN(rval->type) == V_FLOAT)
1715 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1718 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1719 SPEC_NOUN(rval->type) == V_FIXED16X16)
1721 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1725 /* integrals: ignore signedness */
1726 TYPE_TARGET_ULONG l, r;
1728 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1729 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1730 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1731 neccessary to strip them to 16 bit.
1732 Literals are reduced to their cheapest type, therefore left and
1733 right might have different types. It's neccessary to find a
1734 common type: int (used for char too) or long */
1735 if (!IS_LONG (lval->etype) &&
1736 !IS_LONG (rval->etype))
1738 r = (TYPE_TARGET_UINT) r;
1739 l = (TYPE_TARGET_UINT) l;
1741 SPEC_CVAL (val->type).v_int = l != r;
1750 /*------------------------------------------------------------------*/
1751 /* valBitwise - Bitwise operation */
1752 /*------------------------------------------------------------------*/
1754 valBitwise (value * lval, value * rval, int op)
1758 /* create a new value */
1760 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1761 val->etype = getSpec (val->type);
1762 SPEC_SCLS (val->etype) = S_LITERAL;
1767 if (SPEC_LONG (val->type))
1769 if (SPEC_USIGN (val->type))
1770 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
1771 (TYPE_TARGET_ULONG) floatFromVal (rval);
1773 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
1774 (TYPE_TARGET_LONG) floatFromVal (rval);
1778 if (SPEC_USIGN (val->type))
1779 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
1780 (TYPE_TARGET_UINT) floatFromVal (rval);
1782 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
1783 (TYPE_TARGET_INT) floatFromVal (rval);
1788 if (SPEC_LONG (val->type))
1790 if (SPEC_USIGN (val->type))
1791 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
1792 (TYPE_TARGET_ULONG) floatFromVal (rval);
1794 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
1795 (TYPE_TARGET_LONG) floatFromVal (rval);
1799 if (SPEC_USIGN (val->type))
1800 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
1801 (TYPE_TARGET_UINT) floatFromVal (rval);
1803 SPEC_CVAL (val->type).v_int =
1804 (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
1810 if (SPEC_LONG (val->type))
1812 if (SPEC_USIGN (val->type))
1813 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
1814 (TYPE_TARGET_ULONG) floatFromVal (rval);
1816 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
1817 (TYPE_TARGET_LONG) floatFromVal (rval);
1821 if (SPEC_USIGN (val->type))
1822 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
1823 (TYPE_TARGET_UINT) floatFromVal (rval);
1825 SPEC_CVAL (val->type).v_int =
1826 (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
1831 return cheapestVal(val);
1834 /*------------------------------------------------------------------*/
1835 /* valAndOr - Generates code for and / or operation */
1836 /*------------------------------------------------------------------*/
1838 valLogicAndOr (value * lval, value * rval, int op)
1842 /* create a new value */
1844 val->type = val->etype = newCharLink ();
1845 val->type->class = SPECIFIER;
1846 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1847 SPEC_USIGN (val->type) = 1;
1852 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1856 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1864 /*------------------------------------------------------------------*/
1865 /* valCastLiteral - casts a literal value to another type */
1866 /*------------------------------------------------------------------*/
1868 valCastLiteral (sym_link * dtype, double fval)
1871 TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
1878 val->etype = getSpec (val->type = copyLinkChain (dtype));
1881 val->etype = val->type = newLink (SPECIFIER);
1882 SPEC_NOUN (val->etype) = V_VOID;
1884 SPEC_SCLS (val->etype) = S_LITERAL;
1886 /* if it is not a specifier then we can assume that */
1887 /* it will be an unsigned long */
1888 if (!IS_SPEC (val->type)) {
1889 SPEC_CVAL (val->etype).v_ulong = l;
1893 if (SPEC_NOUN (val->etype) == V_FLOAT)
1894 SPEC_CVAL (val->etype).v_float = fval;
1895 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1896 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1897 else if (SPEC_NOUN (val->etype) == V_BIT ||
1898 SPEC_NOUN (val->etype) == V_SBIT)
1899 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1900 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1901 SPEC_CVAL (val->etype).v_uint = l &
1902 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1903 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1904 if (SPEC_USIGN (val->etype))
1905 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1907 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1909 if (SPEC_LONG (val->etype)) {
1910 if (SPEC_USIGN (val->etype))
1911 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1913 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1915 if (SPEC_USIGN (val->etype))
1916 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
1918 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
1924 /*------------------------------------------------------------------*/
1925 /* getNelements - determines # of elements from init list */
1926 /*------------------------------------------------------------------*/
1928 getNelements (sym_link * type, initList * ilist)
1935 if (ilist->type == INIT_DEEP)
1936 ilist = ilist->init.deep;
1938 /* if type is a character array and there is only one
1939 (string) initialiser then get the length of the string */
1940 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1942 ast *iast = ilist->init.node;
1943 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1946 werror (E_CONST_EXPECTED);
1950 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1951 // yep, it's a string
1953 return DCL_ELEM (v->type);
1961 ilist = ilist->next;
1966 /*-----------------------------------------------------------------*/
1967 /* valForArray - returns a value with name of array index */
1968 /*-----------------------------------------------------------------*/
1970 valForArray (ast * arrExpr)
1972 value *val, *lval = NULL;
1974 int size = getSize (arrExpr->left->ftype->next);
1975 /* if the right or left is an array
1977 if (IS_AST_OP (arrExpr->left))
1979 if (arrExpr->left->opval.op == '[')
1980 lval = valForArray (arrExpr->left);
1981 else if (arrExpr->left->opval.op == '.')
1982 lval = valForStructElem (arrExpr->left->left,
1983 arrExpr->left->right);
1984 else if (arrExpr->left->opval.op == PTR_OP &&
1985 IS_ADDRESS_OF_OP (arrExpr->left->left))
1986 lval = valForStructElem (arrExpr->left->left->left,
1987 arrExpr->left->right);
1992 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1995 if (!IS_AST_LIT_VALUE (arrExpr->right))
2001 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
2005 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2008 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2009 (int) AST_LIT_VALUE (arrExpr->right) * size);
2011 val->type = newLink (DECLARATOR);
2012 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
2013 DCL_TYPE (val->type) = CPOINTER;
2014 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
2015 DCL_TYPE (val->type) = FPOINTER;
2016 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
2017 DCL_TYPE (val->type) = PPOINTER;
2018 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
2019 DCL_TYPE (val->type) = IPOINTER;
2020 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
2021 DCL_TYPE (val->type) = EEPPOINTER;
2023 DCL_TYPE (val->type) = POINTER;
2024 val->type->next = arrExpr->left->ftype->next;
2025 val->etype = getSpec (val->type);
2029 /*-----------------------------------------------------------------*/
2030 /* valForStructElem - returns value with name of struct element */
2031 /*-----------------------------------------------------------------*/
2033 valForStructElem (ast * structT, ast * elemT)
2035 value *val, *lval = NULL;
2039 /* left could be furthur derefed */
2040 if (IS_AST_OP (structT))
2042 if (structT->opval.op == '[')
2043 lval = valForArray (structT);
2044 else if (structT->opval.op == '.')
2045 lval = valForStructElem (structT->left, structT->right);
2046 else if (structT->opval.op == PTR_OP &&
2047 IS_ADDRESS_OF_OP (structT->left))
2048 lval = valForStructElem (structT->left->left,
2054 if (!IS_AST_SYM_VALUE (elemT))
2057 if (!IS_STRUCT (structT->etype))
2060 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2061 AST_SYMBOL (elemT))) == NULL)
2069 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2073 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2076 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2079 val->type = newLink (DECLARATOR);
2080 if (SPEC_SCLS (structT->etype) == S_CODE)
2081 DCL_TYPE (val->type) = CPOINTER;
2082 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2083 DCL_TYPE (val->type) = FPOINTER;
2084 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2085 DCL_TYPE (val->type) = PPOINTER;
2086 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2087 DCL_TYPE (val->type) = IPOINTER;
2088 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2089 DCL_TYPE (val->type) = EEPPOINTER;
2091 DCL_TYPE (val->type) = POINTER;
2092 val->type->next = sym->type;
2093 val->etype = getSpec (val->type);
2097 /*-----------------------------------------------------------------*/
2098 /* valForCastAggr - will return value for a cast of an aggregate */
2099 /* plus minus a constant */
2100 /*-----------------------------------------------------------------*/
2102 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2106 if (!IS_AST_SYM_VALUE (aexpr))
2108 if (!IS_AST_LIT_VALUE (cnst))
2113 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2114 AST_SYMBOL (aexpr)->rname, op,
2115 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2118 val->etype = getSpec (val->type);
2122 /*-----------------------------------------------------------------*/
2123 /* valForCastAggr - will return value for a cast of an aggregate */
2124 /* with no constant */
2125 /*-----------------------------------------------------------------*/
2127 valForCastArr (ast * aexpr, sym_link * type)
2131 if (!IS_AST_SYM_VALUE (aexpr))
2136 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2137 AST_SYMBOL (aexpr)->rname);
2140 val->etype = getSpec (val->type);