1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value */
37 /*-----------------------------------------------------------------*/
43 val = Safe_alloc (sizeof (value));
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list */
50 /*-----------------------------------------------------------------*/
52 newiList (int type, void *ilist)
57 nilist = Safe_alloc (sizeof (initList));
60 nilist->lineno = lexLineno;
61 nilist->filename = lexFilename;
66 nilist->init.node = (struct ast *) ilist;
70 nilist->init.deep = (struct initList *) ilist;
77 /*------------------------------------------------------------------*/
78 /* revinit - reverses the initial values for a value chain */
79 /*------------------------------------------------------------------*/
81 revinit (initList * val)
83 initList *prev, *curr, *next;
98 val->next = (void *) NULL;
103 convertIListToConstList(initList *src, literalList **lList)
106 literalList *head, *last, *newL;
110 if (!src || src->type != INIT_DEEP)
115 iLoop = src->init.deep;
119 if (iLoop->type != INIT_NODE)
124 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
131 // We've now established that the initializer list contains only literal values.
133 iLoop = src->init.deep;
136 double val = AST_LIT_VALUE(iLoop->init.node);
138 if (last && last->literalValue == val)
144 newL = Safe_alloc(sizeof(literalList));
145 newL->literalValue = val;
172 copyLiteralList(literalList *src)
174 literalList *head, *prev, *newL;
180 newL = Safe_alloc(sizeof(literalList));
182 newL->literalValue = src->literalValue;
183 newL->count = src->count;
203 /*------------------------------------------------------------------*/
204 /* copyIlist - copy initializer list */
205 /*------------------------------------------------------------------*/
207 copyIlist (initList * src)
209 initList *dest = NULL;
217 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
220 dest = newiList (INIT_NODE, copyAst (src->init.node));
225 dest->next = copyIlist (src->next);
230 /*------------------------------------------------------------------*/
231 /* list2int - converts the first element of the list to value */
232 /*------------------------------------------------------------------*/
234 list2int (initList * val)
238 if (i->type == INIT_DEEP)
239 return list2int (val->init.deep);
241 return floatFromVal (constExprValue (val->init.node, TRUE));
244 /*------------------------------------------------------------------*/
245 /* list2val - converts the first element of the list to value */
246 /*------------------------------------------------------------------*/
248 list2val (initList * val)
253 if (val->type == INIT_DEEP)
254 return list2val (val->init.deep);
256 return constExprValue (val->init.node, TRUE);
259 /*------------------------------------------------------------------*/
260 /* list2expr - returns the first expression in the initializer list */
261 /*------------------------------------------------------------------*/
263 list2expr (initList * ilist)
265 if (ilist->type == INIT_DEEP)
266 return list2expr (ilist->init.deep);
267 return ilist->init.node;
270 /*------------------------------------------------------------------*/
271 /* resolveIvalSym - resolve symbols in initial values */
272 /*------------------------------------------------------------------*/
274 resolveIvalSym (initList * ilist, sym_link * type)
276 int is_ptr = IS_PTR (type);
277 RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
281 if (ilist->type == INIT_NODE)
283 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
284 is_ptr ? RESULT_TYPE_INT : resultType);
286 else if (ilist->type == INIT_DEEP)
288 resolveIvalSym (ilist->init.deep, type);
295 /*------------------------------------------------------------------*/
296 /* symbolVal - creates a value for a symbol */
297 /*------------------------------------------------------------------*/
299 symbolVal (symbol * sym)
311 val->type = sym->type;
312 val->etype = getSpec (val->type);
317 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
321 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
327 /*--------------------------------------------------------------------*/
328 /* cheapestVal - try to reduce 'signed int' to 'char' */
329 /*--------------------------------------------------------------------*/
331 cheapestVal (value *val)
333 /* only int can be reduced */
334 if (!IS_INT(val->type))
337 /* long must not be changed */
338 if (SPEC_LONG(val->type))
341 /* unsigned must not be changed */
342 if (SPEC_USIGN(val->type))
345 /* the only possible reduction is from signed int to (un)signed char,
346 because it's automatically promoted back to signed int.
348 a reduction from unsigned int to unsigned char is a bug,
349 because an _unsigned_ char is promoted to _signed_ int! */
350 if (SPEC_CVAL(val->type).v_int < -128 ||
351 SPEC_CVAL(val->type).v_int > 255)
353 /* not in the range of (un)signed char */
357 SPEC_NOUN(val->type) = V_CHAR;
359 /* 'unsigned char' promotes to 'signed int', so that we can
360 reduce it the other way */
361 if (SPEC_CVAL(val->type).v_int >= 0)
363 SPEC_USIGN(val->type) = 1;
368 /*--------------------------------------------------------------------*/
369 /* checkConstantRange - check if constant fits in numeric range of */
370 /* var type in comparisons and assignments */
371 /*--------------------------------------------------------------------*/
373 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
379 litVal = floatFromVal (valFromType (lit));
380 varBits = bitsForType (var);
387 return CCR_ALWAYS_FALSE;
389 return CCR_ALWAYS_TRUE;
391 /* special: assignment */
397 if (getenv ("SDCC_VERY_PEDANTIC"))
399 if (SPEC_USIGN (var))
401 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
410 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
411 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
421 /* ignore signedness, e.g. allow everything
422 from -127...+255 for (unsigned) char */
423 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
424 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
433 if (exchangeLeftRight)
438 case '>': op = '<'; break;
439 case GE_OP: op = LE_OP; break;
440 case '<': op = '>'; break;
441 case LE_OP: op = GE_OP; break;
442 default: return CCR_ALWAYS_FALSE;
445 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
447 if (SPEC_USIGN (reType))
449 /* unsigned operation */
450 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
451 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
453 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
455 /* both operands are unsigned, this is easy */
457 maxValP = 0xffffffffu >> (32 - varBits);
458 /* there's only range, just copy it to 2nd set */
462 else if (SPEC_USIGN (var))
464 /* lit is casted from signed to unsigned, e.g.:
470 maxValP = 0xffffffffu >> (32 - varBits);
471 /* there's only one range, just copy it to 2nd set */
475 /* it's an unsigned operation */
476 if ( IS_CHAR (reType)
479 /* make signed literal unsigned and
480 limit no of bits to size of return type */
481 litVal = (TYPE_TARGET_ULONG) litVal & opBitsMask;
484 else /* SPEC_USIGN (lit) */
486 /* var is casted from signed to unsigned, e.g.:
491 The possible values after casting var
492 split up in two, nonconsecutive ranges:
494 minValP = 0; positive range: 0...127
496 minValM = 0xff80; negative range: -128...-1
502 maxValP = 0x7fffffffu >> (32 - varBits);
505 minValM = 0xffffffff << (varBits - 1);
506 maxValM = 0xffffffffu; /* -1 */
507 /* limit no of bits to size of return type */
508 minValM &= opBitsMask;
509 maxValM &= opBitsMask;
514 case EQ_OP: /* var == lit */
515 if ( litVal <= maxValP
516 && litVal >= minValP) /* 0 */
518 if ( litVal <= maxValM
519 && litVal >= minValM)
521 return CCR_ALWAYS_FALSE;
522 case NE_OP: /* var != lit */
523 if ( litVal <= maxValP
524 && litVal >= minValP) /* 0 */
526 if ( litVal <= maxValM
527 && litVal >= minValM)
529 return CCR_ALWAYS_TRUE;
530 case '>': /* var > lit */
531 if (litVal >= maxValM)
532 return CCR_ALWAYS_FALSE;
533 if (litVal < minValP) /* 0 */
534 return CCR_ALWAYS_TRUE;
536 case GE_OP: /* var >= lit */
537 if (litVal > maxValM)
538 return CCR_ALWAYS_FALSE;
539 if (litVal <= minValP) /* 0 */
540 return CCR_ALWAYS_TRUE;
542 case '<': /* var < lit */
543 if (litVal > maxValM)
544 return CCR_ALWAYS_TRUE;
545 if (litVal <= minValP) /* 0 */
546 return CCR_ALWAYS_FALSE;
548 case LE_OP: /* var <= lit */
549 if (litVal >= maxValM)
550 return CCR_ALWAYS_TRUE;
551 if (litVal < minValP) /* 0 */
552 return CCR_ALWAYS_FALSE;
555 return CCR_ALWAYS_FALSE;
560 /* signed operation */
561 TYPE_TARGET_LONG minVal, maxVal;
563 if (SPEC_USIGN (var))
565 /* unsigned var, but signed operation. This happens
566 when var is promoted to signed int.
567 Set actual min/max values of var. */
569 maxVal = 0xffffffff >> (32 - varBits);
574 minVal = 0xffffffff << (varBits - 1);
575 maxVal = 0x7fffffff >> (32 - varBits);
580 case EQ_OP: /* var == lit */
583 return CCR_ALWAYS_FALSE;
585 case NE_OP: /* var != lit */
588 return CCR_ALWAYS_TRUE;
590 case '>': /* var > lit */
591 if (litVal >= maxVal)
592 return CCR_ALWAYS_FALSE;
594 return CCR_ALWAYS_TRUE;
596 case GE_OP: /* var >= lit */
598 return CCR_ALWAYS_FALSE;
599 if (litVal <= minVal)
600 return CCR_ALWAYS_TRUE;
602 case '<': /* var < lit */
604 return CCR_ALWAYS_TRUE;
605 if (litVal <= minVal)
606 return CCR_ALWAYS_FALSE;
608 case LE_OP: /* var <= lit */
609 if (litVal >= maxVal)
610 return CCR_ALWAYS_TRUE;
612 return CCR_ALWAYS_FALSE;
615 return CCR_ALWAYS_FALSE;
620 /*-----------------------------------------------------------------*/
621 /* valueFromLit - creates a value from a literal */
622 /*-----------------------------------------------------------------*/
624 valueFromLit (double lit)
628 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
630 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
631 return constVal (buffer);
634 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
635 return constFloatVal (buffer);
638 /*-----------------------------------------------------------------*/
639 /* constFloatVal - converts a FLOAT constant to value */
640 /*-----------------------------------------------------------------*/
642 constFloatVal (char *s)
644 value *val = newValue ();
647 if (sscanf (s, "%lf", &sval) != 1)
649 werror (E_INVALID_FLOAT_CONST, s);
650 return constVal ("0");
653 val->type = val->etype = newLink (SPECIFIER);
654 SPEC_NOUN (val->type) = V_FLOAT;
655 SPEC_SCLS (val->type) = S_LITERAL;
656 SPEC_CVAL (val->type).v_float = sval;
661 /*-----------------------------------------------------------------*/
662 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
663 /*-----------------------------------------------------------------*/
665 constFixed16x16Val (char *s)
667 value *val = newValue ();
670 if (sscanf (s, "%lf", &sval) != 1)
672 werror (E_INVALID_FLOAT_CONST, s);
673 return constVal ("0");
676 val->type = val->etype = newLink (SPECIFIER);
677 SPEC_NOUN (val->type) = V_FLOAT;
678 SPEC_SCLS (val->type) = S_LITERAL;
679 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
684 /*-----------------------------------------------------------------*/
685 /* constVal - converts an INTEGER constant into a cheapest value */
686 /*-----------------------------------------------------------------*/
687 value *constVal (const char *s)
690 short hex = 0, octal = 0;
693 val = newValue (); /* alloc space for value */
695 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
696 SPEC_SCLS (val->type) = S_LITERAL;
697 // let's start with a signed char
698 SPEC_NOUN (val->type) = V_CHAR;
699 SPEC_USIGN (val->type) = 0;
701 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
703 /* set the octal flag */
704 if (!hex && *s == '0' && *(s + 1))
710 sval = strtoul (s, NULL, 0);
714 werror (W_INVALID_INT_CONST, s, dval);
717 sscanf (s, "%lf", &dval);
720 /* Setup the flags first */
721 /* set the unsigned flag if 'uU' is found */
722 if (strchr (s, 'u') || strchr (s, 'U')) {
723 SPEC_USIGN (val->type) = 1;
726 /* set the b_long flag if 'lL' is found */
727 if (strchr (s, 'l') || strchr (s, 'L')) {
728 SPEC_NOUN (val->type) = V_INT;
729 SPEC_LONG (val->type) = 1;
731 if (dval<0) { // "-28u" will still be signed and negative
732 if (dval<-128) { // check if we have to promote to int
733 SPEC_NOUN (val->type) = V_INT;
735 if (dval<-32768) { // check if we have to promote to long int
736 SPEC_LONG (val->type) = 1;
739 if (dval>0xff || /* check if we have to promote to int */
740 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
741 char. After an integral promotion it will
742 be a signed int; this certainly isn't what
743 the programer wants */
744 SPEC_NOUN (val->type) = V_INT;
746 else { /* store char's always as unsigned; this helps other optimizations */
747 SPEC_USIGN (val->type) = 1;
749 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
750 SPEC_LONG (val->type) = 1;
752 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
753 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
755 SPEC_USIGN (val->type) = 1;
757 SPEC_LONG (val->type) = 1;
758 if (dval>0x7fffffff) {
759 SPEC_USIGN (val->type) = 1;
766 /* check for out of range */
767 if (dval<-2147483648.0) {
768 dval = -2147483648.0;
769 werror (W_INVALID_INT_CONST, s, dval);
771 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
773 werror (W_INVALID_INT_CONST, s, dval);
775 if (dval>4294967295.0) {
777 werror (W_INVALID_INT_CONST, s, dval);
780 if (SPEC_LONG (val->type))
782 if (SPEC_USIGN (val->type))
784 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG)dval;
788 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG)dval;
793 if (SPEC_USIGN (val->type))
795 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT)dval;
799 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT)dval;
806 /*------------------------------------------------------------------*/
807 /* strVal - converts a string constant to a value */
808 /*------------------------------------------------------------------*/
810 strVal (const char *s)
814 val = newValue (); /* get a new one */
816 /* get a declarator */
817 val->type = newLink (DECLARATOR);
818 DCL_TYPE (val->type) = ARRAY;
819 val->type->next = val->etype = newLink (SPECIFIER);
820 SPEC_NOUN (val->etype) = V_CHAR;
821 SPEC_SCLS (val->etype) = S_LITERAL;
823 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
824 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
830 /*------------------------------------------------------------------*/
831 /* reverseValWithType - reverses value chain with type & etype */
832 /*------------------------------------------------------------------*/
834 reverseValWithType (value * val)
842 /* save the type * etype chains */
846 /* set the current one 2b null */
847 val->type = val->etype = NULL;
848 val = reverseVal (val);
850 /* restore type & etype */
857 /*------------------------------------------------------------------*/
858 /* reverseVal - reverses the values for a value chain */
859 /*------------------------------------------------------------------*/
861 reverseVal (value * val)
863 value *prev, *curr, *next;
878 val->next = (void *) NULL;
882 /*------------------------------------------------------------------*/
883 /* copyValueChain - will copy a chain of values */
884 /*------------------------------------------------------------------*/
886 copyValueChain (value * src)
893 dest = copyValue (src);
894 dest->next = copyValueChain (src->next);
899 /*------------------------------------------------------------------*/
900 /* copyValue - copies contents of a value to a fresh one */
901 /*------------------------------------------------------------------*/
903 copyValue (value * src)
908 dest->sym = copySymbol (src->sym);
909 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
910 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
911 dest->etype = (src->type ? getSpec (dest->type) : NULL);
916 /*------------------------------------------------------------------*/
917 /* charVal - converts a character constant to a value */
918 /*------------------------------------------------------------------*/
920 charVal (const char *s)
926 val->type = val->etype = newLink (SPECIFIER);
927 SPEC_NOUN (val->type) = V_CHAR;
928 SPEC_USIGN(val->type) = 1;
929 SPEC_SCLS (val->type) = S_LITERAL;
931 s++; /* get rid of quotation */
932 /* if \ then special processing */
935 s++; /* go beyond the backslash */
939 SPEC_CVAL (val->type).v_uint = '\n';
942 SPEC_CVAL (val->type).v_uint = '\t';
945 SPEC_CVAL (val->type).v_uint = '\v';
948 SPEC_CVAL (val->type).v_uint = '\b';
951 SPEC_CVAL (val->type).v_uint = '\r';
954 SPEC_CVAL (val->type).v_uint = '\f';
957 SPEC_CVAL (val->type).v_uint = '\a';
960 SPEC_CVAL (val->type).v_uint = '\\';
963 SPEC_CVAL (val->type).v_uint = '\?';
966 SPEC_CVAL (val->type).v_uint = '\'';
969 SPEC_CVAL (val->type).v_uint = '\"';
980 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
984 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
988 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
992 else /* not a backslash */
993 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
998 /*------------------------------------------------------------------*/
999 /* valFromType - creates a value from type given */
1000 /*------------------------------------------------------------------*/
1002 valFromType (sym_link * type)
1004 value *val = newValue ();
1005 val->type = copyLinkChain (type);
1006 val->etype = getSpec (val->type);
1010 /*------------------------------------------------------------------*/
1011 /* floatFromVal - value to double float conversion */
1012 /*------------------------------------------------------------------*/
1014 floatFromVal (value * val)
1019 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1021 werror (E_CONST_EXPECTED, val->name);
1025 /* if it is not a specifier then we can assume that */
1026 /* it will be an unsigned long */
1027 if (!IS_SPEC (val->type))
1028 return (double) SPEC_CVAL (val->etype).v_ulong;
1030 if (SPEC_NOUN (val->etype) == V_FLOAT)
1031 return (double) SPEC_CVAL (val->etype).v_float;
1033 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1034 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1036 if (SPEC_LONG (val->etype))
1038 if (SPEC_USIGN (val->etype))
1039 return (double) SPEC_CVAL (val->etype).v_ulong;
1041 return (double) SPEC_CVAL (val->etype).v_long;
1044 if (SPEC_NOUN (val->etype) == V_INT) {
1045 if (SPEC_USIGN (val->etype))
1046 return (double) SPEC_CVAL (val->etype).v_uint;
1048 return (double) SPEC_CVAL (val->etype).v_int;
1051 if (SPEC_NOUN (val->etype) == V_CHAR) {
1052 if (SPEC_USIGN (val->etype))
1053 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1055 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1058 if (IS_BITVAR(val->etype)) {
1059 return (double) SPEC_CVAL (val->etype).v_uint;
1062 if (SPEC_NOUN (val->etype) == V_VOID) {
1063 return (double) SPEC_CVAL (val->etype).v_ulong;
1067 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1068 "floatFromVal: unknown value");
1072 /*-----------------------------------------------------------------*/
1073 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1074 /*-----------------------------------------------------------------*/
1075 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1078 /* This version is incorrect negative values. */
1079 double tmp=0, exp=2;
1081 tmp = (value & 0xffff0000) >> 16;
1085 if(value & 0x8000)tmp += 1/exp;
1092 return ((double)(value * 1.0) / (double)(1UL << 16));
1096 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1099 /* This version is incorrect negative values. */
1100 unsigned int tmp=0, pos=16;
1101 TYPE_TARGET_ULONG res;
1103 tmp = floor( value );
1110 if(value >= 1.0)tmp |= (1 << pos);
1111 value -= floor( value );
1118 return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
1122 /*------------------------------------------------------------------*/
1123 /* valUnaryPM - does the unary +/- operation on a constant */
1124 /*------------------------------------------------------------------*/
1126 valUnaryPM (value * val)
1128 /* depending on type */
1129 if (SPEC_NOUN (val->etype) == V_FLOAT)
1130 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1131 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1132 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1135 if (SPEC_LONG (val->etype))
1137 if (SPEC_USIGN (val->etype))
1138 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1140 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1144 if (SPEC_USIGN (val->etype))
1145 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1147 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1149 if (SPEC_NOUN(val->etype) == V_CHAR)
1151 /* promote to 'signed int', cheapestVal() might reduce it again */
1152 SPEC_USIGN(val->etype) = 0;
1153 SPEC_NOUN(val->etype) = V_INT;
1155 return cheapestVal (val);
1161 /*------------------------------------------------------------------*/
1162 /* valueComplement - complements a constant */
1163 /*------------------------------------------------------------------*/
1165 valComplement (value * val)
1167 /* depending on type */
1168 if (SPEC_LONG (val->etype))
1170 if (SPEC_USIGN (val->etype))
1171 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1173 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1177 if (SPEC_USIGN (val->etype))
1178 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1180 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1182 if (SPEC_NOUN(val->etype) == V_CHAR)
1184 /* promote to 'signed int', cheapestVal() might reduce it again */
1185 SPEC_USIGN(val->etype) = 0;
1186 SPEC_NOUN(val->etype) = V_INT;
1188 return cheapestVal (val);
1193 /*------------------------------------------------------------------*/
1194 /* valueNot - complements a constant */
1195 /*------------------------------------------------------------------*/
1197 valNot (value * val)
1199 /* depending on type */
1200 if (SPEC_LONG (val->etype))
1202 if (SPEC_USIGN (val->etype))
1203 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1205 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1209 if (SPEC_USIGN (val->etype))
1210 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1212 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1215 /* ANSI: result type is int, value is 0 or 1 */
1216 /* sdcc will hold this in an 'unsigned char' */
1217 SPEC_USIGN(val->etype) = 1;
1218 SPEC_LONG (val->etype) = 0;
1219 SPEC_NOUN(val->etype) = V_CHAR;
1223 /*------------------------------------------------------------------*/
1224 /* valMult - multiply constants */
1225 /*------------------------------------------------------------------*/
1227 valMult (value * lval, value * rval)
1231 /* create a new value */
1233 val->type = val->etype = computeType (lval->etype,
1237 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1239 if (IS_FLOAT (val->type))
1240 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1242 if (IS_FIXED16X16 (val->type))
1243 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1244 /* signed and unsigned mul are the same, as long as the precision of the
1245 result isn't bigger than the precision of the operands. */
1246 else if (SPEC_LONG (val->type))
1247 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
1248 (TYPE_TARGET_ULONG) floatFromVal (rval);
1249 else if (SPEC_USIGN (val->type)) /* unsigned int */
1251 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
1252 (TYPE_TARGET_UINT) floatFromVal (rval);
1254 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1255 if (ul != (TYPE_TARGET_UINT) ul)
1258 else /* signed int */
1260 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1261 (TYPE_TARGET_INT) floatFromVal (rval);
1263 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1264 if (l != (TYPE_TARGET_INT) l)
1267 return cheapestVal (val);
1270 /*------------------------------------------------------------------*/
1271 /* valDiv - Divide constants */
1272 /*------------------------------------------------------------------*/
1274 valDiv (value * lval, value * rval)
1278 if (floatFromVal (rval) == 0)
1280 werror (E_DIVIDE_BY_ZERO);
1284 /* create a new value */
1286 val->type = val->etype = computeType (lval->etype,
1290 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1292 if (IS_FLOAT (val->type))
1293 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1295 if (IS_FIXED16X16 (val->type))
1296 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1297 else if (SPEC_LONG (val->type))
1299 if (SPEC_USIGN (val->type))
1300 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
1301 (TYPE_TARGET_ULONG) floatFromVal (rval);
1303 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
1304 (TYPE_TARGET_LONG) floatFromVal (rval);
1308 if (SPEC_USIGN (val->type))
1309 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
1310 (TYPE_TARGET_UINT) floatFromVal (rval);
1312 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
1313 (TYPE_TARGET_INT) floatFromVal (rval);
1315 return cheapestVal (val);
1318 /*------------------------------------------------------------------*/
1319 /* valMod - Modulus constants */
1320 /*------------------------------------------------------------------*/
1322 valMod (value * lval, value * rval)
1326 /* create a new value */
1328 val->type = val->etype = computeType (lval->etype,
1332 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1334 if (SPEC_LONG (val->type))
1336 if (SPEC_USIGN (val->type))
1337 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
1338 (TYPE_TARGET_ULONG) floatFromVal (rval);
1340 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
1341 (TYPE_TARGET_LONG) floatFromVal (rval);
1345 if (SPEC_USIGN (val->type))
1346 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
1347 (TYPE_TARGET_UINT) floatFromVal (rval);
1349 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
1350 (TYPE_TARGET_INT) floatFromVal (rval);
1352 return cheapestVal (val);
1355 /*------------------------------------------------------------------*/
1356 /* valPlus - Addition constants */
1357 /*------------------------------------------------------------------*/
1359 valPlus (value * lval, value * rval)
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);
1374 if (IS_FIXED16X16 (val->type))
1375 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1376 else if (SPEC_LONG (val->type))
1378 if (SPEC_USIGN (val->type))
1379 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
1380 (TYPE_TARGET_ULONG) floatFromVal (rval);
1382 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
1383 (TYPE_TARGET_LONG) floatFromVal (rval);
1387 if (SPEC_USIGN (val->type))
1388 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
1389 (TYPE_TARGET_UINT) floatFromVal (rval);
1391 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
1392 (TYPE_TARGET_INT) floatFromVal (rval);
1394 return cheapestVal (val);
1397 /*------------------------------------------------------------------*/
1398 /* valMinus - Addition constants */
1399 /*------------------------------------------------------------------*/
1401 valMinus (value * lval, value * rval)
1405 /* create a new value */
1407 val->type = val->etype = computeType (lval->etype,
1411 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1413 if (IS_FLOAT (val->type))
1414 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1416 if (IS_FIXED16X16 (val->type))
1417 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1418 else if (SPEC_LONG (val->type))
1420 if (SPEC_USIGN (val->type))
1421 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
1422 (TYPE_TARGET_ULONG) floatFromVal (rval);
1424 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
1425 (TYPE_TARGET_LONG) floatFromVal (rval);
1429 if (SPEC_USIGN (val->type))
1430 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
1431 (TYPE_TARGET_UINT) floatFromVal (rval);
1433 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
1434 (TYPE_TARGET_INT) floatFromVal (rval);
1436 return cheapestVal (val);
1439 /*------------------------------------------------------------------*/
1440 /* valShift - Shift left or right */
1441 /*------------------------------------------------------------------*/
1443 valShift (value * lval, value * rval, int lr)
1447 /* create a new value */
1449 val->type = val->etype = computeType (lval->etype,
1453 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1455 if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
1458 /* right shift and unsigned */
1459 (!lr && SPEC_USIGN (rval->type))))
1461 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1464 if (SPEC_LONG (val->type))
1466 if (SPEC_USIGN (val->type))
1468 SPEC_CVAL (val->type).v_ulong = lr ?
1469 (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1470 (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1474 SPEC_CVAL (val->type).v_long = lr ?
1475 (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1476 (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1481 if (SPEC_USIGN (val->type))
1483 SPEC_CVAL (val->type).v_uint = lr ?
1484 (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1485 (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1489 SPEC_CVAL (val->type).v_int = lr ?
1490 (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1491 (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1494 return cheapestVal (val);
1497 /*------------------------------------------------------------------*/
1498 /* valCompare- Compares two literal */
1499 /*------------------------------------------------------------------*/
1501 valCompare (value * lval, value * rval, int ctype)
1505 /* create a new value */
1507 val->type = val->etype = newCharLink ();
1508 val->type->class = SPECIFIER;
1509 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1510 SPEC_USIGN (val->type) = 1;
1511 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1516 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1520 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1524 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1528 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1532 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1533 SPEC_NOUN(rval->type) == V_FLOAT)
1535 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1538 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1539 SPEC_NOUN(rval->type) == V_FIXED16X16)
1541 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1545 /* integrals: ignore signedness */
1546 TYPE_TARGET_ULONG l, r;
1548 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1549 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1550 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1551 neccessary to strip them to 16 bit.
1552 Literals are reduced to their cheapest type, therefore left and
1553 right might have different types. It's neccessary to find a
1554 common type: int (used for char too) or long */
1555 if (!IS_LONG (lval->etype) &&
1556 !IS_LONG (rval->etype))
1558 r = (TYPE_TARGET_UINT) r;
1559 l = (TYPE_TARGET_UINT) l;
1561 SPEC_CVAL (val->type).v_int = l == r;
1565 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1566 SPEC_NOUN(rval->type) == V_FLOAT)
1568 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1571 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1572 SPEC_NOUN(rval->type) == V_FIXED16X16)
1574 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1578 /* integrals: ignore signedness */
1579 TYPE_TARGET_ULONG l, r;
1581 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1582 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1583 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1584 neccessary to strip them to 16 bit.
1585 Literals are reduced to their cheapest type, therefore left and
1586 right might have different types. It's neccessary to find a
1587 common type: int (used for char too) or long */
1588 if (!IS_LONG (lval->etype) &&
1589 !IS_LONG (rval->etype))
1591 r = (TYPE_TARGET_UINT) r;
1592 l = (TYPE_TARGET_UINT) l;
1594 SPEC_CVAL (val->type).v_int = l != r;
1603 /*------------------------------------------------------------------*/
1604 /* valBitwise - Bitwise operation */
1605 /*------------------------------------------------------------------*/
1607 valBitwise (value * lval, value * rval, int op)
1611 /* create a new value */
1613 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1614 val->etype = getSpec (val->type);
1615 SPEC_SCLS (val->etype) = S_LITERAL;
1620 if (SPEC_LONG (val->type))
1622 if (SPEC_USIGN (val->type))
1623 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
1624 (TYPE_TARGET_ULONG) floatFromVal (rval);
1626 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
1627 (TYPE_TARGET_LONG) floatFromVal (rval);
1631 if (SPEC_USIGN (val->type))
1632 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
1633 (TYPE_TARGET_UINT) floatFromVal (rval);
1635 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
1636 (TYPE_TARGET_INT) floatFromVal (rval);
1641 if (SPEC_LONG (val->type))
1643 if (SPEC_USIGN (val->type))
1644 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
1645 (TYPE_TARGET_ULONG) floatFromVal (rval);
1647 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
1648 (TYPE_TARGET_LONG) floatFromVal (rval);
1652 if (SPEC_USIGN (val->type))
1653 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
1654 (TYPE_TARGET_UINT) floatFromVal (rval);
1656 SPEC_CVAL (val->type).v_int =
1657 (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
1663 if (SPEC_LONG (val->type))
1665 if (SPEC_USIGN (val->type))
1666 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
1667 (TYPE_TARGET_ULONG) floatFromVal (rval);
1669 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
1670 (TYPE_TARGET_LONG) floatFromVal (rval);
1674 if (SPEC_USIGN (val->type))
1675 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
1676 (TYPE_TARGET_UINT) floatFromVal (rval);
1678 SPEC_CVAL (val->type).v_int =
1679 (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
1684 return cheapestVal(val);
1687 /*------------------------------------------------------------------*/
1688 /* valAndOr - Generates code for and / or operation */
1689 /*------------------------------------------------------------------*/
1691 valLogicAndOr (value * lval, value * rval, int op)
1695 /* create a new value */
1697 val->type = val->etype = newCharLink ();
1698 val->type->class = SPECIFIER;
1699 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1700 SPEC_USIGN (val->type) = 1;
1705 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1709 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1717 /*------------------------------------------------------------------*/
1718 /* valCastLiteral - casts a literal value to another type */
1719 /*------------------------------------------------------------------*/
1721 valCastLiteral (sym_link * dtype, double fval)
1724 TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
1731 val->etype = getSpec (val->type = copyLinkChain (dtype));
1734 val->etype = val->type = newLink (SPECIFIER);
1735 SPEC_NOUN (val->etype) = V_VOID;
1737 SPEC_SCLS (val->etype) = S_LITERAL;
1739 /* if it is not a specifier then we can assume that */
1740 /* it will be an unsigned long */
1741 if (!IS_SPEC (val->type)) {
1742 SPEC_CVAL (val->etype).v_ulong = l;
1746 if (SPEC_NOUN (val->etype) == V_FLOAT)
1747 SPEC_CVAL (val->etype).v_float = fval;
1748 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1749 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1750 else if (SPEC_NOUN (val->etype) == V_BIT ||
1751 SPEC_NOUN (val->etype) == V_SBIT)
1752 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1753 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1754 SPEC_CVAL (val->etype).v_uint = l &
1755 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1756 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1757 if (SPEC_USIGN (val->etype))
1758 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1760 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1762 if (SPEC_LONG (val->etype)) {
1763 if (SPEC_USIGN (val->etype))
1764 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1766 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1768 if (SPEC_USIGN (val->etype))
1769 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
1771 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
1777 /*------------------------------------------------------------------*/
1778 /* getNelements - determines # of elements from init list */
1779 /*------------------------------------------------------------------*/
1781 getNelements (sym_link * type, initList * ilist)
1788 if (ilist->type == INIT_DEEP)
1789 ilist = ilist->init.deep;
1791 /* if type is a character array and there is only one
1792 (string) initialiser then get the length of the string */
1793 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1795 ast *iast = ilist->init.node;
1796 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1799 werror (E_CONST_EXPECTED);
1803 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1804 // yep, it's a string
1806 return DCL_ELEM (v->type);
1814 ilist = ilist->next;
1819 /*-----------------------------------------------------------------*/
1820 /* valForArray - returns a value with name of array index */
1821 /*-----------------------------------------------------------------*/
1823 valForArray (ast * arrExpr)
1825 value *val, *lval = NULL;
1827 int size = getSize (arrExpr->left->ftype->next);
1828 /* if the right or left is an array
1830 if (IS_AST_OP (arrExpr->left))
1832 if (arrExpr->left->opval.op == '[')
1833 lval = valForArray (arrExpr->left);
1834 else if (arrExpr->left->opval.op == '.')
1835 lval = valForStructElem (arrExpr->left->left,
1836 arrExpr->left->right);
1837 else if (arrExpr->left->opval.op == PTR_OP &&
1838 IS_ADDRESS_OF_OP (arrExpr->left->left))
1839 lval = valForStructElem (arrExpr->left->left->left,
1840 arrExpr->left->right);
1845 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1848 if (!IS_AST_LIT_VALUE (arrExpr->right))
1854 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1858 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1861 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1862 (int) AST_LIT_VALUE (arrExpr->right) * size);
1864 val->type = newLink (DECLARATOR);
1865 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1866 DCL_TYPE (val->type) = CPOINTER;
1867 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1868 DCL_TYPE (val->type) = FPOINTER;
1869 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1870 DCL_TYPE (val->type) = PPOINTER;
1871 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1872 DCL_TYPE (val->type) = IPOINTER;
1873 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1874 DCL_TYPE (val->type) = EEPPOINTER;
1876 DCL_TYPE (val->type) = POINTER;
1877 val->type->next = arrExpr->left->ftype->next;
1878 val->etype = getSpec (val->type);
1882 /*-----------------------------------------------------------------*/
1883 /* valForStructElem - returns value with name of struct element */
1884 /*-----------------------------------------------------------------*/
1886 valForStructElem (ast * structT, ast * elemT)
1888 value *val, *lval = NULL;
1892 /* left could be furthur derefed */
1893 if (IS_AST_OP (structT))
1895 if (structT->opval.op == '[')
1896 lval = valForArray (structT);
1897 else if (structT->opval.op == '.')
1898 lval = valForStructElem (structT->left, structT->right);
1899 else if (structT->opval.op == PTR_OP &&
1900 IS_ADDRESS_OF_OP (structT->left))
1901 lval = valForStructElem (structT->left->left,
1907 if (!IS_AST_SYM_VALUE (elemT))
1910 if (!IS_STRUCT (structT->etype))
1913 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1914 AST_SYMBOL (elemT))) == NULL)
1922 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1926 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1929 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1932 val->type = newLink (DECLARATOR);
1933 if (SPEC_SCLS (structT->etype) == S_CODE)
1934 DCL_TYPE (val->type) = CPOINTER;
1935 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1936 DCL_TYPE (val->type) = FPOINTER;
1937 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1938 DCL_TYPE (val->type) = PPOINTER;
1939 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1940 DCL_TYPE (val->type) = IPOINTER;
1941 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1942 DCL_TYPE (val->type) = EEPPOINTER;
1944 DCL_TYPE (val->type) = POINTER;
1945 val->type->next = sym->type;
1946 val->etype = getSpec (val->type);
1950 /*-----------------------------------------------------------------*/
1951 /* valForCastAggr - will return value for a cast of an aggregate */
1952 /* plus minus a constant */
1953 /*-----------------------------------------------------------------*/
1955 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1959 if (!IS_AST_SYM_VALUE (aexpr))
1961 if (!IS_AST_LIT_VALUE (cnst))
1966 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1967 AST_SYMBOL (aexpr)->rname, op,
1968 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1971 val->etype = getSpec (val->type);
1975 /*-----------------------------------------------------------------*/
1976 /* valForCastAggr - will return value for a cast of an aggregate */
1977 /* with no constant */
1978 /*-----------------------------------------------------------------*/
1980 valForCastArr (ast * aexpr, sym_link * type)
1984 if (!IS_AST_SYM_VALUE (aexpr))
1989 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1990 AST_SYMBOL (aexpr)->rname);
1993 val->etype = getSpec (val->type);