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 = lexLineno;
61 nilist->filename = lexFilename;
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 int is_ptr = IS_PTR (type);
277 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
281 if (ilist->type == INIT_NODE)
283 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
284 is_ptr ? RESULT_TYPE_INT : resultType);
286 else if (ilist->type == INIT_DEEP)
288 resolveIvalSym (ilist->init.deep, type);
295 /*------------------------------------------------------------------*/
296 /* symbolVal - creates a value for a symbol */
297 /*------------------------------------------------------------------*/
299 symbolVal (symbol * sym)
311 val->type = sym->type;
312 val->etype = getSpec (val->type);
317 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
321 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
327 /*--------------------------------------------------------------------*/
328 /* cheapestVal - try to reduce 'signed int' to 'char' */
329 /*--------------------------------------------------------------------*/
331 cheapestVal (value *val)
333 /* only int can be reduced */
334 if (!IS_INT(val->type))
337 /* long must not be changed */
338 if (SPEC_LONG(val->type))
341 /* unsigned must not be changed */
342 if (SPEC_USIGN(val->type))
345 /* the only possible reduction is from signed int to (un)signed char,
346 because it's automatically promoted back to signed int.
348 a reduction from unsigned int to unsigned char is a bug,
349 because an _unsigned_ char is promoted to _signed_ int! */
350 if (SPEC_CVAL(val->type).v_int < -128 ||
351 SPEC_CVAL(val->type).v_int > 255)
353 /* not in the range of (un)signed char */
357 SPEC_NOUN(val->type) = V_CHAR;
359 /* 'unsigned char' promotes to 'signed int', so that we can
360 reduce it the other way */
361 if (SPEC_CVAL(val->type).v_int >= 0)
363 SPEC_USIGN(val->type) = 1;
368 /*--------------------------------------------------------------------*/
369 /* checkConstantRange - check if constant fits in numeric range of */
370 /* var type in comparisons and assignments */
371 /*--------------------------------------------------------------------*/
373 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
379 litVal = floatFromVal (valFromType (lit));
380 varBits = bitsForType (var);
387 return CCR_ALWAYS_FALSE;
389 return CCR_ALWAYS_TRUE;
391 /* special: assignment */
397 if (getenv ("SDCC_VERY_PEDANTIC"))
399 if (SPEC_USIGN (var))
401 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
410 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
411 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
421 /* ignore signedness, e.g. allow everything
422 from -127...+255 for (unsigned) char */
423 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
424 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
433 if (exchangeLeftRight)
438 case '>': op = '<'; break;
439 case GE_OP: op = LE_OP; break;
440 case '<': op = '>'; break;
441 case LE_OP: op = GE_OP; break;
442 default: return CCR_ALWAYS_FALSE;
445 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
447 if (SPEC_USIGN (reType))
449 /* unsigned operation */
450 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
451 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
453 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
455 /* both operands are unsigned, this is easy */
457 maxValP = 0xffffffffu >> (32 - varBits);
458 /* there's only range, just copy it to 2nd set */
462 else if (SPEC_USIGN (var))
464 /* lit is casted from signed to unsigned, e.g.:
470 maxValP = 0xffffffffu >> (32 - varBits);
471 /* there's only one range, just copy it to 2nd set */
475 /* it's an unsigned operation */
476 if ( IS_CHAR (reType)
479 /* make signed literal unsigned and
480 limit no of bits to size of return type */
481 litVal = (TYPE_TARGET_ULONG) double2ul (litVal) & opBitsMask;
484 else /* SPEC_USIGN (lit) */
486 /* var is casted from signed to unsigned, e.g.:
491 The possible values after casting var
492 split up in two, nonconsecutive ranges:
494 minValP = 0; positive range: 0...127
496 minValM = 0xff80; negative range: -128...-1
502 maxValP = 0x7fffffffu >> (32 - varBits);
505 minValM = 0xffffffff << (varBits - 1);
506 maxValM = 0xffffffffu; /* -1 */
507 /* limit no of bits to size of return type */
508 minValM &= opBitsMask;
509 maxValM &= opBitsMask;
514 case EQ_OP: /* var == lit */
515 if ( litVal <= maxValP
516 && litVal >= minValP) /* 0 */
518 if ( litVal <= maxValM
519 && litVal >= minValM)
521 return CCR_ALWAYS_FALSE;
522 case NE_OP: /* var != lit */
523 if ( litVal <= maxValP
524 && litVal >= minValP) /* 0 */
526 if ( litVal <= maxValM
527 && litVal >= minValM)
529 return CCR_ALWAYS_TRUE;
530 case '>': /* var > lit */
531 if (litVal >= maxValM)
532 return CCR_ALWAYS_FALSE;
533 if (litVal < minValP) /* 0 */
534 return CCR_ALWAYS_TRUE;
536 case GE_OP: /* var >= lit */
537 if (litVal > maxValM)
538 return CCR_ALWAYS_FALSE;
539 if (litVal <= minValP) /* 0 */
540 return CCR_ALWAYS_TRUE;
542 case '<': /* var < lit */
543 if (litVal > maxValM)
544 return CCR_ALWAYS_TRUE;
545 if (litVal <= minValP) /* 0 */
546 return CCR_ALWAYS_FALSE;
548 case LE_OP: /* var <= lit */
549 if (litVal >= maxValM)
550 return CCR_ALWAYS_TRUE;
551 if (litVal < minValP) /* 0 */
552 return CCR_ALWAYS_FALSE;
555 return CCR_ALWAYS_FALSE;
560 /* signed operation */
561 TYPE_TARGET_LONG minVal, maxVal;
563 if (SPEC_USIGN (var))
565 /* unsigned var, but signed operation. This happens
566 when var is promoted to signed int.
567 Set actual min/max values of var. */
569 maxVal = 0xffffffff >> (32 - varBits);
574 minVal = 0xffffffff << (varBits - 1);
575 maxVal = 0x7fffffff >> (32 - varBits);
580 case EQ_OP: /* var == lit */
583 return CCR_ALWAYS_FALSE;
585 case NE_OP: /* var != lit */
588 return CCR_ALWAYS_TRUE;
590 case '>': /* var > lit */
591 if (litVal >= maxVal)
592 return CCR_ALWAYS_FALSE;
594 return CCR_ALWAYS_TRUE;
596 case GE_OP: /* var >= lit */
598 return CCR_ALWAYS_FALSE;
599 if (litVal <= minVal)
600 return CCR_ALWAYS_TRUE;
602 case '<': /* var < lit */
604 return CCR_ALWAYS_TRUE;
605 if (litVal <= minVal)
606 return CCR_ALWAYS_FALSE;
608 case LE_OP: /* var <= lit */
609 if (litVal >= maxVal)
610 return CCR_ALWAYS_TRUE;
612 return CCR_ALWAYS_FALSE;
615 return CCR_ALWAYS_FALSE;
620 /*-----------------------------------------------------------------*/
621 /* valueFromLit - creates a value from a literal */
622 /*-----------------------------------------------------------------*/
624 valueFromLit (double lit)
628 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
630 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
631 return constVal (buffer);
634 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
635 return constFloatVal (buffer);
638 /*-----------------------------------------------------------------*/
639 /* constFloatVal - converts a FLOAT constant to value */
640 /*-----------------------------------------------------------------*/
642 constFloatVal (char *s)
644 value *val = newValue ();
648 sval = strtod(s, &p);
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 ();
673 sval = strtod(s, &p);
676 werror (E_INVALID_FLOAT_CONST, s);
677 return constVal ("0");
680 val->type = val->etype = newLink (SPECIFIER);
681 SPEC_NOUN (val->type) = V_FLOAT;
682 SPEC_SCLS (val->type) = S_LITERAL;
683 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
688 /*-----------------------------------------------------------------*/
689 /* constVal - converts an INTEGER constant into a cheapest value */
690 /*-----------------------------------------------------------------*/
691 value *constVal (const char *s)
694 short hex = 0, octal = 0;
697 val = newValue (); /* alloc space for value */
699 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
700 SPEC_SCLS (val->type) = S_LITERAL;
701 /* let's start with a signed char */
702 SPEC_NOUN (val->type) = V_CHAR;
703 SPEC_USIGN (val->type) = 0;
705 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
707 /* set the octal flag */
708 if (!hex && *s == '0' && *(s + 1))
714 sval = strtoul (s, NULL, 0);
718 werror (W_INVALID_INT_CONST, s, dval);
721 dval = strtod(s, NULL);
724 /* Setup the flags first */
725 /* set the unsigned flag if 'uU' is found */
726 if (strchr (s, 'u') || strchr (s, 'U')) {
727 SPEC_USIGN (val->type) = 1;
730 /* set the b_long flag if 'lL' is found */
731 if (strchr (s, 'l') || strchr (s, 'L')) {
732 SPEC_NOUN (val->type) = V_INT;
733 SPEC_LONG (val->type) = 1;
735 if (dval<0) { /* "-28u" will still be signed and negative */
736 if (dval<-128) { /* check if we have to promote to int */
737 SPEC_NOUN (val->type) = V_INT;
739 if (dval<-32768) { /* check if we have to promote to long int */
740 SPEC_LONG (val->type) = 1;
743 if (dval>0xff || /* check if we have to promote to int */
744 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
745 char. After an integral promotion it will
746 be a signed int; this certainly isn't what
747 the programer wants */
748 SPEC_NOUN (val->type) = V_INT;
750 else { /* store char's always as unsigned; this helps other optimizations */
751 SPEC_USIGN (val->type) = 1;
753 if (dval>0xffff && SPEC_USIGN (val->type)) { /* check if we have to promote to long */
754 SPEC_LONG (val->type) = 1;
756 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { /* check if we have to promote to long int */
757 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
759 SPEC_USIGN (val->type) = 1;
761 SPEC_LONG (val->type) = 1;
762 if (dval>0x7fffffff) {
763 SPEC_USIGN (val->type) = 1;
770 /* check for out of range */
771 if (dval<-2147483648.0) {
772 dval = -2147483648.0;
773 werror (W_INVALID_INT_CONST, s, dval);
775 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
777 werror (W_INVALID_INT_CONST, s, dval);
779 if (dval>4294967295.0) {
781 werror (W_INVALID_INT_CONST, s, dval);
784 if (SPEC_LONG (val->type))
786 if (SPEC_USIGN (val->type))
788 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
792 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
797 if (SPEC_USIGN (val->type))
799 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
803 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
810 /*------------------------------------------------------------------*/
811 /* strVal - converts a string constant to a value */
812 /*------------------------------------------------------------------*/
814 strVal (const char *s)
818 val = newValue (); /* get a new one */
820 /* get a declarator */
821 val->type = newLink (DECLARATOR);
822 DCL_TYPE (val->type) = ARRAY;
823 val->type->next = val->etype = newLink (SPECIFIER);
824 SPEC_NOUN (val->etype) = V_CHAR;
825 SPEC_SCLS (val->etype) = S_LITERAL;
827 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
828 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
834 /*------------------------------------------------------------------*/
835 /* reverseValWithType - reverses value chain with type & etype */
836 /*------------------------------------------------------------------*/
838 reverseValWithType (value * val)
846 /* save the type * etype chains */
850 /* set the current one 2b null */
851 val->type = val->etype = NULL;
852 val = reverseVal (val);
854 /* restore type & etype */
861 /*------------------------------------------------------------------*/
862 /* reverseVal - reverses the values for a value chain */
863 /*------------------------------------------------------------------*/
865 reverseVal (value * val)
867 value *prev, *curr, *next;
882 val->next = (void *) NULL;
886 /*------------------------------------------------------------------*/
887 /* copyValueChain - will copy a chain of values */
888 /*------------------------------------------------------------------*/
890 copyValueChain (value * src)
897 dest = copyValue (src);
898 dest->next = copyValueChain (src->next);
903 /*------------------------------------------------------------------*/
904 /* copyValue - copies contents of a value to a fresh one */
905 /*------------------------------------------------------------------*/
907 copyValue (value * src)
912 dest->sym = copySymbol (src->sym);
913 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
914 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
915 dest->etype = (src->type ? getSpec (dest->type) : NULL);
920 /*------------------------------------------------------------------*/
921 /* charVal - converts a character constant to a value */
922 /*------------------------------------------------------------------*/
924 charVal (const char *s)
930 val->type = val->etype = newLink (SPECIFIER);
931 SPEC_NOUN (val->type) = V_CHAR;
932 SPEC_USIGN(val->type) = 1;
933 SPEC_SCLS (val->type) = S_LITERAL;
935 s++; /* get rid of quotation */
936 /* if \ then special processing */
939 s++; /* go beyond the backslash */
943 SPEC_CVAL (val->type).v_uint = '\n';
946 SPEC_CVAL (val->type).v_uint = '\t';
949 SPEC_CVAL (val->type).v_uint = '\v';
952 SPEC_CVAL (val->type).v_uint = '\b';
955 SPEC_CVAL (val->type).v_uint = '\r';
958 SPEC_CVAL (val->type).v_uint = '\f';
961 SPEC_CVAL (val->type).v_uint = '\a';
964 SPEC_CVAL (val->type).v_uint = '\\';
967 SPEC_CVAL (val->type).v_uint = '\?';
970 SPEC_CVAL (val->type).v_uint = '\'';
973 SPEC_CVAL (val->type).v_uint = '\"';
984 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
988 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
992 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
996 else /* not a backslash */
997 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1002 /*------------------------------------------------------------------*/
1003 /* valFromType - creates a value from type given */
1004 /*------------------------------------------------------------------*/
1006 valFromType (sym_link * type)
1008 value *val = newValue ();
1009 val->type = copyLinkChain (type);
1010 val->etype = getSpec (val->type);
1014 /*------------------------------------------------------------------*/
1015 /* floatFromVal - value to double float conversion */
1016 /*------------------------------------------------------------------*/
1018 floatFromVal (value * val)
1023 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1025 werror (E_CONST_EXPECTED, val->name);
1029 /* if it is not a specifier then we can assume that */
1030 /* it will be an unsigned long */
1031 if (!IS_SPEC (val->type))
1032 return SPEC_CVAL (val->etype).v_ulong;
1034 if (SPEC_NOUN (val->etype) == V_FLOAT)
1035 return SPEC_CVAL (val->etype).v_float;
1037 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1038 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1040 if (SPEC_LONG (val->etype))
1042 if (SPEC_USIGN (val->etype))
1043 return SPEC_CVAL (val->etype).v_ulong;
1045 return SPEC_CVAL (val->etype).v_long;
1048 if (SPEC_NOUN (val->etype) == V_INT)
1050 if (SPEC_USIGN (val->etype))
1051 return SPEC_CVAL (val->etype).v_uint;
1053 return SPEC_CVAL (val->etype).v_int;
1056 if (SPEC_NOUN (val->etype) == V_CHAR)
1058 if (SPEC_USIGN (val->etype))
1059 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1061 return (signed char) SPEC_CVAL (val->etype).v_int;
1064 if (IS_BITVAR(val->etype))
1065 return SPEC_CVAL (val->etype).v_uint;
1067 if (SPEC_NOUN (val->etype) == V_VOID)
1068 return SPEC_CVAL (val->etype).v_ulong;
1071 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1075 /*------------------------------------------------------------------*/
1076 /* ulFromVal - value to unsigned long conversion */
1077 /*------------------------------------------------------------------*/
1079 ulFromVal (value * val)
1084 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1086 werror (E_CONST_EXPECTED, val->name);
1090 /* if it is not a specifier then we can assume that */
1091 /* it will be an unsigned long */
1092 if (!IS_SPEC (val->type))
1093 return SPEC_CVAL (val->etype).v_ulong;
1095 if (SPEC_NOUN (val->etype) == V_FLOAT)
1096 return double2ul (SPEC_CVAL (val->etype).v_float);
1098 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1099 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1101 if (SPEC_LONG (val->etype))
1103 if (SPEC_USIGN (val->etype))
1104 return SPEC_CVAL (val->etype).v_ulong;
1106 return SPEC_CVAL (val->etype).v_long;
1109 if (SPEC_NOUN (val->etype) == V_INT)
1111 if (SPEC_USIGN (val->etype))
1112 return SPEC_CVAL (val->etype).v_uint;
1114 return SPEC_CVAL (val->etype).v_int;
1117 if (SPEC_NOUN (val->etype) == V_CHAR)
1119 if (SPEC_USIGN (val->etype))
1120 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1122 return (signed char) SPEC_CVAL (val->etype).v_int;
1125 if (IS_BITVAR(val->etype))
1126 return SPEC_CVAL (val->etype).v_uint;
1128 if (SPEC_NOUN (val->etype) == V_VOID)
1129 return SPEC_CVAL (val->etype).v_ulong;
1132 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1136 /*-----------------------------------------------------------------*/
1137 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1138 /*-----------------------------------------------------------------*/
1139 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1142 /* This version is incorrect negative values. */
1143 double tmp=0, exp=2;
1145 tmp = (value & 0xffff0000) >> 16;
1149 if(value & 0x8000)tmp += 1/exp;
1156 return ((double)(value * 1.0) / (double)(1UL << 16));
1160 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1163 /* This version is incorrect negative values. */
1164 unsigned int tmp=0, pos=16;
1165 TYPE_TARGET_ULONG res;
1167 tmp = floor( value );
1174 if(value >= 1.0)tmp |= (1 << pos);
1175 value -= floor( value );
1182 return double2ul (value * (double)(1UL << 16));
1186 /*------------------------------------------------------------------*/
1187 /* valUnaryPM - does the unary +/- operation on a constant */
1188 /*------------------------------------------------------------------*/
1190 valUnaryPM (value * val)
1192 /* depending on type */
1193 if (SPEC_NOUN (val->etype) == V_FLOAT)
1194 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1195 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1196 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) -((long) SPEC_CVAL (val->etype).v_fixed16x16);
1199 if (SPEC_LONG (val->etype))
1201 if (SPEC_USIGN (val->etype))
1202 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1204 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1208 if (SPEC_USIGN (val->etype))
1209 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1211 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1213 if (SPEC_NOUN(val->etype) == V_CHAR)
1215 /* promote to 'signed int', cheapestVal() might reduce it again */
1216 SPEC_USIGN(val->etype) = 0;
1217 SPEC_NOUN(val->etype) = V_INT;
1219 return cheapestVal (val);
1225 /*------------------------------------------------------------------*/
1226 /* valueComplement - complements a constant */
1227 /*------------------------------------------------------------------*/
1229 valComplement (value * val)
1231 /* depending on type */
1232 if (SPEC_LONG (val->etype))
1234 if (SPEC_USIGN (val->etype))
1235 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1237 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1241 if (SPEC_USIGN (val->etype))
1242 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1244 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1246 if (SPEC_NOUN(val->etype) == V_CHAR)
1248 /* promote to 'signed int', cheapestVal() might reduce it again */
1249 SPEC_USIGN(val->etype) = 0;
1250 SPEC_NOUN(val->etype) = V_INT;
1252 return cheapestVal (val);
1257 /*------------------------------------------------------------------*/
1258 /* valueNot - complements a constant */
1259 /*------------------------------------------------------------------*/
1261 valNot (value * val)
1263 /* depending on type */
1264 if (SPEC_LONG (val->etype))
1266 if (SPEC_USIGN (val->etype))
1267 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1269 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1273 if (SPEC_USIGN (val->etype))
1274 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1276 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1279 /* ANSI: result type is int, value is 0 or 1 */
1280 /* sdcc will hold this in an 'unsigned char' */
1281 SPEC_USIGN(val->etype) = 1;
1282 SPEC_LONG (val->etype) = 0;
1283 SPEC_NOUN(val->etype) = V_CHAR;
1287 /*------------------------------------------------------------------*/
1288 /* valMult - multiply constants */
1289 /*------------------------------------------------------------------*/
1291 valMult (value * lval, value * rval)
1295 /* create a new value */
1297 val->type = val->etype = computeType (lval->etype,
1301 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1303 if (IS_FLOAT (val->type))
1304 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1306 if (IS_FIXED16X16 (val->type))
1307 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1308 /* signed and unsigned mul are the same, as long as the precision of the
1309 result isn't bigger than the precision of the operands. */
1310 else if (SPEC_LONG (val->type))
1311 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1312 (TYPE_TARGET_ULONG) ulFromVal (rval);
1313 else if (SPEC_USIGN (val->type)) /* unsigned int */
1315 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1316 (TYPE_TARGET_UINT) ulFromVal (rval);
1318 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1319 if (ul != (TYPE_TARGET_UINT) ul)
1322 else /* signed int */
1324 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1325 (TYPE_TARGET_INT) floatFromVal (rval);
1327 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1328 if (l != (TYPE_TARGET_INT) l)
1331 return cheapestVal (val);
1334 /*------------------------------------------------------------------*/
1335 /* valDiv - Divide constants */
1336 /*------------------------------------------------------------------*/
1338 valDiv (value * lval, value * rval)
1342 if (floatFromVal (rval) == 0)
1344 werror (E_DIVIDE_BY_ZERO);
1348 /* create a new value */
1350 val->type = val->etype = computeType (lval->etype,
1354 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1356 if (IS_FLOAT (val->type))
1357 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1359 if (IS_FIXED16X16 (val->type))
1360 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1361 else if (SPEC_LONG (val->type))
1363 if (SPEC_USIGN (val->type))
1364 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1365 (TYPE_TARGET_ULONG) ulFromVal (rval);
1367 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1368 (TYPE_TARGET_LONG) ulFromVal (rval);
1372 if (SPEC_USIGN (val->type))
1373 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1374 (TYPE_TARGET_UINT) ulFromVal (rval);
1376 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1377 (TYPE_TARGET_INT) ulFromVal (rval);
1379 return cheapestVal (val);
1382 /*------------------------------------------------------------------*/
1383 /* valMod - Modulus constants */
1384 /*------------------------------------------------------------------*/
1386 valMod (value * lval, value * rval)
1390 /* create a new value */
1392 val->type = val->etype = computeType (lval->etype,
1396 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1398 if (SPEC_LONG (val->type))
1400 if (SPEC_USIGN (val->type))
1401 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1402 (TYPE_TARGET_ULONG) ulFromVal (rval);
1404 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1405 (TYPE_TARGET_LONG) ulFromVal (rval);
1409 if (SPEC_USIGN (val->type))
1410 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1411 (TYPE_TARGET_UINT) ulFromVal (rval);
1413 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1414 (TYPE_TARGET_INT) ulFromVal (rval);
1416 return cheapestVal (val);
1419 /*------------------------------------------------------------------*/
1420 /* valPlus - Addition constants */
1421 /*------------------------------------------------------------------*/
1423 valPlus (value * lval, value * rval)
1427 /* create a new value */
1429 val->type = val->etype = computeType (lval->etype,
1433 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1435 if (IS_FLOAT (val->type))
1436 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1438 if (IS_FIXED16X16 (val->type))
1439 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1440 else if (SPEC_LONG (val->type))
1442 if (SPEC_USIGN (val->type))
1443 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1444 (TYPE_TARGET_ULONG) ulFromVal (rval);
1446 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1447 (TYPE_TARGET_LONG) ulFromVal (rval);
1451 if (SPEC_USIGN (val->type))
1452 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1453 (TYPE_TARGET_UINT) ulFromVal (rval);
1455 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1456 (TYPE_TARGET_INT) ulFromVal (rval);
1458 return cheapestVal (val);
1461 /*------------------------------------------------------------------*/
1462 /* valMinus - Addition constants */
1463 /*------------------------------------------------------------------*/
1465 valMinus (value * lval, value * rval)
1469 /* create a new value */
1471 val->type = val->etype = computeType (lval->etype,
1475 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1477 if (IS_FLOAT (val->type))
1478 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1480 if (IS_FIXED16X16 (val->type))
1481 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1482 else if (SPEC_LONG (val->type))
1484 if (SPEC_USIGN (val->type))
1485 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1486 (TYPE_TARGET_ULONG) ulFromVal (rval);
1488 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1489 (TYPE_TARGET_LONG) ulFromVal (rval);
1493 if (SPEC_USIGN (val->type))
1494 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1495 (TYPE_TARGET_UINT) ulFromVal (rval);
1497 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1498 (TYPE_TARGET_INT) ulFromVal (rval);
1500 return cheapestVal (val);
1503 /*------------------------------------------------------------------*/
1504 /* valShift - Shift left or right */
1505 /*------------------------------------------------------------------*/
1507 valShift (value * lval, value * rval, int lr)
1511 /* create a new value */
1513 val->type = val->etype = computeType (lval->etype,
1517 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1519 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1522 /* right shift and unsigned */
1523 (!lr && SPEC_USIGN (rval->type))))
1525 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1528 if (SPEC_LONG (val->type))
1530 if (SPEC_USIGN (val->type))
1532 SPEC_CVAL (val->type).v_ulong = lr ?
1533 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1534 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1538 SPEC_CVAL (val->type).v_long = lr ?
1539 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1540 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1545 if (SPEC_USIGN (val->type))
1547 SPEC_CVAL (val->type).v_uint = lr ?
1548 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1549 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1553 SPEC_CVAL (val->type).v_int = lr ?
1554 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1555 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1558 return cheapestVal (val);
1561 /*------------------------------------------------------------------*/
1562 /* valCompare- Compares two literal */
1563 /*------------------------------------------------------------------*/
1565 valCompare (value * lval, value * rval, int ctype)
1569 /* create a new value */
1571 val->type = val->etype = newCharLink ();
1572 val->type->class = SPECIFIER;
1573 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1574 SPEC_USIGN (val->type) = 1;
1575 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1580 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1584 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1588 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1592 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1596 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1597 SPEC_NOUN(rval->type) == V_FLOAT)
1599 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1602 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1603 SPEC_NOUN(rval->type) == V_FIXED16X16)
1605 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1609 /* integrals: ignore signedness */
1610 TYPE_TARGET_ULONG l, r;
1612 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1613 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1614 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1615 neccessary to strip them to 16 bit.
1616 Literals are reduced to their cheapest type, therefore left and
1617 right might have different types. It's neccessary to find a
1618 common type: int (used for char too) or long */
1619 if (!IS_LONG (lval->etype) &&
1620 !IS_LONG (rval->etype))
1622 r = (TYPE_TARGET_UINT) r;
1623 l = (TYPE_TARGET_UINT) l;
1625 SPEC_CVAL (val->type).v_int = l == r;
1629 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1630 SPEC_NOUN(rval->type) == V_FLOAT)
1632 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1635 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1636 SPEC_NOUN(rval->type) == V_FIXED16X16)
1638 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1642 /* integrals: ignore signedness */
1643 TYPE_TARGET_ULONG l, r;
1645 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1646 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1647 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1648 neccessary to strip them to 16 bit.
1649 Literals are reduced to their cheapest type, therefore left and
1650 right might have different types. It's neccessary to find a
1651 common type: int (used for char too) or long */
1652 if (!IS_LONG (lval->etype) &&
1653 !IS_LONG (rval->etype))
1655 r = (TYPE_TARGET_UINT) r;
1656 l = (TYPE_TARGET_UINT) l;
1658 SPEC_CVAL (val->type).v_int = l != r;
1667 /*------------------------------------------------------------------*/
1668 /* valBitwise - Bitwise operation */
1669 /*------------------------------------------------------------------*/
1671 valBitwise (value * lval, value * rval, int op)
1675 /* create a new value */
1677 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1678 val->etype = getSpec (val->type);
1679 SPEC_SCLS (val->etype) = S_LITERAL;
1684 if (SPEC_LONG (val->type))
1686 if (SPEC_USIGN (val->type))
1687 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1688 (TYPE_TARGET_ULONG) ulFromVal (rval);
1690 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1691 (TYPE_TARGET_LONG) ulFromVal (rval);
1695 if (SPEC_USIGN (val->type))
1696 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1697 (TYPE_TARGET_UINT) ulFromVal (rval);
1699 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1700 (TYPE_TARGET_INT) ulFromVal (rval);
1705 if (SPEC_LONG (val->type))
1707 if (SPEC_USIGN (val->type))
1708 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1709 (TYPE_TARGET_ULONG) ulFromVal (rval);
1711 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1712 (TYPE_TARGET_LONG) ulFromVal (rval);
1716 if (SPEC_USIGN (val->type))
1717 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1718 (TYPE_TARGET_UINT) ulFromVal (rval);
1720 SPEC_CVAL (val->type).v_int =
1721 (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1727 if (SPEC_LONG (val->type))
1729 if (SPEC_USIGN (val->type))
1730 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1731 (TYPE_TARGET_ULONG) ulFromVal (rval);
1733 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1734 (TYPE_TARGET_LONG) ulFromVal (rval);
1738 if (SPEC_USIGN (val->type))
1739 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1740 (TYPE_TARGET_UINT) ulFromVal (rval);
1742 SPEC_CVAL (val->type).v_int =
1743 (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1748 return cheapestVal(val);
1751 /*------------------------------------------------------------------*/
1752 /* valAndOr - Generates code for and / or operation */
1753 /*------------------------------------------------------------------*/
1755 valLogicAndOr (value * lval, value * rval, int op)
1759 /* create a new value */
1761 val->type = val->etype = newCharLink ();
1762 val->type->class = SPECIFIER;
1763 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1764 SPEC_USIGN (val->type) = 1;
1769 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1773 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1781 /*------------------------------------------------------------------*/
1782 /* valCastLiteral - casts a literal value to another type */
1783 /*------------------------------------------------------------------*/
1785 valCastLiteral (sym_link * dtype, double fval)
1788 unsigned long l = double2ul (fval);
1795 val->etype = getSpec (val->type = copyLinkChain (dtype));
1798 val->etype = val->type = newLink (SPECIFIER);
1799 SPEC_NOUN (val->etype) = V_VOID;
1801 SPEC_SCLS (val->etype) = S_LITERAL;
1803 /* if it is not a specifier then we can assume that */
1804 /* it will be an unsigned long */
1805 if (!IS_SPEC (val->type))
1807 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1811 switch (SPEC_NOUN (val->etype))
1814 SPEC_CVAL (val->etype).v_float = fval;
1818 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1823 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1827 SPEC_CVAL (val->etype).v_uint = ((TYPE_TARGET_UINT) l) &
1828 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1832 if (SPEC_USIGN (val->etype))
1833 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1835 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1839 if (SPEC_LONG (val->etype))
1841 if (SPEC_USIGN (val->etype))
1842 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1844 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1848 if (SPEC_USIGN (val->etype))
1849 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1851 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1858 /*------------------------------------------------------------------*/
1859 /* getNelements - determines # of elements from init list */
1860 /*------------------------------------------------------------------*/
1862 getNelements (sym_link * type, initList * ilist)
1869 if (ilist->type == INIT_DEEP)
1870 ilist = ilist->init.deep;
1872 /* if type is a character array and there is only one
1873 (string) initialiser then get the length of the string */
1874 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1876 ast *iast = ilist->init.node;
1877 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1880 werror (E_CONST_EXPECTED);
1884 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1885 /* yep, it's a string */
1887 return DCL_ELEM (v->type);
1895 ilist = ilist->next;
1900 /*-----------------------------------------------------------------*/
1901 /* valForArray - returns a value with name of array index */
1902 /*-----------------------------------------------------------------*/
1904 valForArray (ast * arrExpr)
1906 value *val, *lval = NULL;
1908 int size = getSize (arrExpr->left->ftype->next);
1909 /* if the right or left is an array
1911 if (IS_AST_OP (arrExpr->left))
1913 if (arrExpr->left->opval.op == '[')
1914 lval = valForArray (arrExpr->left);
1915 else if (arrExpr->left->opval.op == '.')
1916 lval = valForStructElem (arrExpr->left->left,
1917 arrExpr->left->right);
1918 else if (arrExpr->left->opval.op == PTR_OP &&
1919 IS_ADDRESS_OF_OP (arrExpr->left->left))
1920 lval = valForStructElem (arrExpr->left->left->left,
1921 arrExpr->left->right);
1926 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1929 if (!IS_AST_LIT_VALUE (arrExpr->right))
1935 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1939 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1942 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1943 (int) AST_LIT_VALUE (arrExpr->right) * size);
1945 val->type = newLink (DECLARATOR);
1946 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1947 DCL_TYPE (val->type) = CPOINTER;
1948 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1949 DCL_TYPE (val->type) = FPOINTER;
1950 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1951 DCL_TYPE (val->type) = PPOINTER;
1952 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1953 DCL_TYPE (val->type) = IPOINTER;
1954 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1955 DCL_TYPE (val->type) = EEPPOINTER;
1957 DCL_TYPE (val->type) = POINTER;
1958 val->type->next = arrExpr->left->ftype->next;
1959 val->etype = getSpec (val->type);
1963 /*-----------------------------------------------------------------*/
1964 /* valForStructElem - returns value with name of struct element */
1965 /*-----------------------------------------------------------------*/
1967 valForStructElem (ast * structT, ast * elemT)
1969 value *val, *lval = NULL;
1973 /* left could be furthur derefed */
1974 if (IS_AST_OP (structT))
1976 if (structT->opval.op == '[')
1977 lval = valForArray (structT);
1978 else if (structT->opval.op == '.')
1979 lval = valForStructElem (structT->left, structT->right);
1980 else if (structT->opval.op == PTR_OP &&
1981 IS_ADDRESS_OF_OP (structT->left))
1982 lval = valForStructElem (structT->left->left,
1988 if (!IS_AST_SYM_VALUE (elemT))
1991 if (!IS_STRUCT (structT->etype))
1994 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1995 AST_SYMBOL (elemT))) == NULL)
2003 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2007 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2010 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2013 val->type = newLink (DECLARATOR);
2014 if (SPEC_SCLS (structT->etype) == S_CODE)
2015 DCL_TYPE (val->type) = CPOINTER;
2016 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2017 DCL_TYPE (val->type) = FPOINTER;
2018 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2019 DCL_TYPE (val->type) = PPOINTER;
2020 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2021 DCL_TYPE (val->type) = IPOINTER;
2022 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2023 DCL_TYPE (val->type) = EEPPOINTER;
2025 DCL_TYPE (val->type) = POINTER;
2026 val->type->next = sym->type;
2027 val->etype = getSpec (val->type);
2031 /*-----------------------------------------------------------------*/
2032 /* valForCastAggr - will return value for a cast of an aggregate */
2033 /* plus minus a constant */
2034 /*-----------------------------------------------------------------*/
2036 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2040 if (!IS_AST_SYM_VALUE (aexpr))
2042 if (!IS_AST_LIT_VALUE (cnst))
2047 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2048 AST_SYMBOL (aexpr)->rname, op,
2049 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2052 val->etype = getSpec (val->type);
2056 /*-----------------------------------------------------------------*/
2057 /* valForCastAggr - will return value for a cast of an aggregate */
2058 /* with no constant */
2059 /*-----------------------------------------------------------------*/
2061 valForCastArr (ast * aexpr, sym_link * type)
2065 if (!IS_AST_SYM_VALUE (aexpr))
2070 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2071 AST_SYMBOL (aexpr)->rname);
2074 val->etype = getSpec (val->type);