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)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->filename = lexFilename;
60 nilist->lineno = lexLineno;
65 nilist->init.node = (struct ast *) ilist;
69 nilist->init.deep = (struct initList *) ilist;
76 /*------------------------------------------------------------------*/
77 /* revinit - reverses the initial values for a value chain */
78 /*------------------------------------------------------------------*/
80 revinit (initList * val)
82 initList *prev, *curr, *next;
97 val->next = (void *) NULL;
102 convertIListToConstList(initList *src, literalList **lList, int size)
106 literalList *head, *last, *newL;
110 if (src && src->type != INIT_DEEP)
115 iLoop = src ? src->init.deep : NULL;
119 if (iLoop->type != INIT_NODE)
124 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
136 /* We've now established that the initializer list contains only literal values. */
138 iLoop = src ? src->init.deep : NULL;
141 double val = iLoop ? AST_FLOAT_VALUE(iLoop->init.node) : 0;
143 if (last && last->literalValue == val)
149 newL = Safe_alloc(sizeof(literalList));
150 newL->literalValue = val;
164 iLoop = iLoop ? iLoop->next : NULL;
177 copyLiteralList(literalList *src)
179 literalList *head, *prev, *newL;
185 newL = Safe_alloc(sizeof(literalList));
187 newL->literalValue = src->literalValue;
188 newL->count = src->count;
208 /*------------------------------------------------------------------*/
209 /* copyIlist - copy initializer list */
210 /*------------------------------------------------------------------*/
212 copyIlist (initList * src)
214 initList *dest = NULL;
222 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
225 dest = newiList (INIT_NODE, copyAst (src->init.node));
230 dest->next = copyIlist (src->next);
235 /*------------------------------------------------------------------*/
236 /* list2int - converts the first element of the list to value */
237 /*------------------------------------------------------------------*/
239 list2int (initList * val)
243 if (i->type == INIT_DEEP)
244 return list2int (val->init.deep);
246 return floatFromVal (constExprValue (val->init.node, TRUE));
249 /*------------------------------------------------------------------*/
250 /* list2val - converts the first element of the list to value */
251 /*------------------------------------------------------------------*/
253 list2val (initList * val)
258 if (val->type == INIT_DEEP)
259 return list2val (val->init.deep);
261 return constExprValue (val->init.node, TRUE);
264 /*------------------------------------------------------------------*/
265 /* list2expr - returns the first expression in the initializer list */
266 /*------------------------------------------------------------------*/
268 list2expr (initList * ilist)
272 if (ilist->type == INIT_DEEP)
273 return list2expr (ilist->init.deep);
274 return ilist->init.node;
277 /*------------------------------------------------------------------*/
278 /* resolveIvalSym - resolve symbols in initial values */
279 /*------------------------------------------------------------------*/
281 resolveIvalSym (initList * ilist, sym_link * type)
283 int is_ptr = IS_PTR (type);
284 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
288 if (ilist->type == INIT_NODE)
290 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
291 is_ptr ? RESULT_TYPE_INT : resultType);
293 else if (ilist->type == INIT_DEEP)
295 resolveIvalSym (ilist->init.deep, type);
302 /*------------------------------------------------------------------*/
303 /* symbolVal - creates a value for a symbol */
304 /*------------------------------------------------------------------*/
306 symbolVal (symbol * sym)
318 val->type = sym->type;
319 val->etype = getSpec (val->type);
324 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
328 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
334 /*--------------------------------------------------------------------*/
335 /* cheapestVal - try to reduce 'signed int' to 'char' */
336 /*--------------------------------------------------------------------*/
338 cheapestVal (value *val)
340 /* only int can be reduced */
341 if (!IS_INT(val->type))
344 /* long must not be changed */
345 if (SPEC_LONG(val->type))
348 /* unsigned must not be changed */
349 if (SPEC_USIGN(val->type))
352 /* the only possible reduction is from signed int to (un)signed char,
353 because it's automatically promoted back to signed int.
355 a reduction from unsigned int to unsigned char is a bug,
356 because an _unsigned_ char is promoted to _signed_ int! */
357 if (SPEC_CVAL(val->type).v_int < -128 ||
358 SPEC_CVAL(val->type).v_int > 255)
360 /* not in the range of (un)signed char */
364 SPEC_NOUN(val->type) = V_CHAR;
366 /* 'unsigned char' promotes to 'signed int', so that we can
367 reduce it the other way */
368 if (SPEC_CVAL(val->type).v_int >= 0)
370 SPEC_USIGN(val->type) = 1;
375 /*--------------------------------------------------------------------*/
376 /* checkConstantRange - check if constant fits in numeric range of */
377 /* var type in comparisons and assignments */
378 /*--------------------------------------------------------------------*/
380 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
386 litVal = floatFromVal (valFromType (lit));
387 varBits = bitsForType (var);
394 return CCR_ALWAYS_FALSE;
396 return CCR_ALWAYS_TRUE;
398 /* special: assignment */
404 if (getenv ("SDCC_VERY_PEDANTIC"))
406 if (SPEC_USIGN (var))
408 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
417 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
418 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
428 /* ignore signedness, e.g. allow everything
429 from -127...+255 for (unsigned) char */
430 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
431 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
440 if (exchangeLeftRight)
445 case '>': op = '<'; break;
446 case GE_OP: op = LE_OP; break;
447 case '<': op = '>'; break;
448 case LE_OP: op = GE_OP; break;
449 default: return CCR_ALWAYS_FALSE;
452 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
454 if (SPEC_USIGN (reType))
456 /* unsigned operation */
457 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
458 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
460 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
462 /* both operands are unsigned, this is easy */
464 maxValP = 0xffffffffu >> (32 - varBits);
465 /* there's only range, just copy it to 2nd set */
469 else if (SPEC_USIGN (var))
471 /* lit is casted from signed to unsigned, e.g.:
477 maxValP = 0xffffffffu >> (32 - varBits);
478 /* there's only one range, just copy it to 2nd set */
482 /* it's an unsigned operation */
483 if ( IS_CHAR (reType)
486 /* make signed literal unsigned and
487 limit no of bits to size of return type */
488 litVal = (TYPE_TARGET_ULONG) double2ul (litVal) & opBitsMask;
491 else /* SPEC_USIGN (lit) */
493 /* var is casted from signed to unsigned, e.g.:
498 The possible values after casting var
499 split up in two, nonconsecutive ranges:
501 minValP = 0; positive range: 0...127
503 minValM = 0xff80; negative range: -128...-1
509 maxValP = 0x7fffffffu >> (32 - varBits);
512 minValM = 0xffffffff << (varBits - 1);
513 maxValM = 0xffffffffu; /* -1 */
514 /* limit no of bits to size of return type */
515 minValM &= opBitsMask;
516 maxValM &= opBitsMask;
521 case EQ_OP: /* var == lit */
522 if ( litVal <= maxValP
523 && litVal >= minValP) /* 0 */
525 if ( litVal <= maxValM
526 && litVal >= minValM)
528 return CCR_ALWAYS_FALSE;
529 case NE_OP: /* var != lit */
530 if ( litVal <= maxValP
531 && litVal >= minValP) /* 0 */
533 if ( litVal <= maxValM
534 && litVal >= minValM)
536 return CCR_ALWAYS_TRUE;
537 case '>': /* var > lit */
538 if (litVal >= maxValM)
539 return CCR_ALWAYS_FALSE;
540 if (litVal < minValP) /* 0 */
541 return CCR_ALWAYS_TRUE;
543 case GE_OP: /* var >= lit */
544 if (litVal > maxValM)
545 return CCR_ALWAYS_FALSE;
546 if (litVal <= minValP) /* 0 */
547 return CCR_ALWAYS_TRUE;
549 case '<': /* var < lit */
550 if (litVal > maxValM)
551 return CCR_ALWAYS_TRUE;
552 if (litVal <= minValP) /* 0 */
553 return CCR_ALWAYS_FALSE;
555 case LE_OP: /* var <= lit */
556 if (litVal >= maxValM)
557 return CCR_ALWAYS_TRUE;
558 if (litVal < minValP) /* 0 */
559 return CCR_ALWAYS_FALSE;
562 return CCR_ALWAYS_FALSE;
567 /* signed operation */
568 TYPE_TARGET_LONG minVal, maxVal;
570 if (SPEC_USIGN (var))
572 /* unsigned var, but signed operation. This happens
573 when var is promoted to signed int.
574 Set actual min/max values of var. */
576 maxVal = 0xffffffff >> (32 - varBits);
581 minVal = 0xffffffff << (varBits - 1);
582 maxVal = 0x7fffffff >> (32 - varBits);
587 case EQ_OP: /* var == lit */
590 return CCR_ALWAYS_FALSE;
592 case NE_OP: /* var != lit */
595 return CCR_ALWAYS_TRUE;
597 case '>': /* var > lit */
598 if (litVal >= maxVal)
599 return CCR_ALWAYS_FALSE;
601 return CCR_ALWAYS_TRUE;
603 case GE_OP: /* var >= lit */
605 return CCR_ALWAYS_FALSE;
606 if (litVal <= minVal)
607 return CCR_ALWAYS_TRUE;
609 case '<': /* var < lit */
611 return CCR_ALWAYS_TRUE;
612 if (litVal <= minVal)
613 return CCR_ALWAYS_FALSE;
615 case LE_OP: /* var <= lit */
616 if (litVal >= maxVal)
617 return CCR_ALWAYS_TRUE;
619 return CCR_ALWAYS_FALSE;
622 return CCR_ALWAYS_FALSE;
627 /*-----------------------------------------------------------------*/
628 /* valueFromLit - creates a value from a literal */
629 /*-----------------------------------------------------------------*/
631 valueFromLit (double lit)
635 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
637 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
638 return constVal (buffer);
641 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
642 return constFloatVal (buffer);
645 /*-----------------------------------------------------------------*/
646 /* constFloatVal - converts a FLOAT constant to value */
647 /*-----------------------------------------------------------------*/
649 constFloatVal (const char *s)
651 value *val = newValue ();
655 sval = strtod(s, &p);
658 werror (E_INVALID_FLOAT_CONST, s);
659 return constCharVal (0);
662 val->type = val->etype = newLink (SPECIFIER);
663 SPEC_NOUN (val->type) = V_FLOAT;
664 SPEC_SCLS (val->type) = S_LITERAL;
665 SPEC_CVAL (val->type).v_float = sval;
670 /*-----------------------------------------------------------------*/
671 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
672 /*-----------------------------------------------------------------*/
674 constFixed16x16Val (const char *s)
676 value *val = newValue ();
680 sval = strtod(s, &p);
683 werror (E_INVALID_FLOAT_CONST, s);
684 return constCharVal (0);
687 val->type = val->etype = newLink (SPECIFIER);
688 SPEC_NOUN (val->type) = V_FLOAT;
689 SPEC_SCLS (val->type) = S_LITERAL;
690 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
695 /*-----------------------------------------------------------------*/
696 /* constVal - converts an INTEGER constant into a cheapest value */
697 /*-----------------------------------------------------------------*/
698 value *constVal (const char *s)
701 bool hex = FALSE, octal = FALSE;
705 val = newValue (); /* alloc space for value */
707 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
708 SPEC_SCLS (val->type) = S_LITERAL;
709 /* let's start with a signed char */
710 SPEC_NOUN (val->type) = V_CHAR;
711 SPEC_USIGN (val->type) = 0;
715 if (s[1] == 'x' || s[1] == 'X')
717 else if (isdigit(s[1]))
724 dval = strtoul (s, &p, 0);
728 werror (W_INVALID_INT_CONST, s, dval);
733 dval = strtod(s, &p);
736 /* Setup the flags first */
737 /* set the unsigned flag if 'uU' is found */
738 if (strchr (p, 'u') || strchr (p, 'U'))
740 SPEC_USIGN (val->type) = 1;
743 /* set the b_long flag if 'lL' is found */
744 if (strchr (p, 'l') || strchr (p, 'L'))
746 SPEC_NOUN (val->type) = V_INT;
747 SPEC_LONG (val->type) = 1;
752 { /* "-28u" will still be signed and negative */
754 { /* check if we have to promote to int */
755 SPEC_NOUN (val->type) = V_INT;
758 { /* check if we have to promote to long int */
759 SPEC_LONG (val->type) = 1;
764 if (dval > 0xff || /* check if we have to promote to int */
765 SPEC_USIGN (val->type))
766 { /* if it's unsigned, we can't use unsigned
767 char. After an integral promotion it will
768 be a signed int; this certainly isn't what
769 the programer wants */
770 SPEC_NOUN (val->type) = V_INT;
773 { /* store char's always as unsigned; this helps other optimizations */
774 SPEC_USIGN (val->type) = 1;
776 if (dval > 0xffff && SPEC_USIGN (val->type))
777 { /* check if we have to promote to long */
778 SPEC_LONG (val->type) = 1;
780 else if (dval > 0x7fff && !SPEC_USIGN (val->type))
781 { /* check if we have to promote to long int */
782 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
785 SPEC_USIGN (val->type) = 1;
789 SPEC_LONG (val->type) = 1;
790 if (dval > 0x7fffffff)
792 SPEC_USIGN (val->type) = 1;
799 /* check for out of range */
800 if (dval < -2147483648.0)
802 dval = -2147483648.0;
803 werror (W_INVALID_INT_CONST, s, dval);
805 if (dval > 2147483647.0 && !SPEC_USIGN (val->type))
808 werror (W_INVALID_INT_CONST, s, dval);
810 if (dval > 4294967295.0)
813 werror (W_INVALID_INT_CONST, s, dval);
816 if (SPEC_LONG (val->type))
818 if (SPEC_USIGN (val->type))
820 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
824 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
829 if (SPEC_USIGN (val->type))
831 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
835 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
842 value *constCharVal (unsigned char v)
844 value *val = newValue (); /* alloc space for value */
846 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
847 SPEC_SCLS (val->type) = S_LITERAL;
848 /* let's start with a signed char */
849 SPEC_NOUN (val->type) = V_CHAR;
850 SPEC_USIGN (val->type) = 1;
851 SPEC_CVAL (val->type).v_uint = v;
856 /*------------------------------------------------------------------*/
857 /* strVal - converts a string constant to a value */
858 /*------------------------------------------------------------------*/
860 strVal (const char *s)
864 val = newValue (); /* get a new one */
866 /* get a declarator */
867 val->type = newLink (DECLARATOR);
868 DCL_TYPE (val->type) = ARRAY;
869 val->type->next = val->etype = newLink (SPECIFIER);
870 SPEC_NOUN (val->etype) = V_CHAR;
871 SPEC_SCLS (val->etype) = S_LITERAL;
873 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
874 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
880 /*------------------------------------------------------------------*/
881 /* reverseValWithType - reverses value chain with type & etype */
882 /*------------------------------------------------------------------*/
884 reverseValWithType (value * val)
892 /* save the type * etype chains */
896 /* set the current one 2b null */
897 val->type = val->etype = NULL;
898 val = reverseVal (val);
900 /* restore type & etype */
907 /*------------------------------------------------------------------*/
908 /* reverseVal - reverses the values for a value chain */
909 /*------------------------------------------------------------------*/
911 reverseVal (value * val)
913 value *prev, *curr, *next;
928 val->next = (void *) NULL;
932 /*------------------------------------------------------------------*/
933 /* copyValueChain - will copy a chain of values */
934 /*------------------------------------------------------------------*/
936 copyValueChain (value * src)
943 dest = copyValue (src);
944 dest->next = copyValueChain (src->next);
949 /*------------------------------------------------------------------*/
950 /* copyValue - copies contents of a value to a fresh one */
951 /*------------------------------------------------------------------*/
953 copyValue (value * src)
958 dest->sym = copySymbol (src->sym);
959 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
960 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
961 dest->etype = (src->type ? getSpec (dest->type) : NULL);
966 /*------------------------------------------------------------------*/
967 /* charVal - converts a character constant to a value */
968 /*------------------------------------------------------------------*/
970 charVal (const char *s)
972 /* get rid of quotation */
973 /* if \ then special processing */
976 switch (*++s) /* go beyond the backslash */
979 return constCharVal ('\n');
981 return constCharVal ('\t');
983 return constCharVal ('\v');
985 return constCharVal ('\b');
987 return constCharVal ('\r');
989 return constCharVal ('\f');
991 return constCharVal ('\a');
993 return constCharVal ('\\');
995 return constCharVal ('\?');
997 return constCharVal ('\'');
999 return constCharVal ('\"');
1009 return constCharVal (octalEscape (&s));
1012 return constCharVal (hexEscape (&s));
1015 return constCharVal (*s);
1018 else /* not a backslash */
1019 return constCharVal (*s);
1022 /*------------------------------------------------------------------*/
1023 /* valFromType - creates a value from type given */
1024 /*------------------------------------------------------------------*/
1026 valFromType (sym_link * type)
1028 value *val = newValue ();
1029 val->type = copyLinkChain (type);
1030 val->etype = getSpec (val->type);
1034 /*------------------------------------------------------------------*/
1035 /* floatFromVal - value to double float conversion */
1036 /*------------------------------------------------------------------*/
1038 floatFromVal (value * val)
1043 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1045 werror (E_CONST_EXPECTED, val->name);
1049 /* if it is not a specifier then we can assume that */
1050 /* it will be an unsigned long */
1051 if (!IS_SPEC (val->type))
1052 return SPEC_CVAL (val->etype).v_ulong;
1054 if (SPEC_NOUN (val->etype) == V_FLOAT)
1055 return SPEC_CVAL (val->etype).v_float;
1057 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1058 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1060 if (SPEC_LONG (val->etype))
1062 if (SPEC_USIGN (val->etype))
1063 return SPEC_CVAL (val->etype).v_ulong;
1065 return SPEC_CVAL (val->etype).v_long;
1068 if (SPEC_NOUN (val->etype) == V_INT)
1070 if (SPEC_USIGN (val->etype))
1071 return SPEC_CVAL (val->etype).v_uint;
1073 return SPEC_CVAL (val->etype).v_int;
1076 if (SPEC_NOUN (val->etype) == V_CHAR)
1078 if (SPEC_USIGN (val->etype))
1079 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1081 return (signed char) SPEC_CVAL (val->etype).v_int;
1084 if (IS_BITVAR(val->etype))
1085 return SPEC_CVAL (val->etype).v_uint;
1087 if (SPEC_NOUN (val->etype) == V_VOID)
1088 return SPEC_CVAL (val->etype).v_ulong;
1091 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1095 /*------------------------------------------------------------------*/
1096 /* ulFromVal - value to unsigned long conversion */
1097 /*------------------------------------------------------------------*/
1099 ulFromVal (value * val)
1104 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1106 werror (E_CONST_EXPECTED, val->name);
1110 /* if it is not a specifier then we can assume that */
1111 /* it will be an unsigned long */
1112 if (!IS_SPEC (val->type))
1113 return SPEC_CVAL (val->etype).v_ulong;
1115 if (SPEC_NOUN (val->etype) == V_FLOAT)
1116 return double2ul (SPEC_CVAL (val->etype).v_float);
1118 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1119 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1121 if (SPEC_LONG (val->etype))
1123 if (SPEC_USIGN (val->etype))
1124 return SPEC_CVAL (val->etype).v_ulong;
1126 return SPEC_CVAL (val->etype).v_long;
1129 if (SPEC_NOUN (val->etype) == V_INT)
1131 if (SPEC_USIGN (val->etype))
1132 return SPEC_CVAL (val->etype).v_uint;
1134 return SPEC_CVAL (val->etype).v_int;
1137 if (SPEC_NOUN (val->etype) == V_CHAR)
1139 if (SPEC_USIGN (val->etype))
1140 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1142 return (signed char) SPEC_CVAL (val->etype).v_int;
1145 if (IS_BITVAR(val->etype))
1146 return SPEC_CVAL (val->etype).v_uint;
1148 if (SPEC_NOUN (val->etype) == V_VOID)
1149 return SPEC_CVAL (val->etype).v_ulong;
1152 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1156 /*-----------------------------------------------------------------*/
1157 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1158 /*-----------------------------------------------------------------*/
1159 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1162 /* This version is incorrect negative values. */
1163 double tmp=0, exp=2;
1165 tmp = (value & 0xffff0000) >> 16;
1169 if(value & 0x8000)tmp += 1/exp;
1176 return ((double)(value * 1.0) / (double)(1UL << 16));
1180 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1183 /* This version is incorrect negative values. */
1184 unsigned int tmp=0, pos=16;
1185 TYPE_TARGET_ULONG res;
1187 tmp = floor( value );
1194 if(value >= 1.0)tmp |= (1 << pos);
1195 value -= floor( value );
1202 return double2ul (value * (double)(1UL << 16));
1206 /*------------------------------------------------------------------*/
1207 /* valUnaryPM - does the unary +/- operation on a constant */
1208 /*------------------------------------------------------------------*/
1210 valUnaryPM (value * val)
1212 /* depending on type */
1213 if (SPEC_NOUN (val->etype) == V_FLOAT)
1214 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1215 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1216 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) -((long) SPEC_CVAL (val->etype).v_fixed16x16);
1219 if (SPEC_LONG (val->etype))
1221 if (SPEC_USIGN (val->etype))
1222 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1224 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1228 if (SPEC_USIGN (val->etype))
1229 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1231 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1233 if (SPEC_NOUN(val->etype) == V_CHAR)
1235 /* promote to 'signed int', cheapestVal() might reduce it again */
1236 SPEC_USIGN(val->etype) = 0;
1237 SPEC_NOUN(val->etype) = V_INT;
1239 return cheapestVal (val);
1245 /*------------------------------------------------------------------*/
1246 /* valueComplement - complements a constant */
1247 /*------------------------------------------------------------------*/
1249 valComplement (value * val)
1251 /* depending on type */
1252 if (SPEC_LONG (val->etype))
1254 if (SPEC_USIGN (val->etype))
1255 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1257 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1261 if (SPEC_USIGN (val->etype))
1262 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1264 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1266 if (SPEC_NOUN(val->etype) == V_CHAR)
1268 /* promote to 'signed int', cheapestVal() might reduce it again */
1269 SPEC_USIGN(val->etype) = 0;
1270 SPEC_NOUN(val->etype) = V_INT;
1272 return cheapestVal (val);
1277 /*------------------------------------------------------------------*/
1278 /* valueNot - complements a constant */
1279 /*------------------------------------------------------------------*/
1281 valNot (value * val)
1283 /* depending on type */
1284 if (SPEC_LONG (val->etype))
1286 if (SPEC_USIGN (val->etype))
1287 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1289 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1293 if (SPEC_USIGN (val->etype))
1294 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1296 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1299 /* ANSI: result type is int, value is 0 or 1 */
1300 /* sdcc will hold this in an 'unsigned char' */
1301 SPEC_USIGN(val->etype) = 1;
1302 SPEC_LONG (val->etype) = 0;
1303 SPEC_NOUN(val->etype) = V_CHAR;
1307 /*------------------------------------------------------------------*/
1308 /* valMult - multiply constants */
1309 /*------------------------------------------------------------------*/
1311 valMult (value * lval, value * rval)
1315 /* create a new value */
1317 val->type = val->etype = computeType (lval->etype,
1321 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1323 if (IS_FLOAT (val->type))
1324 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1326 if (IS_FIXED16X16 (val->type))
1327 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1328 /* signed and unsigned mul are the same, as long as the precision of the
1329 result isn't bigger than the precision of the operands. */
1330 else if (SPEC_LONG (val->type))
1331 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1332 (TYPE_TARGET_ULONG) ulFromVal (rval);
1333 else if (SPEC_USIGN (val->type)) /* unsigned int */
1335 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1336 (TYPE_TARGET_UINT) ulFromVal (rval);
1338 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1339 if (ul != (TYPE_TARGET_UINT) ul)
1342 else /* signed int */
1344 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1345 (TYPE_TARGET_INT) floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1348 if (l != (TYPE_TARGET_INT) l)
1351 return cheapestVal (val);
1354 /*------------------------------------------------------------------*/
1355 /* valDiv - Divide constants */
1356 /*------------------------------------------------------------------*/
1358 valDiv (value * lval, value * rval)
1362 if (floatFromVal (rval) == 0)
1364 werror (E_DIVIDE_BY_ZERO);
1368 /* create a new value */
1370 val->type = val->etype = computeType (lval->etype,
1374 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1376 if (IS_FLOAT (val->type))
1377 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1378 else if (IS_FIXED16X16 (val->type))
1379 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1380 else if (SPEC_LONG (val->type))
1382 if (SPEC_USIGN (val->type))
1383 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1384 (TYPE_TARGET_ULONG) ulFromVal (rval);
1386 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1387 (TYPE_TARGET_LONG) ulFromVal (rval);
1391 if (SPEC_USIGN (val->type))
1392 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1393 (TYPE_TARGET_UINT) ulFromVal (rval);
1395 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1396 (TYPE_TARGET_INT) ulFromVal (rval);
1398 return cheapestVal (val);
1401 /*------------------------------------------------------------------*/
1402 /* valMod - Modulus constants */
1403 /*------------------------------------------------------------------*/
1405 valMod (value * lval, value * rval)
1409 /* create a new value */
1411 val->type = val->etype = computeType (lval->etype,
1415 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1417 if (SPEC_LONG (val->type))
1419 if (SPEC_USIGN (val->type))
1420 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1421 (TYPE_TARGET_ULONG) ulFromVal (rval);
1423 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1424 (TYPE_TARGET_LONG) ulFromVal (rval);
1428 if (SPEC_USIGN (val->type))
1429 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1430 (TYPE_TARGET_UINT) ulFromVal (rval);
1432 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1433 (TYPE_TARGET_INT) ulFromVal (rval);
1435 return cheapestVal (val);
1438 /*------------------------------------------------------------------*/
1439 /* valPlus - Addition constants */
1440 /*------------------------------------------------------------------*/
1442 valPlus (value * lval, value * rval)
1446 /* create a new value */
1448 val->type = val->etype = computeType (lval->etype,
1452 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1454 if (IS_FLOAT (val->type))
1455 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1457 if (IS_FIXED16X16 (val->type))
1458 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1459 else if (SPEC_LONG (val->type))
1461 if (SPEC_USIGN (val->type))
1462 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1463 (TYPE_TARGET_ULONG) ulFromVal (rval);
1465 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1466 (TYPE_TARGET_LONG) ulFromVal (rval);
1470 if (SPEC_USIGN (val->type))
1471 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1472 (TYPE_TARGET_UINT) ulFromVal (rval);
1474 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1475 (TYPE_TARGET_INT) ulFromVal (rval);
1477 return cheapestVal (val);
1480 /*------------------------------------------------------------------*/
1481 /* valMinus - Addition constants */
1482 /*------------------------------------------------------------------*/
1484 valMinus (value * lval, value * rval)
1488 /* create a new value */
1490 val->type = val->etype = computeType (lval->etype,
1494 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1496 if (IS_FLOAT (val->type))
1497 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1499 if (IS_FIXED16X16 (val->type))
1500 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1501 else if (SPEC_LONG (val->type))
1503 if (SPEC_USIGN (val->type))
1504 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1505 (TYPE_TARGET_ULONG) ulFromVal (rval);
1507 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1508 (TYPE_TARGET_LONG) ulFromVal (rval);
1512 if (SPEC_USIGN (val->type))
1513 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1514 (TYPE_TARGET_UINT) ulFromVal (rval);
1516 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1517 (TYPE_TARGET_INT) ulFromVal (rval);
1519 return cheapestVal (val);
1522 /*------------------------------------------------------------------*/
1523 /* valShift - Shift left or right */
1524 /*------------------------------------------------------------------*/
1526 valShift (value * lval, value * rval, int lr)
1530 /* create a new value */
1532 val->type = val->etype = computeType (lval->etype,
1536 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1538 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1541 /* right shift and unsigned */
1542 (!lr && SPEC_USIGN (rval->type))))
1544 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1547 if (SPEC_LONG (val->type))
1549 if (SPEC_USIGN (val->type))
1551 SPEC_CVAL (val->type).v_ulong = lr ?
1552 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1553 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1557 SPEC_CVAL (val->type).v_long = lr ?
1558 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1559 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1564 if (SPEC_USIGN (val->type))
1566 SPEC_CVAL (val->type).v_uint = lr ?
1567 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1568 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1572 SPEC_CVAL (val->type).v_int = lr ?
1573 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1574 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1577 return cheapestVal (val);
1580 /*------------------------------------------------------------------*/
1581 /* valCompare- Compares two literal */
1582 /*------------------------------------------------------------------*/
1584 valCompare (value * lval, value * rval, int ctype)
1588 /* create a new value */
1590 val->type = val->etype = newCharLink ();
1591 val->type->class = SPECIFIER;
1592 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1593 SPEC_USIGN (val->type) = 1;
1594 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1599 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1603 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1607 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1611 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1615 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1616 SPEC_NOUN(rval->type) == V_FLOAT)
1618 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1621 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1622 SPEC_NOUN(rval->type) == V_FIXED16X16)
1624 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1628 /* integrals: ignore signedness */
1629 TYPE_TARGET_ULONG l, r;
1631 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1632 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1633 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1634 neccessary to strip them to 16 bit.
1635 Literals are reduced to their cheapest type, therefore left and
1636 right might have different types. It's neccessary to find a
1637 common type: int (used for char too) or long */
1638 if (!IS_LONG (lval->etype) &&
1639 !IS_LONG (rval->etype))
1641 r = (TYPE_TARGET_UINT) r;
1642 l = (TYPE_TARGET_UINT) l;
1644 SPEC_CVAL (val->type).v_int = l == r;
1648 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1649 SPEC_NOUN(rval->type) == V_FLOAT)
1651 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1654 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1655 SPEC_NOUN(rval->type) == V_FIXED16X16)
1657 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1661 /* integrals: ignore signedness */
1662 TYPE_TARGET_ULONG l, r;
1664 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1665 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1666 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1667 neccessary to strip them to 16 bit.
1668 Literals are reduced to their cheapest type, therefore left and
1669 right might have different types. It's neccessary to find a
1670 common type: int (used for char too) or long */
1671 if (!IS_LONG (lval->etype) &&
1672 !IS_LONG (rval->etype))
1674 r = (TYPE_TARGET_UINT) r;
1675 l = (TYPE_TARGET_UINT) l;
1677 SPEC_CVAL (val->type).v_int = l != r;
1686 /*------------------------------------------------------------------*/
1687 /* valBitwise - Bitwise operation */
1688 /*------------------------------------------------------------------*/
1690 valBitwise (value * lval, value * rval, int op)
1694 /* create a new value */
1696 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1697 val->etype = getSpec (val->type);
1698 SPEC_SCLS (val->etype) = S_LITERAL;
1703 if (SPEC_LONG (val->type))
1705 if (SPEC_USIGN (val->type))
1706 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1707 (TYPE_TARGET_ULONG) ulFromVal (rval);
1709 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1710 (TYPE_TARGET_LONG) ulFromVal (rval);
1714 if (SPEC_USIGN (val->type))
1715 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1716 (TYPE_TARGET_UINT) ulFromVal (rval);
1718 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1719 (TYPE_TARGET_INT) ulFromVal (rval);
1724 if (SPEC_LONG (val->type))
1726 if (SPEC_USIGN (val->type))
1727 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1728 (TYPE_TARGET_ULONG) ulFromVal (rval);
1730 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1731 (TYPE_TARGET_LONG) ulFromVal (rval);
1735 if (SPEC_USIGN (val->type))
1736 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1737 (TYPE_TARGET_UINT) ulFromVal (rval);
1739 SPEC_CVAL (val->type).v_int =
1740 (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1746 if (SPEC_LONG (val->type))
1748 if (SPEC_USIGN (val->type))
1749 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1750 (TYPE_TARGET_ULONG) ulFromVal (rval);
1752 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1753 (TYPE_TARGET_LONG) ulFromVal (rval);
1757 if (SPEC_USIGN (val->type))
1758 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1759 (TYPE_TARGET_UINT) ulFromVal (rval);
1761 SPEC_CVAL (val->type).v_int =
1762 (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1767 return cheapestVal(val);
1770 /*------------------------------------------------------------------*/
1771 /* valAndOr - Generates code for and / or operation */
1772 /*------------------------------------------------------------------*/
1774 valLogicAndOr (value * lval, value * rval, int op)
1778 /* create a new value */
1780 val->type = val->etype = newCharLink ();
1781 val->type->class = SPECIFIER;
1782 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1783 SPEC_USIGN (val->type) = 1;
1788 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1792 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1800 /*------------------------------------------------------------------*/
1801 /* valCastLiteral - casts a literal value to another type */
1802 /*------------------------------------------------------------------*/
1804 valCastLiteral (sym_link * dtype, double fval)
1807 unsigned long l = double2ul (fval);
1814 val->etype = getSpec (val->type = copyLinkChain (dtype));
1817 val->etype = val->type = newLink (SPECIFIER);
1818 SPEC_NOUN (val->etype) = V_VOID;
1820 SPEC_SCLS (val->etype) = S_LITERAL;
1822 /* if it is not a specifier then we can assume that */
1823 /* it will be an unsigned long */
1824 if (!IS_SPEC (val->type))
1826 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1830 switch (SPEC_NOUN (val->etype))
1833 SPEC_CVAL (val->etype).v_float = fval;
1837 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1842 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1846 l &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
1847 if (SPEC_USIGN (val->etype))
1848 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1850 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1854 if (SPEC_USIGN (val->etype))
1855 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1857 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1861 if (SPEC_LONG (val->etype))
1863 if (SPEC_USIGN (val->etype))
1864 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1866 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1870 if (SPEC_USIGN (val->etype))
1871 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1873 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1880 /*------------------------------------------------------------------*/
1881 /* getNelements - determines # of elements from init list */
1882 /*------------------------------------------------------------------*/
1884 getNelements (sym_link * type, initList * ilist)
1891 if (ilist->type == INIT_DEEP)
1892 ilist = ilist->init.deep;
1894 /* if type is a character array and there is only one
1895 (string) initialiser then get the length of the string */
1896 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1898 ast *iast = ilist->init.node;
1899 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1902 werror (E_CONST_EXPECTED);
1906 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1907 /* yep, it's a string */
1909 return DCL_ELEM (v->type);
1917 ilist = ilist->next;
1922 /*-----------------------------------------------------------------*/
1923 /* valForArray - returns a value with name of array index */
1924 /*-----------------------------------------------------------------*/
1926 valForArray (ast * arrExpr)
1928 value *val, *lval = NULL;
1930 int size = getSize (arrExpr->left->ftype->next);
1931 /* if the right or left is an array
1933 if (IS_AST_OP (arrExpr->left))
1935 if (arrExpr->left->opval.op == '[')
1936 lval = valForArray (arrExpr->left);
1937 else if (arrExpr->left->opval.op == '.')
1938 lval = valForStructElem (arrExpr->left->left,
1939 arrExpr->left->right);
1940 else if (arrExpr->left->opval.op == PTR_OP &&
1941 IS_ADDRESS_OF_OP (arrExpr->left->left))
1942 lval = valForStructElem (arrExpr->left->left->left,
1943 arrExpr->left->right);
1948 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1951 if (!IS_AST_LIT_VALUE (arrExpr->right))
1957 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1961 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1964 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1965 AST_ULONG_VALUE (arrExpr->right) * size);
1967 val->type = newLink (DECLARATOR);
1968 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1969 DCL_TYPE (val->type) = CPOINTER;
1970 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1971 DCL_TYPE (val->type) = FPOINTER;
1972 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1973 DCL_TYPE (val->type) = PPOINTER;
1974 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1975 DCL_TYPE (val->type) = IPOINTER;
1976 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1977 DCL_TYPE (val->type) = EEPPOINTER;
1979 DCL_TYPE (val->type) = POINTER;
1980 val->type->next = arrExpr->left->ftype->next;
1981 val->etype = getSpec (val->type);
1985 /*-----------------------------------------------------------------*/
1986 /* valForStructElem - returns value with name of struct element */
1987 /*-----------------------------------------------------------------*/
1989 valForStructElem (ast * structT, ast * elemT)
1991 value *val, *lval = NULL;
1995 /* left could be furthur derefed */
1996 if (IS_AST_OP (structT))
1998 if (structT->opval.op == '[')
1999 lval = valForArray (structT);
2000 else if (structT->opval.op == '.')
2001 lval = valForStructElem (structT->left, structT->right);
2002 else if (structT->opval.op == PTR_OP &&
2003 IS_ADDRESS_OF_OP (structT->left))
2004 lval = valForStructElem (structT->left->left,
2010 if (!IS_AST_SYM_VALUE (elemT))
2013 if (!IS_STRUCT (structT->etype))
2016 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2017 AST_SYMBOL (elemT))) == NULL)
2025 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2029 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2032 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2035 val->type = newLink (DECLARATOR);
2036 if (SPEC_SCLS (structT->etype) == S_CODE)
2037 DCL_TYPE (val->type) = CPOINTER;
2038 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2039 DCL_TYPE (val->type) = FPOINTER;
2040 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2041 DCL_TYPE (val->type) = PPOINTER;
2042 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2043 DCL_TYPE (val->type) = IPOINTER;
2044 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2045 DCL_TYPE (val->type) = EEPPOINTER;
2047 DCL_TYPE (val->type) = POINTER;
2048 val->type->next = sym->type;
2049 val->etype = getSpec (val->type);
2053 /*-----------------------------------------------------------------*/
2054 /* valForCastAggr - will return value for a cast of an aggregate */
2055 /* plus minus a constant */
2056 /*-----------------------------------------------------------------*/
2058 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2062 if (!IS_AST_SYM_VALUE (aexpr))
2064 if (!IS_AST_LIT_VALUE (cnst))
2069 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2070 AST_SYMBOL (aexpr)->rname, op,
2071 getSize (type->next) * AST_ULONG_VALUE (cnst));
2074 val->etype = getSpec (val->type);
2078 /*-----------------------------------------------------------------*/
2079 /* valForCastAggr - will return value for a cast of an aggregate */
2080 /* with no constant */
2081 /*-----------------------------------------------------------------*/
2083 valForCastArr (ast * aexpr, sym_link * type)
2087 if (!IS_AST_SYM_VALUE (aexpr))
2092 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2093 AST_SYMBOL (aexpr)->rname);
2096 val->etype = getSpec (val->type);