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;
844 SPEC_NOUN (val->type) = V_CHAR;
846 if (options.unsigned_char)
848 SPEC_USIGN (val->type) = 1;
849 SPEC_CVAL (val->type).v_uint = (unsigned char) v;
853 SPEC_CVAL (val->type).v_int = (signed char) v;
859 /*------------------------------------------------------------------*/
860 /* strVal - converts a string constant to a value */
861 /*------------------------------------------------------------------*/
863 strVal (const char *s)
867 val = newValue (); /* get a new one */
869 /* get a declarator */
870 val->type = newLink (DECLARATOR);
871 DCL_TYPE (val->type) = ARRAY;
872 val->type->next = val->etype = newLink (SPECIFIER);
873 SPEC_NOUN (val->etype) = V_CHAR;
874 SPEC_SCLS (val->etype) = S_LITERAL;
876 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
877 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
883 /*------------------------------------------------------------------*/
884 /* reverseValWithType - reverses value chain with type & etype */
885 /*------------------------------------------------------------------*/
887 reverseValWithType (value * val)
895 /* save the type * etype chains */
899 /* set the current one 2b null */
900 val->type = val->etype = NULL;
901 val = reverseVal (val);
903 /* restore type & etype */
910 /*------------------------------------------------------------------*/
911 /* reverseVal - reverses the values for a value chain */
912 /*------------------------------------------------------------------*/
914 reverseVal (value * val)
916 value *prev, *curr, *next;
931 val->next = (void *) NULL;
935 /*------------------------------------------------------------------*/
936 /* copyValueChain - will copy a chain of values */
937 /*------------------------------------------------------------------*/
939 copyValueChain (value * src)
946 dest = copyValue (src);
947 dest->next = copyValueChain (src->next);
952 /*------------------------------------------------------------------*/
953 /* copyValue - copies contents of a value to a fresh one */
954 /*------------------------------------------------------------------*/
956 copyValue (value * src)
961 dest->sym = copySymbol (src->sym);
962 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
963 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
964 dest->etype = (src->type ? getSpec (dest->type) : NULL);
969 /*------------------------------------------------------------------*/
970 /* charVal - converts a character constant to a value */
971 /*------------------------------------------------------------------*/
973 charVal (const char *s)
975 /* get rid of quotation */
976 /* if \ then special processing */
979 switch (*++s) /* go beyond the backslash */
982 return constCharVal ('\n');
984 return constCharVal ('\t');
986 return constCharVal ('\v');
988 return constCharVal ('\b');
990 return constCharVal ('\r');
992 return constCharVal ('\f');
994 return constCharVal ('\a');
996 return constCharVal ('\\');
998 return constCharVal ('\?');
1000 return constCharVal ('\'');
1002 return constCharVal ('\"');
1012 return constCharVal (octalEscape (&s));
1015 return constCharVal (hexEscape (&s));
1018 return constCharVal (*s);
1021 else /* not a backslash */
1022 return constCharVal (*s);
1025 /*------------------------------------------------------------------*/
1026 /* valFromType - creates a value from type given */
1027 /*------------------------------------------------------------------*/
1029 valFromType (sym_link * type)
1031 value *val = newValue ();
1032 val->type = copyLinkChain (type);
1033 val->etype = getSpec (val->type);
1037 /*------------------------------------------------------------------*/
1038 /* floatFromVal - value to double float conversion */
1039 /*------------------------------------------------------------------*/
1041 floatFromVal (value * val)
1046 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1048 werror (E_CONST_EXPECTED, val->name);
1052 /* if it is not a specifier then we can assume that */
1053 /* it will be an unsigned long */
1054 if (!IS_SPEC (val->type))
1055 return SPEC_CVAL (val->etype).v_ulong;
1057 if (SPEC_NOUN (val->etype) == V_FLOAT)
1058 return SPEC_CVAL (val->etype).v_float;
1060 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1061 return doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16);
1063 if (SPEC_LONG (val->etype))
1065 if (SPEC_USIGN (val->etype))
1066 return SPEC_CVAL (val->etype).v_ulong;
1068 return SPEC_CVAL (val->etype).v_long;
1071 if (SPEC_NOUN (val->etype) == V_INT)
1073 if (SPEC_USIGN (val->etype))
1074 return SPEC_CVAL (val->etype).v_uint;
1076 return SPEC_CVAL (val->etype).v_int;
1079 if (SPEC_NOUN (val->etype) == V_CHAR)
1081 if (SPEC_USIGN (val->etype))
1082 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1084 return (signed char) SPEC_CVAL (val->etype).v_int;
1087 if (IS_BITVAR(val->etype))
1088 return SPEC_CVAL (val->etype).v_uint;
1090 if (SPEC_NOUN (val->etype) == V_VOID)
1091 return SPEC_CVAL (val->etype).v_ulong;
1094 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1098 /*------------------------------------------------------------------*/
1099 /* ulFromVal - value to unsigned long conversion */
1100 /*------------------------------------------------------------------*/
1102 ulFromVal (value * val)
1107 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1109 werror (E_CONST_EXPECTED, val->name);
1113 /* if it is not a specifier then we can assume that */
1114 /* it will be an unsigned long */
1115 if (!IS_SPEC (val->type))
1116 return SPEC_CVAL (val->etype).v_ulong;
1118 if (SPEC_NOUN (val->etype) == V_FLOAT)
1119 return double2ul (SPEC_CVAL (val->etype).v_float);
1121 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1122 return double2ul (doubleFromFixed16x16 (SPEC_CVAL (val->etype).v_fixed16x16));
1124 if (SPEC_LONG (val->etype))
1126 if (SPEC_USIGN (val->etype))
1127 return SPEC_CVAL (val->etype).v_ulong;
1129 return SPEC_CVAL (val->etype).v_long;
1132 if (SPEC_NOUN (val->etype) == V_INT)
1134 if (SPEC_USIGN (val->etype))
1135 return SPEC_CVAL (val->etype).v_uint;
1137 return SPEC_CVAL (val->etype).v_int;
1140 if (SPEC_NOUN (val->etype) == V_CHAR)
1142 if (SPEC_USIGN (val->etype))
1143 return (unsigned char) SPEC_CVAL (val->etype).v_uint;
1145 return (signed char) SPEC_CVAL (val->etype).v_int;
1148 if (IS_BITVAR(val->etype))
1149 return SPEC_CVAL (val->etype).v_uint;
1151 if (SPEC_NOUN (val->etype) == V_VOID)
1152 return SPEC_CVAL (val->etype).v_ulong;
1155 werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1159 /*-----------------------------------------------------------------*/
1160 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1161 /*-----------------------------------------------------------------*/
1162 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1165 /* This version is incorrect negative values. */
1166 double tmp=0, exp=2;
1168 tmp = (value & 0xffff0000) >> 16;
1172 if(value & 0x8000)tmp += 1/exp;
1179 return ((double)(value * 1.0) / (double)(1UL << 16));
1183 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1186 /* This version is incorrect negative values. */
1187 unsigned int tmp=0, pos=16;
1188 TYPE_TARGET_ULONG res;
1190 tmp = floor( value );
1197 if(value >= 1.0)tmp |= (1 << pos);
1198 value -= floor( value );
1205 return double2ul (value * (double)(1UL << 16));
1209 /*------------------------------------------------------------------*/
1210 /* valUnaryPM - does the unary +/- operation on a constant */
1211 /*------------------------------------------------------------------*/
1213 valUnaryPM (value * val)
1215 /* depending on type */
1216 if (SPEC_NOUN (val->etype) == V_FLOAT)
1217 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1218 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1219 SPEC_CVAL (val->etype).v_fixed16x16 = (TYPE_TARGET_ULONG) -((long) SPEC_CVAL (val->etype).v_fixed16x16);
1222 if (SPEC_LONG (val->etype))
1224 if (SPEC_USIGN (val->etype))
1225 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1227 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1231 if (SPEC_USIGN (val->etype))
1232 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1234 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1236 if (SPEC_NOUN(val->etype) == V_CHAR)
1238 /* promote to 'signed int', cheapestVal() might reduce it again */
1239 SPEC_USIGN(val->etype) = 0;
1240 SPEC_NOUN(val->etype) = V_INT;
1242 return cheapestVal (val);
1248 /*------------------------------------------------------------------*/
1249 /* valueComplement - complements a constant */
1250 /*------------------------------------------------------------------*/
1252 valComplement (value * val)
1254 /* depending on type */
1255 if (SPEC_LONG (val->etype))
1257 if (SPEC_USIGN (val->etype))
1258 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1260 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1264 if (SPEC_USIGN (val->etype))
1265 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1267 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1269 if (SPEC_NOUN(val->etype) == V_CHAR)
1271 /* promote to 'signed int', cheapestVal() might reduce it again */
1272 SPEC_USIGN(val->etype) = 0;
1273 SPEC_NOUN(val->etype) = V_INT;
1275 return cheapestVal (val);
1280 /*------------------------------------------------------------------*/
1281 /* valueNot - complements a constant */
1282 /*------------------------------------------------------------------*/
1284 valNot (value * val)
1286 /* depending on type */
1287 if (SPEC_LONG (val->etype))
1289 if (SPEC_USIGN (val->etype))
1290 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1292 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1296 if (SPEC_USIGN (val->etype))
1297 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1299 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1302 /* ANSI: result type is int, value is 0 or 1 */
1303 /* sdcc will hold this in an 'unsigned char' */
1304 SPEC_USIGN(val->etype) = 1;
1305 SPEC_LONG (val->etype) = 0;
1306 SPEC_NOUN(val->etype) = V_CHAR;
1310 /*------------------------------------------------------------------*/
1311 /* valMult - multiply constants */
1312 /*------------------------------------------------------------------*/
1314 valMult (value * lval, value * rval)
1318 /* create a new value */
1320 val->type = val->etype = computeType (lval->etype,
1324 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1326 if (IS_FLOAT (val->type))
1327 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1329 if (IS_FIXED16X16 (val->type))
1330 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1331 /* signed and unsigned mul are the same, as long as the precision of the
1332 result isn't bigger than the precision of the operands. */
1333 else if (SPEC_LONG (val->type))
1334 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1335 (TYPE_TARGET_ULONG) ulFromVal (rval);
1336 else if (SPEC_USIGN (val->type)) /* unsigned int */
1338 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1339 (TYPE_TARGET_UINT) ulFromVal (rval);
1341 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1342 if (ul != (TYPE_TARGET_UINT) ul)
1345 else /* signed int */
1347 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1348 (TYPE_TARGET_INT) floatFromVal (rval);
1350 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1351 if (l != (TYPE_TARGET_INT) l)
1354 return cheapestVal (val);
1357 /*------------------------------------------------------------------*/
1358 /* valDiv - Divide constants */
1359 /*------------------------------------------------------------------*/
1361 valDiv (value * lval, value * rval)
1365 if (floatFromVal (rval) == 0)
1367 werror (E_DIVIDE_BY_ZERO);
1371 /* create a new value */
1373 val->type = val->etype = computeType (lval->etype,
1377 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1379 if (IS_FLOAT (val->type))
1380 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1381 else if (IS_FIXED16X16 (val->type))
1382 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1383 else if (SPEC_LONG (val->type))
1385 if (SPEC_USIGN (val->type))
1386 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1387 (TYPE_TARGET_ULONG) ulFromVal (rval);
1389 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1390 (TYPE_TARGET_LONG) ulFromVal (rval);
1394 if (SPEC_USIGN (val->type))
1395 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1396 (TYPE_TARGET_UINT) ulFromVal (rval);
1398 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1399 (TYPE_TARGET_INT) ulFromVal (rval);
1401 return cheapestVal (val);
1404 /*------------------------------------------------------------------*/
1405 /* valMod - Modulus constants */
1406 /*------------------------------------------------------------------*/
1408 valMod (value * lval, value * rval)
1412 /* create a new value */
1414 val->type = val->etype = computeType (lval->etype,
1418 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1420 if (SPEC_LONG (val->type))
1422 if (SPEC_USIGN (val->type))
1423 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1424 (TYPE_TARGET_ULONG) ulFromVal (rval);
1426 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1427 (TYPE_TARGET_LONG) ulFromVal (rval);
1431 if (SPEC_USIGN (val->type))
1432 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1433 (TYPE_TARGET_UINT) ulFromVal (rval);
1435 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1436 (TYPE_TARGET_INT) ulFromVal (rval);
1438 return cheapestVal (val);
1441 /*------------------------------------------------------------------*/
1442 /* valPlus - Addition constants */
1443 /*------------------------------------------------------------------*/
1445 valPlus (value * lval, value * rval)
1449 /* create a new value */
1451 val->type = val->etype = computeType (lval->etype,
1455 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1457 if (IS_FLOAT (val->type))
1458 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1460 if (IS_FIXED16X16 (val->type))
1461 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1462 else if (SPEC_LONG (val->type))
1464 if (SPEC_USIGN (val->type))
1465 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1466 (TYPE_TARGET_ULONG) ulFromVal (rval);
1468 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1469 (TYPE_TARGET_LONG) ulFromVal (rval);
1473 if (SPEC_USIGN (val->type))
1474 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1475 (TYPE_TARGET_UINT) ulFromVal (rval);
1477 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1478 (TYPE_TARGET_INT) ulFromVal (rval);
1480 return cheapestVal (val);
1483 /*------------------------------------------------------------------*/
1484 /* valMinus - Addition constants */
1485 /*------------------------------------------------------------------*/
1487 valMinus (value * lval, value * rval)
1491 /* create a new value */
1493 val->type = val->etype = computeType (lval->etype,
1497 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1499 if (IS_FLOAT (val->type))
1500 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1502 if (IS_FIXED16X16 (val->type))
1503 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1504 else if (SPEC_LONG (val->type))
1506 if (SPEC_USIGN (val->type))
1507 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1508 (TYPE_TARGET_ULONG) ulFromVal (rval);
1510 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1511 (TYPE_TARGET_LONG) ulFromVal (rval);
1515 if (SPEC_USIGN (val->type))
1516 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1517 (TYPE_TARGET_UINT) ulFromVal (rval);
1519 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1520 (TYPE_TARGET_INT) ulFromVal (rval);
1522 return cheapestVal (val);
1525 /*------------------------------------------------------------------*/
1526 /* valShift - Shift left or right */
1527 /*------------------------------------------------------------------*/
1529 valShift (value * lval, value * rval, int lr)
1533 /* create a new value */
1535 val->type = val->etype = computeType (lval->etype,
1539 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1541 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1544 /* right shift and unsigned */
1545 (!lr && SPEC_USIGN (rval->type))))
1547 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1550 if (SPEC_LONG (val->type))
1552 if (SPEC_USIGN (val->type))
1554 SPEC_CVAL (val->type).v_ulong = lr ?
1555 (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1556 (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1560 SPEC_CVAL (val->type).v_long = lr ?
1561 (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1562 (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1567 if (SPEC_USIGN (val->type))
1569 SPEC_CVAL (val->type).v_uint = lr ?
1570 (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1571 (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1575 SPEC_CVAL (val->type).v_int = lr ?
1576 (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1577 (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1580 return cheapestVal (val);
1583 /*------------------------------------------------------------------*/
1584 /* valCompare- Compares two literal */
1585 /*------------------------------------------------------------------*/
1587 valCompare (value * lval, value * rval, int ctype)
1591 /* create a new value */
1593 val->type = val->etype = newCharLink ();
1594 val->type->class = SPECIFIER;
1595 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1596 SPEC_USIGN (val->type) = 1;
1597 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1602 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1606 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1610 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1614 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1618 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1619 SPEC_NOUN(rval->type) == V_FLOAT)
1621 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1624 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1625 SPEC_NOUN(rval->type) == V_FIXED16X16)
1627 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1631 /* integrals: ignore signedness */
1632 TYPE_TARGET_ULONG l, r;
1634 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1635 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1636 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1637 neccessary to strip them to 16 bit.
1638 Literals are reduced to their cheapest type, therefore left and
1639 right might have different types. It's neccessary to find a
1640 common type: int (used for char too) or long */
1641 if (!IS_LONG (lval->etype) &&
1642 !IS_LONG (rval->etype))
1644 r = (TYPE_TARGET_UINT) r;
1645 l = (TYPE_TARGET_UINT) l;
1647 SPEC_CVAL (val->type).v_int = l == r;
1651 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1652 SPEC_NOUN(rval->type) == V_FLOAT)
1654 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1657 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1658 SPEC_NOUN(rval->type) == V_FIXED16X16)
1660 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1664 /* integrals: ignore signedness */
1665 TYPE_TARGET_ULONG l, r;
1667 l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1668 r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1669 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1670 neccessary to strip them to 16 bit.
1671 Literals are reduced to their cheapest type, therefore left and
1672 right might have different types. It's neccessary to find a
1673 common type: int (used for char too) or long */
1674 if (!IS_LONG (lval->etype) &&
1675 !IS_LONG (rval->etype))
1677 r = (TYPE_TARGET_UINT) r;
1678 l = (TYPE_TARGET_UINT) l;
1680 SPEC_CVAL (val->type).v_int = l != r;
1689 /*------------------------------------------------------------------*/
1690 /* valBitwise - Bitwise operation */
1691 /*------------------------------------------------------------------*/
1693 valBitwise (value * lval, value * rval, int op)
1697 /* create a new value */
1699 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1700 val->etype = getSpec (val->type);
1701 SPEC_SCLS (val->etype) = S_LITERAL;
1706 if (SPEC_LONG (val->type))
1708 if (SPEC_USIGN (val->type))
1709 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1710 (TYPE_TARGET_ULONG) ulFromVal (rval);
1712 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1713 (TYPE_TARGET_LONG) ulFromVal (rval);
1717 if (SPEC_USIGN (val->type))
1718 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1719 (TYPE_TARGET_UINT) ulFromVal (rval);
1721 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1722 (TYPE_TARGET_INT) ulFromVal (rval);
1727 if (SPEC_LONG (val->type))
1729 if (SPEC_USIGN (val->type))
1730 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1731 (TYPE_TARGET_ULONG) ulFromVal (rval);
1733 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1734 (TYPE_TARGET_LONG) ulFromVal (rval);
1738 if (SPEC_USIGN (val->type))
1739 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1740 (TYPE_TARGET_UINT) ulFromVal (rval);
1742 SPEC_CVAL (val->type).v_int =
1743 (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1749 if (SPEC_LONG (val->type))
1751 if (SPEC_USIGN (val->type))
1752 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1753 (TYPE_TARGET_ULONG) ulFromVal (rval);
1755 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1756 (TYPE_TARGET_LONG) ulFromVal (rval);
1760 if (SPEC_USIGN (val->type))
1761 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1762 (TYPE_TARGET_UINT) ulFromVal (rval);
1764 SPEC_CVAL (val->type).v_int =
1765 (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1770 return cheapestVal(val);
1773 /*------------------------------------------------------------------*/
1774 /* valAndOr - Generates code for and / or operation */
1775 /*------------------------------------------------------------------*/
1777 valLogicAndOr (value * lval, value * rval, int op)
1781 /* create a new value */
1783 val->type = val->etype = newCharLink ();
1784 val->type->class = SPECIFIER;
1785 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1786 SPEC_USIGN (val->type) = 1;
1791 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1795 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1803 /*------------------------------------------------------------------*/
1804 /* valCastLiteral - casts a literal value to another type */
1805 /*------------------------------------------------------------------*/
1807 valCastLiteral (sym_link * dtype, double fval)
1810 unsigned long l = double2ul (fval);
1817 val->etype = getSpec (val->type = copyLinkChain (dtype));
1820 val->etype = val->type = newLink (SPECIFIER);
1821 SPEC_NOUN (val->etype) = V_VOID;
1823 SPEC_SCLS (val->etype) = S_LITERAL;
1825 /* if it is not a specifier then we can assume that */
1826 /* it will be an unsigned long */
1827 if (!IS_SPEC (val->type))
1829 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1833 switch (SPEC_NOUN (val->etype))
1836 SPEC_CVAL (val->etype).v_float = fval;
1840 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1845 SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1849 l &= (0xffffffffu >> (32 - SPEC_BLEN (val->etype)));
1850 if (SPEC_USIGN (val->etype))
1851 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1853 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1857 if (SPEC_USIGN (val->etype))
1858 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1860 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1864 if (SPEC_LONG (val->etype))
1866 if (SPEC_USIGN (val->etype))
1867 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1869 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1873 if (SPEC_USIGN (val->etype))
1874 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1876 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1883 /*------------------------------------------------------------------*/
1884 /* getNelements - determines # of elements from init list */
1885 /*------------------------------------------------------------------*/
1887 getNelements (sym_link * type, initList * ilist)
1894 if (ilist->type == INIT_DEEP)
1895 ilist = ilist->init.deep;
1897 /* if type is a character array and there is only one
1898 (string) initialiser then get the length of the string */
1899 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1901 ast *iast = ilist->init.node;
1902 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1905 werror (E_CONST_EXPECTED);
1909 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1910 /* yep, it's a string */
1912 return DCL_ELEM (v->type);
1920 ilist = ilist->next;
1925 /*-----------------------------------------------------------------*/
1926 /* valForArray - returns a value with name of array index */
1927 /*-----------------------------------------------------------------*/
1929 valForArray (ast * arrExpr)
1931 value *val, *lval = NULL;
1933 int size = getSize (arrExpr->left->ftype->next);
1934 /* if the right or left is an array
1936 if (IS_AST_OP (arrExpr->left))
1938 if (arrExpr->left->opval.op == '[')
1939 lval = valForArray (arrExpr->left);
1940 else if (arrExpr->left->opval.op == '.')
1941 lval = valForStructElem (arrExpr->left->left,
1942 arrExpr->left->right);
1943 else if (arrExpr->left->opval.op == PTR_OP &&
1944 IS_ADDRESS_OF_OP (arrExpr->left->left))
1945 lval = valForStructElem (arrExpr->left->left->left,
1946 arrExpr->left->right);
1951 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1954 if (!IS_AST_LIT_VALUE (arrExpr->right))
1960 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1964 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1967 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1968 AST_ULONG_VALUE (arrExpr->right) * size);
1970 val->type = newLink (DECLARATOR);
1971 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1972 DCL_TYPE (val->type) = CPOINTER;
1973 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1974 DCL_TYPE (val->type) = FPOINTER;
1975 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1976 DCL_TYPE (val->type) = PPOINTER;
1977 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1978 DCL_TYPE (val->type) = IPOINTER;
1979 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1980 DCL_TYPE (val->type) = EEPPOINTER;
1982 DCL_TYPE (val->type) = POINTER;
1983 val->type->next = arrExpr->left->ftype->next;
1984 val->etype = getSpec (val->type);
1988 /*-----------------------------------------------------------------*/
1989 /* valForStructElem - returns value with name of struct element */
1990 /*-----------------------------------------------------------------*/
1992 valForStructElem (ast * structT, ast * elemT)
1994 value *val, *lval = NULL;
1998 /* left could be furthur derefed */
1999 if (IS_AST_OP (structT))
2001 if (structT->opval.op == '[')
2002 lval = valForArray (structT);
2003 else if (structT->opval.op == '.')
2004 lval = valForStructElem (structT->left, structT->right);
2005 else if (structT->opval.op == PTR_OP &&
2006 IS_ADDRESS_OF_OP (structT->left))
2007 lval = valForStructElem (structT->left->left,
2013 if (!IS_AST_SYM_VALUE (elemT))
2016 if (!IS_STRUCT (structT->etype))
2019 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2020 AST_SYMBOL (elemT))) == NULL)
2028 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2032 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2035 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2038 val->type = newLink (DECLARATOR);
2039 if (SPEC_SCLS (structT->etype) == S_CODE)
2040 DCL_TYPE (val->type) = CPOINTER;
2041 else if (SPEC_SCLS (structT->etype) == S_XDATA)
2042 DCL_TYPE (val->type) = FPOINTER;
2043 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2044 DCL_TYPE (val->type) = PPOINTER;
2045 else if (SPEC_SCLS (structT->etype) == S_IDATA)
2046 DCL_TYPE (val->type) = IPOINTER;
2047 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2048 DCL_TYPE (val->type) = EEPPOINTER;
2050 DCL_TYPE (val->type) = POINTER;
2051 val->type->next = sym->type;
2052 val->etype = getSpec (val->type);
2056 /*-----------------------------------------------------------------*/
2057 /* valForCastAggr - will return value for a cast of an aggregate */
2058 /* plus minus a constant */
2059 /*-----------------------------------------------------------------*/
2061 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2065 if (!IS_AST_SYM_VALUE (aexpr))
2067 if (!IS_AST_LIT_VALUE (cnst))
2072 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2073 AST_SYMBOL (aexpr)->rname, op,
2074 getSize (type->next) * AST_ULONG_VALUE (cnst));
2077 val->etype = getSpec (val->type);
2081 /*-----------------------------------------------------------------*/
2082 /* valForCastAggr - will return value for a cast of an aggregate */
2083 /* with no constant */
2084 /*-----------------------------------------------------------------*/
2086 valForCastArr (ast * aexpr, sym_link * type)
2090 if (!IS_AST_SYM_VALUE (aexpr))
2095 SNPRINTF (val->name, sizeof(val->name), "(%s)",
2096 AST_SYMBOL (aexpr)->rname);
2099 val->etype = getSpec (val->type);