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 = mylineno;
61 nilist->filename = currFname;
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 (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(char **src)
816 unsigned long value ;
818 (*src)++ ; /* Skip over the 'x' */
819 s = *src ; /* Save for error detection */
821 value = strtol (*src, src, 16);
824 // no valid hex found
825 werror(E_INVALID_HEX);
828 werror(W_ESC_SEQ_OOR_FOR_CHAR);
834 /*------------------------------------------------------------------*/
835 /* octalEscape - process an octal constant of max three digits */
836 /* return the octal value, throw a warning for illegal octal */
837 /* adjust src to point at the last proccesed char */
838 /*------------------------------------------------------------------*/
840 unsigned char octalEscape (char **str) {
844 for (digits=0; digits<3; digits++) {
845 if (**str>='0' && **str<='7') {
846 value = value*8 + (**str-'0');
853 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
854 werror (W_ESC_SEQ_OOR_FOR_CHAR);
861 /fn int copyStr (char *dest, char *src)
863 Copies a source string to a dest buffer interpreting escape sequences
864 and special characters
866 /param dest Buffer to receive the resultant string
867 /param src Buffer containing the source string with escape sequecnes
868 /return Number of characters in output string
873 copyStr (char *dest, char *src)
876 char *OriginalDest = dest ;
882 else if (*src == '\\')
917 *dest++ = octalEscape(&src);
922 *dest++ = hexEscape(&src) ;
949 return dest - OriginalDest ;
952 /*------------------------------------------------------------------*/
953 /* strVal - converts a string constant to a value */
954 /*------------------------------------------------------------------*/
960 val = newValue (); /* get a new one */
962 /* get a declarator */
963 val->type = newLink (DECLARATOR);
964 DCL_TYPE (val->type) = ARRAY;
965 val->type->next = val->etype = newLink (SPECIFIER);
966 SPEC_NOUN (val->etype) = V_CHAR;
967 SPEC_SCLS (val->etype) = S_LITERAL;
969 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
970 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
976 /*------------------------------------------------------------------*/
977 /* reverseValWithType - reverses value chain with type & etype */
978 /*------------------------------------------------------------------*/
980 reverseValWithType (value * val)
988 /* save the type * etype chains */
992 /* set the current one 2b null */
993 val->type = val->etype = NULL;
994 val = reverseVal (val);
996 /* restore type & etype */
1003 /*------------------------------------------------------------------*/
1004 /* reverseVal - reverses the values for a value chain */
1005 /*------------------------------------------------------------------*/
1007 reverseVal (value * val)
1009 value *prev, *curr, *next;
1024 val->next = (void *) NULL;
1028 /*------------------------------------------------------------------*/
1029 /* copyValueChain - will copy a chain of values */
1030 /*------------------------------------------------------------------*/
1032 copyValueChain (value * src)
1039 dest = copyValue (src);
1040 dest->next = copyValueChain (src->next);
1045 /*------------------------------------------------------------------*/
1046 /* copyValue - copies contents of a value to a fresh one */
1047 /*------------------------------------------------------------------*/
1049 copyValue (value * src)
1054 dest->sym = copySymbol (src->sym);
1055 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
1056 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
1057 dest->etype = (src->type ? getSpec (dest->type) : NULL);
1062 /*------------------------------------------------------------------*/
1063 /* charVal - converts a character constant to a value */
1064 /*------------------------------------------------------------------*/
1072 val->type = val->etype = newLink (SPECIFIER);
1073 SPEC_NOUN (val->type) = V_CHAR;
1074 SPEC_USIGN(val->type) = 1;
1075 SPEC_SCLS (val->type) = S_LITERAL;
1077 s++; /* get rid of quotation */
1078 /* if \ then special processing */
1081 s++; /* go beyond the backslash */
1085 SPEC_CVAL (val->type).v_uint = '\n';
1088 SPEC_CVAL (val->type).v_uint = '\t';
1091 SPEC_CVAL (val->type).v_uint = '\v';
1094 SPEC_CVAL (val->type).v_uint = '\b';
1097 SPEC_CVAL (val->type).v_uint = '\r';
1100 SPEC_CVAL (val->type).v_uint = '\f';
1103 SPEC_CVAL (val->type).v_uint = '\a';
1106 SPEC_CVAL (val->type).v_uint = '\\';
1109 SPEC_CVAL (val->type).v_uint = '\?';
1112 SPEC_CVAL (val->type).v_uint = '\'';
1115 SPEC_CVAL (val->type).v_uint = '\"';
1126 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
1130 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
1134 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1138 else /* not a backslash */
1139 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1144 /*------------------------------------------------------------------*/
1145 /* valFromType - creates a value from type given */
1146 /*------------------------------------------------------------------*/
1148 valFromType (sym_link * type)
1150 value *val = newValue ();
1151 val->type = copyLinkChain (type);
1152 val->etype = getSpec (val->type);
1156 /*------------------------------------------------------------------*/
1157 /* floatFromVal - value to double float conversion */
1158 /*------------------------------------------------------------------*/
1160 floatFromVal (value * val)
1165 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1167 werror (E_CONST_EXPECTED, val->name);
1171 /* if it is not a specifier then we can assume that */
1172 /* it will be an unsigned long */
1173 if (!IS_SPEC (val->type))
1174 return (double) SPEC_CVAL (val->etype).v_ulong;
1176 if (SPEC_NOUN (val->etype) == V_FLOAT)
1177 return (double) SPEC_CVAL (val->etype).v_float;
1179 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1180 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1182 if (SPEC_LONG (val->etype))
1184 if (SPEC_USIGN (val->etype))
1185 return (double) SPEC_CVAL (val->etype).v_ulong;
1187 return (double) SPEC_CVAL (val->etype).v_long;
1190 if (SPEC_NOUN (val->etype) == V_INT) {
1191 if (SPEC_USIGN (val->etype))
1192 return (double) SPEC_CVAL (val->etype).v_uint;
1194 return (double) SPEC_CVAL (val->etype).v_int;
1197 if (SPEC_NOUN (val->etype) == V_CHAR) {
1198 if (SPEC_USIGN (val->etype))
1199 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1201 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1204 if (IS_BITVAR(val->etype)) {
1205 return (double) SPEC_CVAL (val->etype).v_uint;
1208 if (SPEC_NOUN (val->etype) == V_VOID) {
1209 return (double) SPEC_CVAL (val->etype).v_ulong;
1213 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1214 "floatFromVal: unknown value");
1218 /*-----------------------------------------------------------------*/
1219 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1220 /*-----------------------------------------------------------------*/
1221 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1224 /* This version is incorrect negative values. */
1225 double tmp=0, exp=2;
1227 tmp = (value & 0xffff0000) >> 16;
1231 if(value & 0x8000)tmp += 1/exp;
1238 return ((double)(value * 1.0) / (double)(1UL << 16));
1242 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1245 /* This version is incorrect negative values. */
1246 unsigned int tmp=0, pos=16;
1247 TYPE_TARGET_ULONG res;
1249 tmp = floor( value );
1256 if(value >= 1.0)tmp |= (1 << pos);
1257 value -= floor( value );
1264 return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
1268 /*------------------------------------------------------------------*/
1269 /* valUnaryPM - does the unary +/- operation on a constant */
1270 /*------------------------------------------------------------------*/
1272 valUnaryPM (value * val)
1274 /* depending on type */
1275 if (SPEC_NOUN (val->etype) == V_FLOAT)
1276 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1277 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1278 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1281 if (SPEC_LONG (val->etype))
1283 if (SPEC_USIGN (val->etype))
1284 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1286 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1290 if (SPEC_USIGN (val->etype))
1291 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1293 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1295 if (SPEC_NOUN(val->etype) == V_CHAR)
1297 /* promote to 'signed int', cheapestVal() might reduce it again */
1298 SPEC_USIGN(val->etype) = 0;
1299 SPEC_NOUN(val->etype) = V_INT;
1301 return cheapestVal (val);
1307 /*------------------------------------------------------------------*/
1308 /* valueComplement - complements a constant */
1309 /*------------------------------------------------------------------*/
1311 valComplement (value * val)
1313 /* depending on type */
1314 if (SPEC_LONG (val->etype))
1316 if (SPEC_USIGN (val->etype))
1317 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1319 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1323 if (SPEC_USIGN (val->etype))
1324 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1326 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1328 if (SPEC_NOUN(val->etype) == V_CHAR)
1330 /* promote to 'signed int', cheapestVal() might reduce it again */
1331 SPEC_USIGN(val->etype) = 0;
1332 SPEC_NOUN(val->etype) = V_INT;
1334 return cheapestVal (val);
1339 /*------------------------------------------------------------------*/
1340 /* valueNot - complements a constant */
1341 /*------------------------------------------------------------------*/
1343 valNot (value * val)
1345 /* depending on type */
1346 if (SPEC_LONG (val->etype))
1348 if (SPEC_USIGN (val->etype))
1349 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1351 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1355 if (SPEC_USIGN (val->etype))
1356 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1358 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1361 /* ANSI: result type is int, value is 0 or 1 */
1362 /* sdcc will hold this in an 'unsigned char' */
1363 SPEC_USIGN(val->etype) = 1;
1364 SPEC_LONG (val->etype) = 0;
1365 SPEC_NOUN(val->etype) = V_CHAR;
1369 /*------------------------------------------------------------------*/
1370 /* valMult - multiply constants */
1371 /*------------------------------------------------------------------*/
1373 valMult (value * lval, value * rval)
1377 /* create a new value */
1379 val->type = val->etype = computeType (lval->etype,
1383 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1385 if (IS_FLOAT (val->type))
1386 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1388 if (IS_FIXED16X16 (val->type))
1389 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1390 /* signed and unsigned mul are the same, as long as the precision of the
1391 result isn't bigger than the precision of the operands. */
1392 else if (SPEC_LONG (val->type))
1393 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
1394 (TYPE_TARGET_ULONG) floatFromVal (rval);
1395 else if (SPEC_USIGN (val->type)) /* unsigned int */
1397 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
1398 (TYPE_TARGET_UINT) floatFromVal (rval);
1400 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1401 if (ul != (TYPE_TARGET_UINT) ul)
1404 else /* signed int */
1406 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1407 (TYPE_TARGET_INT) floatFromVal (rval);
1409 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1410 if (l != (TYPE_TARGET_INT) l)
1413 return cheapestVal (val);
1416 /*------------------------------------------------------------------*/
1417 /* valDiv - Divide constants */
1418 /*------------------------------------------------------------------*/
1420 valDiv (value * lval, value * rval)
1424 if (floatFromVal (rval) == 0)
1426 werror (E_DIVIDE_BY_ZERO);
1430 /* create a new value */
1432 val->type = val->etype = computeType (lval->etype,
1436 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1438 if (IS_FLOAT (val->type))
1439 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1441 if (IS_FIXED16X16 (val->type))
1442 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1443 else if (SPEC_LONG (val->type))
1445 if (SPEC_USIGN (val->type))
1446 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
1447 (TYPE_TARGET_ULONG) floatFromVal (rval);
1449 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
1450 (TYPE_TARGET_LONG) floatFromVal (rval);
1454 if (SPEC_USIGN (val->type))
1455 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
1456 (TYPE_TARGET_UINT) floatFromVal (rval);
1458 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
1459 (TYPE_TARGET_INT) floatFromVal (rval);
1461 return cheapestVal (val);
1464 /*------------------------------------------------------------------*/
1465 /* valMod - Modulus constants */
1466 /*------------------------------------------------------------------*/
1468 valMod (value * lval, value * rval)
1472 /* create a new value */
1474 val->type = val->etype = computeType (lval->etype,
1478 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1480 if (SPEC_LONG (val->type))
1482 if (SPEC_USIGN (val->type))
1483 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
1484 (TYPE_TARGET_ULONG) floatFromVal (rval);
1486 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
1487 (TYPE_TARGET_LONG) floatFromVal (rval);
1491 if (SPEC_USIGN (val->type))
1492 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
1493 (TYPE_TARGET_UINT) floatFromVal (rval);
1495 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
1496 (TYPE_TARGET_INT) floatFromVal (rval);
1498 return cheapestVal (val);
1501 /*------------------------------------------------------------------*/
1502 /* valPlus - Addition constants */
1503 /*------------------------------------------------------------------*/
1505 valPlus (value * lval, value * rval)
1509 /* create a new value */
1511 val->type = val->etype = computeType (lval->etype,
1515 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1517 if (IS_FLOAT (val->type))
1518 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1520 if (IS_FIXED16X16 (val->type))
1521 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1522 else if (SPEC_LONG (val->type))
1524 if (SPEC_USIGN (val->type))
1525 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
1526 (TYPE_TARGET_ULONG) floatFromVal (rval);
1528 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
1529 (TYPE_TARGET_LONG) floatFromVal (rval);
1533 if (SPEC_USIGN (val->type))
1534 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
1535 (TYPE_TARGET_UINT) floatFromVal (rval);
1537 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
1538 (TYPE_TARGET_INT) floatFromVal (rval);
1540 return cheapestVal (val);
1543 /*------------------------------------------------------------------*/
1544 /* valMinus - Addition constants */
1545 /*------------------------------------------------------------------*/
1547 valMinus (value * lval, value * rval)
1551 /* create a new value */
1553 val->type = val->etype = computeType (lval->etype,
1557 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1559 if (IS_FLOAT (val->type))
1560 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1562 if (IS_FIXED16X16 (val->type))
1563 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1564 else if (SPEC_LONG (val->type))
1566 if (SPEC_USIGN (val->type))
1567 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
1568 (TYPE_TARGET_ULONG) floatFromVal (rval);
1570 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
1571 (TYPE_TARGET_LONG) floatFromVal (rval);
1575 if (SPEC_USIGN (val->type))
1576 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
1577 (TYPE_TARGET_UINT) floatFromVal (rval);
1579 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
1580 (TYPE_TARGET_INT) floatFromVal (rval);
1582 return cheapestVal (val);
1585 /*------------------------------------------------------------------*/
1586 /* valShift - Shift left or right */
1587 /*------------------------------------------------------------------*/
1589 valShift (value * lval, value * rval, int lr)
1593 /* create a new value */
1595 val->type = val->etype = computeType (lval->etype,
1599 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1601 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
1604 /* right shift and unsigned */
1605 (!lr && SPEC_USIGN (rval->type))))
1607 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1610 if (SPEC_LONG (val->type))
1612 if (SPEC_USIGN (val->type))
1614 SPEC_CVAL (val->type).v_ulong = lr ?
1615 (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1616 (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1620 SPEC_CVAL (val->type).v_long = lr ?
1621 (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1622 (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1627 if (SPEC_USIGN (val->type))
1629 SPEC_CVAL (val->type).v_uint = lr ?
1630 (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1631 (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1635 SPEC_CVAL (val->type).v_int = lr ?
1636 (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1637 (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1640 return cheapestVal (val);
1643 /*------------------------------------------------------------------*/
1644 /* valCompare- Compares two literal */
1645 /*------------------------------------------------------------------*/
1647 valCompare (value * lval, value * rval, int ctype)
1651 /* create a new value */
1653 val->type = val->etype = newCharLink ();
1654 val->type->class = SPECIFIER;
1655 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1656 SPEC_USIGN (val->type) = 1;
1657 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1662 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1666 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1670 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1674 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1678 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1679 SPEC_NOUN(rval->type) == V_FLOAT)
1681 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1684 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1685 SPEC_NOUN(rval->type) == V_FIXED16X16)
1687 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1691 /* integrals: ignore signedness */
1692 TYPE_TARGET_ULONG l, r;
1694 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1695 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1696 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1697 neccessary to strip them to 16 bit.
1698 Literals are reduced to their cheapest type, therefore left and
1699 right might have different types. It's neccessary to find a
1700 common type: int (used for char too) or long */
1701 if (!IS_LONG (lval->etype) &&
1702 !IS_LONG (rval->etype))
1704 r = (TYPE_TARGET_UINT) r;
1705 l = (TYPE_TARGET_UINT) l;
1707 SPEC_CVAL (val->type).v_int = l == r;
1711 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1712 SPEC_NOUN(rval->type) == V_FLOAT)
1714 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1717 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1718 SPEC_NOUN(rval->type) == V_FIXED16X16)
1720 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1724 /* integrals: ignore signedness */
1725 TYPE_TARGET_ULONG l, r;
1727 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1728 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1729 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1730 neccessary to strip them to 16 bit.
1731 Literals are reduced to their cheapest type, therefore left and
1732 right might have different types. It's neccessary to find a
1733 common type: int (used for char too) or long */
1734 if (!IS_LONG (lval->etype) &&
1735 !IS_LONG (rval->etype))
1737 r = (TYPE_TARGET_UINT) r;
1738 l = (TYPE_TARGET_UINT) l;
1740 SPEC_CVAL (val->type).v_int = l != r;
1749 /*------------------------------------------------------------------*/
1750 /* valBitwise - Bitwise operation */
1751 /*------------------------------------------------------------------*/
1753 valBitwise (value * lval, value * rval, int op)
1757 /* create a new value */
1759 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1760 val->etype = getSpec (val->type);
1761 SPEC_SCLS (val->etype) = S_LITERAL;
1766 if (SPEC_LONG (val->type))
1768 if (SPEC_USIGN (val->type))
1769 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
1770 (TYPE_TARGET_ULONG) floatFromVal (rval);
1772 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
1773 (TYPE_TARGET_LONG) floatFromVal (rval);
1777 if (SPEC_USIGN (val->type))
1778 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
1779 (TYPE_TARGET_UINT) floatFromVal (rval);
1781 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
1782 (TYPE_TARGET_INT) floatFromVal (rval);
1787 if (SPEC_LONG (val->type))
1789 if (SPEC_USIGN (val->type))
1790 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
1791 (TYPE_TARGET_ULONG) floatFromVal (rval);
1793 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
1794 (TYPE_TARGET_LONG) floatFromVal (rval);
1798 if (SPEC_USIGN (val->type))
1799 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
1800 (TYPE_TARGET_UINT) floatFromVal (rval);
1802 SPEC_CVAL (val->type).v_int =
1803 (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
1809 if (SPEC_LONG (val->type))
1811 if (SPEC_USIGN (val->type))
1812 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
1813 (TYPE_TARGET_ULONG) floatFromVal (rval);
1815 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
1816 (TYPE_TARGET_LONG) floatFromVal (rval);
1820 if (SPEC_USIGN (val->type))
1821 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
1822 (TYPE_TARGET_UINT) floatFromVal (rval);
1824 SPEC_CVAL (val->type).v_int =
1825 (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
1830 return cheapestVal(val);
1833 /*------------------------------------------------------------------*/
1834 /* valAndOr - Generates code for and / or operation */
1835 /*------------------------------------------------------------------*/
1837 valLogicAndOr (value * lval, value * rval, int op)
1841 /* create a new value */
1843 val->type = val->etype = newCharLink ();
1844 val->type->class = SPECIFIER;
1845 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1846 SPEC_USIGN (val->type) = 1;
1851 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1855 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1863 /*------------------------------------------------------------------*/
1864 /* valCastLiteral - casts a literal value to another type */
1865 /*------------------------------------------------------------------*/
1867 valCastLiteral (sym_link * dtype, double fval)
1870 TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
1877 val->etype = getSpec (val->type = copyLinkChain (dtype));
1880 val->etype = val->type = newLink (SPECIFIER);
1881 SPEC_NOUN (val->etype) = V_VOID;
1883 SPEC_SCLS (val->etype) = S_LITERAL;
1885 /* if it is not a specifier then we can assume that */
1886 /* it will be an unsigned long */
1887 if (!IS_SPEC (val->type)) {
1888 SPEC_CVAL (val->etype).v_ulong = l;
1892 if (SPEC_NOUN (val->etype) == V_FLOAT)
1893 SPEC_CVAL (val->etype).v_float = fval;
1894 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1895 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1896 else if (SPEC_NOUN (val->etype) == V_BIT ||
1897 SPEC_NOUN (val->etype) == V_SBIT)
1898 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1899 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1900 SPEC_CVAL (val->etype).v_uint = l &
1901 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1902 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1903 if (SPEC_USIGN (val->etype))
1904 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1906 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1908 if (SPEC_LONG (val->etype)) {
1909 if (SPEC_USIGN (val->etype))
1910 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1912 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1914 if (SPEC_USIGN (val->etype))
1915 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
1917 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
1923 /*------------------------------------------------------------------*/
1924 /* getNelements - determines # of elements from init list */
1925 /*------------------------------------------------------------------*/
1927 getNelements (sym_link * type, initList * ilist)
1934 if (ilist->type == INIT_DEEP)
1935 ilist = ilist->init.deep;
1937 /* if type is a character array and there is only one
1938 (string) initialiser then get the length of the string */
1939 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1941 ast *iast = ilist->init.node;
1942 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1945 werror (E_CONST_EXPECTED);
1949 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1950 // yep, it's a string
1952 return DCL_ELEM (v->type);
1960 ilist = ilist->next;
1965 /*-----------------------------------------------------------------*/
1966 /* valForArray - returns a value with name of array index */
1967 /*-----------------------------------------------------------------*/
1969 valForArray (ast * arrExpr)
1971 value *val, *lval = NULL;
1973 int size = getSize (arrExpr->left->ftype->next);
1974 /* if the right or left is an array
1976 if (IS_AST_OP (arrExpr->left))
1978 if (arrExpr->left->opval.op == '[')
1979 lval = valForArray (arrExpr->left);
1980 else if (arrExpr->left->opval.op == '.')
1981 lval = valForStructElem (arrExpr->left->left,
1982 arrExpr->left->right);
1983 else if (arrExpr->left->opval.op == PTR_OP &&
1984 IS_ADDRESS_OF_OP (arrExpr->left->left))
1985 lval = valForStructElem (arrExpr->left->left->left,
1986 arrExpr->left->right);
1991 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1994 if (!IS_AST_LIT_VALUE (arrExpr->right))
2000 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
2004 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2007 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2008 (int) AST_LIT_VALUE (arrExpr->right) * size);
2010 val->type = newLink (DECLARATOR);
2011 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
2012 DCL_TYPE (val->type) = CPOINTER;
2013 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
2014 DCL_TYPE (val->type) = FPOINTER;
2015 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
2016 DCL_TYPE (val->type) = PPOINTER;
2017 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
2018 DCL_TYPE (val->type) = IPOINTER;
2019 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
2020 DCL_TYPE (val->type) = EEPPOINTER;
2022 DCL_TYPE (val->type) = POINTER;
2023 val->type->next = arrExpr->left->ftype->next;
2024 val->etype = getSpec (val->type);
2028 /*-----------------------------------------------------------------*/
2029 /* valForStructElem - returns value with name of struct element */
2030 /*-----------------------------------------------------------------*/
2032 valForStructElem (ast * structT, ast * elemT)
2034 value *val, *lval = NULL;
2038 /* left could be furthur derefed */
2039 if (IS_AST_OP (structT))
2041 if (structT->opval.op == '[')
2042 lval = valForArray (structT);
2043 else if (structT->opval.op == '.')
2044 lval = valForStructElem (structT->left, structT->right);
2045 else if (structT->opval.op == PTR_OP &&
2046 IS_ADDRESS_OF_OP (structT->left))
2047 lval = valForStructElem (structT->left->left,
2053 if (!IS_AST_SYM_VALUE (elemT))
2056 if (!IS_STRUCT (structT->etype))
2059 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2060 AST_SYMBOL (elemT))) == NULL)
2068 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2072 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2075 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2078 val->type = newLink (DECLARATOR);
2079 if (SPEC_SCLS (structT->etype) == S_CODE)
2080 DCL_TYPE (val->type) = CPOINTER;
2081 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2082 DCL_TYPE (val->type) = FPOINTER;
2083 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2084 DCL_TYPE (val->type) = PPOINTER;
2085 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2086 DCL_TYPE (val->type) = IPOINTER;
2087 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2088 DCL_TYPE (val->type) = EEPPOINTER;
2090 DCL_TYPE (val->type) = POINTER;
2091 val->type->next = sym->type;
2092 val->etype = getSpec (val->type);
2096 /*-----------------------------------------------------------------*/
2097 /* valForCastAggr - will return value for a cast of an aggregate */
2098 /* plus minus a constant */
2099 /*-----------------------------------------------------------------*/
2101 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2105 if (!IS_AST_SYM_VALUE (aexpr))
2107 if (!IS_AST_LIT_VALUE (cnst))
2112 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2113 AST_SYMBOL (aexpr)->rname, op,
2114 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2117 val->etype = getSpec (val->type);
2121 /*-----------------------------------------------------------------*/
2122 /* valForCastAggr - will return value for a cast of an aggregate */
2123 /* with no constant */
2124 /*-----------------------------------------------------------------*/
2126 valForCastArr (ast * aexpr, sym_link * type)
2130 if (!IS_AST_SYM_VALUE (aexpr))
2135 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2136 AST_SYMBOL (aexpr)->rname);
2139 val->etype = getSpec (val->type);