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)
703 bool is_integral = 0;
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;
716 if (s[1] == 'b' || s[1] == 'B')
717 dval = strtoul (s + 2, &p, 2);
719 dval = strtoul (s, &p, 0);
723 dval = strtod (s, &p);
728 werror (W_INVALID_INT_CONST, s, dval);
731 /* Setup the flags first */
732 /* set the unsigned flag if 'uU' is found */
733 if (strchr (p, 'u') || strchr (p, 'U'))
735 SPEC_USIGN (val->type) = 1;
738 /* set the b_long flag if 'lL' is found */
739 if (strchr (p, 'l') || strchr (p, 'L'))
741 SPEC_NOUN (val->type) = V_INT;
742 SPEC_LONG (val->type) = 1;
747 { /* "-28u" will still be signed and negative */
749 { /* check if we have to promote to int */
750 SPEC_NOUN (val->type) = V_INT;
753 { /* check if we have to promote to long int */
754 SPEC_LONG (val->type) = 1;
759 if (dval > 0xff || /* check if we have to promote to int */
760 SPEC_USIGN (val->type))
761 { /* if it's unsigned, we can't use unsigned
762 char. After an integral promotion it will
763 be a signed int; this certainly isn't what
764 the programer wants */
765 SPEC_NOUN (val->type) = V_INT;
768 { /* store char's always as unsigned; this helps other optimizations */
769 SPEC_USIGN (val->type) = 1;
771 if (dval > 0xffff && SPEC_USIGN (val->type))
772 { /* check if we have to promote to long */
773 SPEC_LONG (val->type) = 1;
775 else if (dval > 0x7fff && !SPEC_USIGN (val->type))
776 { /* check if we have to promote to long int */
777 if (is_integral && /* integral (hex, octal and binary) constants may be stored in unsigned type */
780 SPEC_USIGN (val->type) = 1;
784 SPEC_LONG (val->type) = 1;
785 if (dval > 0x7fffffff)
787 SPEC_USIGN (val->type) = 1;
794 /* check for out of range */
795 if (dval < -2147483648.0)
797 dval = -2147483648.0;
798 werror (W_INVALID_INT_CONST, s, dval);
800 if (dval > 2147483647.0 && !SPEC_USIGN (val->type))
803 werror (W_INVALID_INT_CONST, s, dval);
805 if (dval > 4294967295.0)
808 werror (W_INVALID_INT_CONST, s, dval);
811 if (SPEC_LONG (val->type))
813 if (SPEC_USIGN (val->type))
815 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
819 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
824 if (SPEC_USIGN (val->type))
826 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
830 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
837 value *constCharVal (unsigned char v)
839 value *val = newValue (); /* alloc space for value */
841 val->type = val->etype = newLink (SPECIFIER); /* create the specifier */
842 SPEC_SCLS (val->type) = S_LITERAL;
843 /* let's start with a signed char */
844 SPEC_NOUN (val->type) = V_CHAR;
845 SPEC_USIGN (val->type) = 1;
846 SPEC_CVAL (val->type).v_uint = v;
851 /*------------------------------------------------------------------*/
852 /* strVal - converts a string constant to a value */
853 /*------------------------------------------------------------------*/
855 strVal (const char *s)
859 val = newValue (); /* get a new one */
861 /* get a declarator */
862 val->type = newLink (DECLARATOR);
863 DCL_TYPE (val->type) = ARRAY;
864 val->type->next = val->etype = newLink (SPECIFIER);
865 SPEC_NOUN (val->etype) = V_CHAR;
866 SPEC_SCLS (val->etype) = S_LITERAL;
868 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
869 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
875 /*------------------------------------------------------------------*/
876 /* reverseValWithType - reverses value chain with type & etype */
877 /*------------------------------------------------------------------*/
879 reverseValWithType (value * val)
887 /* save the type * etype chains */
891 /* set the current one 2b null */
892 val->type = val->etype = NULL;
893 val = reverseVal (val);
895 /* restore type & etype */
902 /*------------------------------------------------------------------*/
903 /* reverseVal - reverses the values for a value chain */
904 /*------------------------------------------------------------------*/
906 reverseVal (value * val)
908 value *prev, *curr, *next;
923 val->next = (void *) NULL;
927 /*------------------------------------------------------------------*/
928 /* copyValueChain - will copy a chain of values */
929 /*------------------------------------------------------------------*/
931 copyValueChain (value * src)
938 dest = copyValue (src);
939 dest->next = copyValueChain (src->next);
944 /*------------------------------------------------------------------*/
945 /* copyValue - copies contents of a value to a fresh one */
946 /*------------------------------------------------------------------*/
948 copyValue (value * src)
953 dest->sym = copySymbol (src->sym);
954 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
955 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
956 dest->etype = (src->type ? getSpec (dest->type) : NULL);
961 /*------------------------------------------------------------------*/
962 /* charVal - converts a character constant to a value */
963 /*------------------------------------------------------------------*/
965 charVal (const char *s)
967 /* get rid of quotation */
968 /* if \ then special processing */
971 switch (*++s) /* go beyond the backslash */
974 return constCharVal ('\n');
976 return constCharVal ('\t');
978 return constCharVal ('\v');
980 return constCharVal ('\b');
982 return constCharVal ('\r');
984 return constCharVal ('\f');
986 return constCharVal ('\a');
988 return constCharVal ('\\');
990 return constCharVal ('\?');
992 return constCharVal ('\'');
994 return constCharVal ('\"');
1004 return constCharVal (octalEscape (&s));
1007 return constCharVal (hexEscape (&s));
1010 return constCharVal (*s);
1013 else /* not a backslash */
1014 return constCharVal (*s);
1017 /*------------------------------------------------------------------*/
1018 /* valFromType - creates a value from type given */
1019 /*------------------------------------------------------------------*/
1021 valFromType (sym_link * type)
1023 value *val = newValue ();
1024 val->type = copyLinkChain (type);
1025 val->etype = getSpec (val->type);
1029 /*------------------------------------------------------------------*/
1030 /* floatFromVal - value to double float conversion */
1031 /*------------------------------------------------------------------*/
1033 floatFromVal (value * val)
1038 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1040 werror (E_CONST_EXPECTED, val->name);
1044 /* if it is not a specifier then we can assume that */
1045 /* it will be an unsigned long */
1046 if (!IS_SPEC (val->type))
1047 return SPEC_CVAL (val->etype).v_ulong;
1049 if (SPEC_NOUN (val->etype) == V_FLOAT)
1050 return SPEC_CVAL (val->etype).v_float;
1052 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1053 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1055 if (SPEC_LONG (val->etype))
1057 if (SPEC_USIGN (val->etype))
1058 return SPEC_CVAL (val->etype).v_ulong;
1060 return SPEC_CVAL (val->etype).v_long;
1063 if (SPEC_NOUN (val->etype) == V_INT)
1065 if (SPEC_USIGN (val->etype))
1066 return SPEC_CVAL (val->etype).v_uint;
1068 return SPEC_CVAL (val->etype).v_int;
1071 if (SPEC_NOUN (val->etype) == V_CHAR)
1073 if (SPEC_USIGN (val->etype))
1074 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1076 return (signed char) SPEC_CVAL (val->etype).v_int;
1079 if (IS_BITVAR(val->etype))
1080 return SPEC_CVAL (val->etype).v_uint;
1082 if (SPEC_NOUN (val->etype) == V_VOID)
1083 return SPEC_CVAL (val->etype).v_ulong;
1086 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1090 /*------------------------------------------------------------------*/
1091 /* ulFromVal - value to unsigned long conversion */
1092 /*------------------------------------------------------------------*/
1094 ulFromVal (value * val)
1099 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1101 werror (E_CONST_EXPECTED, val->name);
1105 /* if it is not a specifier then we can assume that */
1106 /* it will be an unsigned long */
1107 if (!IS_SPEC (val->type))
1108 return SPEC_CVAL (val->etype).v_ulong;
1110 if (SPEC_NOUN (val->etype) == V_FLOAT)
1111 return double2ul (SPEC_CVAL (val->etype).v_float);
1113 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1114 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1116 if (SPEC_LONG (val->etype))
1118 if (SPEC_USIGN (val->etype))
1119 return SPEC_CVAL (val->etype).v_ulong;
1121 return SPEC_CVAL (val->etype).v_long;
1124 if (SPEC_NOUN (val->etype) == V_INT)
1126 if (SPEC_USIGN (val->etype))
1127 return SPEC_CVAL (val->etype).v_uint;
1129 return SPEC_CVAL (val->etype).v_int;
1132 if (SPEC_NOUN (val->etype) == V_CHAR)
1134 if (SPEC_USIGN (val->etype))
1135 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1137 return (signed char) SPEC_CVAL (val->etype).v_int;
1140 if (IS_BITVAR(val->etype))
1141 return SPEC_CVAL (val->etype).v_uint;
1143 if (SPEC_NOUN (val->etype) == V_VOID)
1144 return SPEC_CVAL (val->etype).v_ulong;
1147 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1151 /*-----------------------------------------------------------------*/
1152 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1153 /*-----------------------------------------------------------------*/
1154 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1157 /* This version is incorrect negative values. */
1158 double tmp=0, exp=2;
1160 tmp = (value & 0xffff0000) >> 16;
1164 if(value & 0x8000)tmp += 1/exp;
1171 return ((double)(value * 1.0) / (double)(1UL << 16));
1175 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1178 /* This version is incorrect negative values. */
1179 unsigned int tmp=0, pos=16;
1180 TYPE_TARGET_ULONG res;
1182 tmp = floor( value );
1189 if(value >= 1.0)tmp |= (1 << pos);
1190 value -= floor( value );
1197 return double2ul (value * (double)(1UL << 16));
1201 /*------------------------------------------------------------------*/
1202 /* valUnaryPM - does the unary +/- operation on a constant */
1203 /*------------------------------------------------------------------*/
1205 valUnaryPM (value * val)
1207 /* depending on type */
1208 if (SPEC_NOUN (val->etype) == V_FLOAT)
1209 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1210 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1211 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) -((long) SPEC_CVAL (val->etype).v_fixed16x16);
1214 if (SPEC_LONG (val->etype))
1216 if (SPEC_USIGN (val->etype))
1217 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1219 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1223 if (SPEC_USIGN (val->etype))
1224 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1226 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1228 if (SPEC_NOUN(val->etype) == V_CHAR)
1230 /* promote to 'signed int', cheapestVal() might reduce it again */
1231 SPEC_USIGN(val->etype) = 0;
1232 SPEC_NOUN(val->etype) = V_INT;
1234 return cheapestVal (val);
1240 /*------------------------------------------------------------------*/
1241 /* valueComplement - complements a constant */
1242 /*------------------------------------------------------------------*/
1244 valComplement (value * val)
1246 /* depending on type */
1247 if (SPEC_LONG (val->etype))
1249 if (SPEC_USIGN (val->etype))
1250 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1252 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1256 if (SPEC_USIGN (val->etype))
1257 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1259 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1261 if (SPEC_NOUN(val->etype) == V_CHAR)
1263 /* promote to 'signed int', cheapestVal() might reduce it again */
1264 SPEC_USIGN(val->etype) = 0;
1265 SPEC_NOUN(val->etype) = V_INT;
1267 return cheapestVal (val);
1272 /*------------------------------------------------------------------*/
1273 /* valueNot - complements a constant */
1274 /*------------------------------------------------------------------*/
1276 valNot (value * val)
1278 /* depending on type */
1279 if (SPEC_LONG (val->etype))
1281 if (SPEC_USIGN (val->etype))
1282 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1284 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1288 if (SPEC_USIGN (val->etype))
1289 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1291 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1294 /* ANSI: result type is int, value is 0 or 1 */
1295 /* sdcc will hold this in an 'unsigned char' */
1296 SPEC_USIGN(val->etype) = 1;
1297 SPEC_LONG (val->etype) = 0;
1298 SPEC_NOUN(val->etype) = V_CHAR;
1302 /*------------------------------------------------------------------*/
1303 /* valMult - multiply constants */
1304 /*------------------------------------------------------------------*/
1306 valMult (value * lval, value * rval)
1310 /* create a new value */
1312 val->type = val->etype = computeType (lval->etype,
1316 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1318 if (IS_FLOAT (val->type))
1319 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1321 if (IS_FIXED16X16 (val->type))
1322 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1323 /* signed and unsigned mul are the same, as long as the precision of the
1324 result isn't bigger than the precision of the operands. */
1325 else if (SPEC_LONG (val->type))
1326 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1327 (TYPE_TARGET_ULONG) ulFromVal (rval);
1328 else if (SPEC_USIGN (val->type)) /* unsigned int */
1330 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1331 (TYPE_TARGET_UINT) ulFromVal (rval);
1333 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1334 if (ul != (TYPE_TARGET_UINT) ul)
1337 else /* signed int */
1339 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1340 (TYPE_TARGET_INT) floatFromVal (rval);
1342 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1343 if (l != (TYPE_TARGET_INT) l)
1346 return cheapestVal (val);
1349 /*------------------------------------------------------------------*/
1350 /* valDiv - Divide constants */
1351 /*------------------------------------------------------------------*/
1353 valDiv (value * lval, value * rval)
1357 if (floatFromVal (rval) == 0)
1359 werror (E_DIVIDE_BY_ZERO);
1363 /* create a new value */
1365 val->type = val->etype = computeType (lval->etype,
1369 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1371 if (IS_FLOAT (val->type))
1372 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1373 else if (IS_FIXED16X16 (val->type))
1374 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1375 else if (SPEC_LONG (val->type))
1377 if (SPEC_USIGN (val->type))
1378 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1379 (TYPE_TARGET_ULONG) ulFromVal (rval);
1381 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1382 (TYPE_TARGET_LONG) ulFromVal (rval);
1386 if (SPEC_USIGN (val->type))
1387 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1388 (TYPE_TARGET_UINT) ulFromVal (rval);
1390 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1391 (TYPE_TARGET_INT) ulFromVal (rval);
1393 return cheapestVal (val);
1396 /*------------------------------------------------------------------*/
1397 /* valMod - Modulus constants */
1398 /*------------------------------------------------------------------*/
1400 valMod (value * lval, value * rval)
1404 /* create a new value */
1406 val->type = val->etype = computeType (lval->etype,
1410 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1412 if (SPEC_LONG (val->type))
1414 if (SPEC_USIGN (val->type))
1415 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1416 (TYPE_TARGET_ULONG) ulFromVal (rval);
1418 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1419 (TYPE_TARGET_LONG) ulFromVal (rval);
1423 if (SPEC_USIGN (val->type))
1424 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1425 (TYPE_TARGET_UINT) ulFromVal (rval);
1427 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1428 (TYPE_TARGET_INT) ulFromVal (rval);
1430 return cheapestVal (val);
1433 /*------------------------------------------------------------------*/
1434 /* valPlus - Addition constants */
1435 /*------------------------------------------------------------------*/
1437 valPlus (value * lval, value * rval)
1441 /* create a new value */
1443 val->type = val->etype = computeType (lval->etype,
1447 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1449 if (IS_FLOAT (val->type))
1450 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1452 if (IS_FIXED16X16 (val->type))
1453 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1454 else if (SPEC_LONG (val->type))
1456 if (SPEC_USIGN (val->type))
1457 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1458 (TYPE_TARGET_ULONG) ulFromVal (rval);
1460 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1461 (TYPE_TARGET_LONG) ulFromVal (rval);
1465 if (SPEC_USIGN (val->type))
1466 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1467 (TYPE_TARGET_UINT) ulFromVal (rval);
1469 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1470 (TYPE_TARGET_INT) ulFromVal (rval);
1472 return cheapestVal (val);
1475 /*------------------------------------------------------------------*/
1476 /* valMinus - Addition constants */
1477 /*------------------------------------------------------------------*/
1479 valMinus (value * lval, value * rval)
1483 /* create a new value */
1485 val->type = val->etype = computeType (lval->etype,
1489 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1491 if (IS_FLOAT (val->type))
1492 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1494 if (IS_FIXED16X16 (val->type))
1495 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1496 else if (SPEC_LONG (val->type))
1498 if (SPEC_USIGN (val->type))
1499 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1500 (TYPE_TARGET_ULONG) ulFromVal (rval);
1502 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1503 (TYPE_TARGET_LONG) ulFromVal (rval);
1507 if (SPEC_USIGN (val->type))
1508 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1509 (TYPE_TARGET_UINT) ulFromVal (rval);
1511 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1512 (TYPE_TARGET_INT) ulFromVal (rval);
1514 return cheapestVal (val);
1517 /*------------------------------------------------------------------*/
1518 /* valShift - Shift left or right */
1519 /*------------------------------------------------------------------*/
1521 valShift (value * lval, value * rval, int lr)
1525 /* create a new value */
1527 val->type = val->etype = computeType (lval->etype,
1531 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1533 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1536 /* right shift and unsigned */
1537 (!lr && SPEC_USIGN (rval->type))))
1539 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1542 if (SPEC_LONG (val->type))
1544 if (SPEC_USIGN (val->type))
1546 SPEC_CVAL (val->type).v_ulong = lr ?
1547 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1548 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1552 SPEC_CVAL (val->type).v_long = lr ?
1553 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1554 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1559 if (SPEC_USIGN (val->type))
1561 SPEC_CVAL (val->type).v_uint = lr ?
1562 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1563 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1567 SPEC_CVAL (val->type).v_int = lr ?
1568 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1569 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1572 return cheapestVal (val);
1575 /*------------------------------------------------------------------*/
1576 /* valCompare- Compares two literal */
1577 /*------------------------------------------------------------------*/
1579 valCompare (value * lval, value * rval, int ctype)
1583 /* create a new value */
1585 val->type = val->etype = newCharLink ();
1586 val->type->class = SPECIFIER;
1587 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1588 SPEC_USIGN (val->type) = 1;
1589 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1594 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1598 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1602 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1606 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1610 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1611 SPEC_NOUN(rval->type) == V_FLOAT)
1613 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1616 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1617 SPEC_NOUN(rval->type) == V_FIXED16X16)
1619 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1623 /* integrals: ignore signedness */
1624 TYPE_TARGET_ULONG l, r;
1626 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1627 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1628 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1629 neccessary to strip them to 16 bit.
1630 Literals are reduced to their cheapest type, therefore left and
1631 right might have different types. It's neccessary to find a
1632 common type: int (used for char too) or long */
1633 if (!IS_LONG (lval->etype) &&
1634 !IS_LONG (rval->etype))
1636 r = (TYPE_TARGET_UINT) r;
1637 l = (TYPE_TARGET_UINT) l;
1639 SPEC_CVAL (val->type).v_int = l == r;
1643 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1644 SPEC_NOUN(rval->type) == V_FLOAT)
1646 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1649 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1650 SPEC_NOUN(rval->type) == V_FIXED16X16)
1652 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1656 /* integrals: ignore signedness */
1657 TYPE_TARGET_ULONG l, r;
1659 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1660 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1661 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1662 neccessary to strip them to 16 bit.
1663 Literals are reduced to their cheapest type, therefore left and
1664 right might have different types. It's neccessary to find a
1665 common type: int (used for char too) or long */
1666 if (!IS_LONG (lval->etype) &&
1667 !IS_LONG (rval->etype))
1669 r = (TYPE_TARGET_UINT) r;
1670 l = (TYPE_TARGET_UINT) l;
1672 SPEC_CVAL (val->type).v_int = l != r;
1681 /*------------------------------------------------------------------*/
1682 /* valBitwise - Bitwise operation */
1683 /*------------------------------------------------------------------*/
1685 valBitwise (value * lval, value * rval, int op)
1689 /* create a new value */
1691 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1692 val->etype = getSpec (val->type);
1693 SPEC_SCLS (val->etype) = S_LITERAL;
1698 if (SPEC_LONG (val->type))
1700 if (SPEC_USIGN (val->type))
1701 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1702 (TYPE_TARGET_ULONG) ulFromVal (rval);
1704 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1705 (TYPE_TARGET_LONG) ulFromVal (rval);
1709 if (SPEC_USIGN (val->type))
1710 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1711 (TYPE_TARGET_UINT) ulFromVal (rval);
1713 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1714 (TYPE_TARGET_INT) ulFromVal (rval);
1719 if (SPEC_LONG (val->type))
1721 if (SPEC_USIGN (val->type))
1722 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1723 (TYPE_TARGET_ULONG) ulFromVal (rval);
1725 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1726 (TYPE_TARGET_LONG) ulFromVal (rval);
1730 if (SPEC_USIGN (val->type))
1731 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1732 (TYPE_TARGET_UINT) ulFromVal (rval);
1734 SPEC_CVAL (val->type).v_int =
1735 (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1741 if (SPEC_LONG (val->type))
1743 if (SPEC_USIGN (val->type))
1744 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1745 (TYPE_TARGET_ULONG) ulFromVal (rval);
1747 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1748 (TYPE_TARGET_LONG) ulFromVal (rval);
1752 if (SPEC_USIGN (val->type))
1753 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1754 (TYPE_TARGET_UINT) ulFromVal (rval);
1756 SPEC_CVAL (val->type).v_int =
1757 (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1762 return cheapestVal(val);
1765 /*------------------------------------------------------------------*/
1766 /* valAndOr - Generates code for and / or operation */
1767 /*------------------------------------------------------------------*/
1769 valLogicAndOr (value * lval, value * rval, int op)
1773 /* create a new value */
1775 val->type = val->etype = newCharLink ();
1776 val->type->class = SPECIFIER;
1777 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1778 SPEC_USIGN (val->type) = 1;
1783 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1787 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1795 /*------------------------------------------------------------------*/
1796 /* valCastLiteral - casts a literal value to another type */
1797 /*------------------------------------------------------------------*/
1799 valCastLiteral (sym_link * dtype, double fval)
1802 unsigned long l = double2ul (fval);
1809 val->etype = getSpec (val->type = copyLinkChain (dtype));
1812 val->etype = val->type = newLink (SPECIFIER);
1813 SPEC_NOUN (val->etype) = V_VOID;
1815 SPEC_SCLS (val->etype) = S_LITERAL;
1817 /* if it is not a specifier then we can assume that */
1818 /* it will be an unsigned long */
1819 if (!IS_SPEC (val->type))
1821 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1825 switch (SPEC_NOUN (val->etype))
1828 SPEC_CVAL (val->etype).v_float = fval;
1832 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1837 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1841 l &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
1842 if (SPEC_USIGN (val->etype))
1843 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1845 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1849 if (SPEC_USIGN (val->etype))
1850 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1852 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1856 if (SPEC_LONG (val->etype))
1858 if (SPEC_USIGN (val->etype))
1859 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1861 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1865 if (SPEC_USIGN (val->etype))
1866 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1868 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1875 /*------------------------------------------------------------------*/
1876 /* getNelements - determines # of elements from init list */
1877 /*------------------------------------------------------------------*/
1879 getNelements (sym_link * type, initList * ilist)
1886 if (ilist->type == INIT_DEEP)
1887 ilist = ilist->init.deep;
1889 /* if type is a character array and there is only one
1890 (string) initialiser then get the length of the string */
1891 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1893 ast *iast = ilist->init.node;
1894 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1897 werror (E_CONST_EXPECTED);
1901 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1902 /* yep, it's a string */
1904 return DCL_ELEM (v->type);
1912 ilist = ilist->next;
1917 /*-----------------------------------------------------------------*/
1918 /* valForArray - returns a value with name of array index */
1919 /*-----------------------------------------------------------------*/
1921 valForArray (ast * arrExpr)
1923 value *val, *lval = NULL;
1925 int size = getSize (arrExpr->left->ftype->next);
1926 /* if the right or left is an array
1928 if (IS_AST_OP (arrExpr->left))
1930 if (arrExpr->left->opval.op == '[')
1931 lval = valForArray (arrExpr->left);
1932 else if (arrExpr->left->opval.op == '.')
1933 lval = valForStructElem (arrExpr->left->left,
1934 arrExpr->left->right);
1935 else if (arrExpr->left->opval.op == PTR_OP &&
1936 IS_ADDRESS_OF_OP (arrExpr->left->left))
1937 lval = valForStructElem (arrExpr->left->left->left,
1938 arrExpr->left->right);
1943 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1946 if (!IS_AST_LIT_VALUE (arrExpr->right))
1952 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1956 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1959 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1960 AST_ULONG_VALUE (arrExpr->right) * size);
1962 val->type = newLink (DECLARATOR);
1963 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1964 DCL_TYPE (val->type) = CPOINTER;
1965 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1966 DCL_TYPE (val->type) = FPOINTER;
1967 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1968 DCL_TYPE (val->type) = PPOINTER;
1969 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1970 DCL_TYPE (val->type) = IPOINTER;
1971 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1972 DCL_TYPE (val->type) = EEPPOINTER;
1974 DCL_TYPE (val->type) = POINTER;
1975 val->type->next = arrExpr->left->ftype->next;
1976 val->etype = getSpec (val->type);
1980 /*-----------------------------------------------------------------*/
1981 /* valForStructElem - returns value with name of struct element */
1982 /*-----------------------------------------------------------------*/
1984 valForStructElem (ast * structT, ast * elemT)
1986 value *val, *lval = NULL;
1990 /* left could be furthur derefed */
1991 if (IS_AST_OP (structT))
1993 if (structT->opval.op == '[')
1994 lval = valForArray (structT);
1995 else if (structT->opval.op == '.')
1996 lval = valForStructElem (structT->left, structT->right);
1997 else if (structT->opval.op == PTR_OP &&
1998 IS_ADDRESS_OF_OP (structT->left))
1999 lval = valForStructElem (structT->left->left,
2005 if (!IS_AST_SYM_VALUE (elemT))
2008 if (!IS_STRUCT (structT->etype))
2011 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2012 AST_SYMBOL (elemT))) == NULL)
2020 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2024 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2027 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2030 val->type = newLink (DECLARATOR);
2031 if (SPEC_SCLS (structT->etype) == S_CODE)
2032 DCL_TYPE (val->type) = CPOINTER;
2033 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2034 DCL_TYPE (val->type) = FPOINTER;
2035 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2036 DCL_TYPE (val->type) = PPOINTER;
2037 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2038 DCL_TYPE (val->type) = IPOINTER;
2039 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2040 DCL_TYPE (val->type) = EEPPOINTER;
2042 DCL_TYPE (val->type) = POINTER;
2043 val->type->next = sym->type;
2044 val->etype = getSpec (val->type);
2048 /*-----------------------------------------------------------------*/
2049 /* valForCastAggr - will return value for a cast of an aggregate */
2050 /* plus minus a constant */
2051 /*-----------------------------------------------------------------*/
2053 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2057 if (!IS_AST_SYM_VALUE (aexpr))
2059 if (!IS_AST_LIT_VALUE (cnst))
2064 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2065 AST_SYMBOL (aexpr)->rname, op,
2066 getSize (type->next) * AST_ULONG_VALUE (cnst));
2069 val->etype = getSpec (val->type);
2073 /*-----------------------------------------------------------------*/
2074 /* valForCastAggr - will return value for a cast of an aggregate */
2075 /* with no constant */
2076 /*-----------------------------------------------------------------*/
2078 valForCastArr (ast * aexpr, sym_link * type)
2082 if (!IS_AST_SYM_VALUE (aexpr))
2087 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2088 AST_SYMBOL (aexpr)->rname);
2091 val->etype = getSpec (val->type);