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 RESULT_TYPE resultType;
281 if (ilist->type == INIT_NODE)
284 resultType = RESULT_TYPE_INT;
286 resultType = getResultTypeFromType (getSpec (type));
287 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
291 if (ilist->type == INIT_DEEP)
292 resolveIvalSym (ilist->init.deep, type);
294 resolveIvalSym (ilist->next, type);
297 /*-----------------------------------------------------------------*/
298 /* symbolVal - creates a value for a symbol */
299 /*-----------------------------------------------------------------*/
301 symbolVal (symbol * sym)
313 val->type = sym->type;
314 val->etype = getSpec (val->type);
319 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
323 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
329 /*--------------------------------------------------------------------*/
330 /* cheapestVal - try to reduce 'signed int' to 'char' */
331 /*--------------------------------------------------------------------*/
333 cheapestVal (value *val)
335 /* only int can be reduced */
336 if (!IS_INT(val->type))
339 /* long must not be changed */
340 if (SPEC_LONG(val->type))
343 /* unsigned must not be changed */
344 if (SPEC_USIGN(val->type))
347 /* the only possible reduction is from signed int to (un)signed char,
348 because it's automatically promoted back to signed int.
350 a reduction from unsigned int to unsigned char is a bug,
351 because an _unsigned_ char is promoted to _signed_ int! */
352 if (SPEC_CVAL(val->type).v_int < -128 ||
353 SPEC_CVAL(val->type).v_int > 255)
355 /* not in the range of (un)signed char */
359 SPEC_NOUN(val->type) = V_CHAR;
361 /* 'unsigned char' promotes to 'signed int', so that we can
362 reduce it the other way */
363 if (SPEC_CVAL(val->type).v_int >= 0)
365 SPEC_USIGN(val->type) = 1;
370 /*--------------------------------------------------------------------*/
371 /* checkConstantRange - check if constant fits in numeric range of */
372 /* var type in comparisons and assignments */
373 /*--------------------------------------------------------------------*/
375 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
381 litVal = floatFromVal (valFromType (lit));
382 varBits = bitsForType (var);
389 return CCR_ALWAYS_FALSE;
391 return CCR_ALWAYS_TRUE;
393 /* special: assignment */
399 if (getenv ("SDCC_VERY_PEDANTIC"))
401 if (SPEC_USIGN (var))
403 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
412 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
413 TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
423 /* ignore signedness, e.g. allow everything
424 from -127...+255 for (unsigned) char */
425 TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
426 TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
435 if (exchangeLeftRight)
440 case '>': op = '<'; break;
441 case GE_OP: op = LE_OP; break;
442 case '<': op = '>'; break;
443 case LE_OP: op = GE_OP; break;
444 default: return CCR_ALWAYS_FALSE;
447 reType = computeType (var, lit, RESULT_TYPE_NONE, op);
449 if (SPEC_USIGN (reType))
451 /* unsigned operation */
452 TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
453 TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
455 if (SPEC_USIGN (lit) && SPEC_USIGN (var))
457 /* both operands are unsigned, this is easy */
459 maxValP = 0xffffffffu >> (32 - varBits);
460 /* there's only range, just copy it to 2nd set */
464 else if (SPEC_USIGN (var))
466 /* lit is casted from signed to unsigned, e.g.:
472 maxValP = 0xffffffffu >> (32 - varBits);
473 /* there's only one range, just copy it to 2nd set */
477 /* it's an unsigned operation */
478 if ( IS_CHAR (reType)
481 /* make signed literal unsigned and
482 limit no of bits to size of return type */
483 litVal = (TYPE_TARGET_ULONG) litVal & opBitsMask;
486 else /* SPEC_USIGN (lit) */
488 /* var is casted from signed to unsigned, e.g.:
493 The possible values after casting var
494 split up in two, nonconsecutive ranges:
496 minValP = 0; positive range: 0...127
498 minValM = 0xff80; negative range: -128...-1
504 maxValP = 0x7fffffffu >> (32 - varBits);
507 minValM = 0xffffffff << (varBits - 1);
508 maxValM = 0xffffffffu; /* -1 */
509 /* limit no of bits to size of return type */
510 minValM &= opBitsMask;
511 maxValM &= opBitsMask;
516 case EQ_OP: /* var == lit */
517 if ( litVal <= maxValP
518 && litVal >= minValP) /* 0 */
520 if ( litVal <= maxValM
521 && litVal >= minValM)
523 return CCR_ALWAYS_FALSE;
524 case NE_OP: /* var != lit */
525 if ( litVal <= maxValP
526 && litVal >= minValP) /* 0 */
528 if ( litVal <= maxValM
529 && litVal >= minValM)
531 return CCR_ALWAYS_TRUE;
532 case '>': /* var > lit */
533 if (litVal >= maxValM)
534 return CCR_ALWAYS_FALSE;
535 if (litVal < minValP) /* 0 */
536 return CCR_ALWAYS_TRUE;
538 case GE_OP: /* var >= lit */
539 if (litVal > maxValM)
540 return CCR_ALWAYS_FALSE;
541 if (litVal <= minValP) /* 0 */
542 return CCR_ALWAYS_TRUE;
544 case '<': /* var < lit */
545 if (litVal > maxValM)
546 return CCR_ALWAYS_TRUE;
547 if (litVal <= minValP) /* 0 */
548 return CCR_ALWAYS_FALSE;
550 case LE_OP: /* var <= lit */
551 if (litVal >= maxValM)
552 return CCR_ALWAYS_TRUE;
553 if (litVal < minValP) /* 0 */
554 return CCR_ALWAYS_FALSE;
557 return CCR_ALWAYS_FALSE;
562 /* signed operation */
563 TYPE_TARGET_LONG minVal, maxVal;
565 if (SPEC_USIGN (var))
567 /* unsigned var, but signed operation. This happens
568 when var is promoted to signed int.
569 Set actual min/max values of var. */
571 maxVal = 0xffffffff >> (32 - varBits);
576 minVal = 0xffffffff << (varBits - 1);
577 maxVal = 0x7fffffff >> (32 - varBits);
582 case EQ_OP: /* var == lit */
585 return CCR_ALWAYS_FALSE;
587 case NE_OP: /* var != lit */
590 return CCR_ALWAYS_TRUE;
592 case '>': /* var > lit */
593 if (litVal >= maxVal)
594 return CCR_ALWAYS_FALSE;
596 return CCR_ALWAYS_TRUE;
598 case GE_OP: /* var >= lit */
600 return CCR_ALWAYS_FALSE;
601 if (litVal <= minVal)
602 return CCR_ALWAYS_TRUE;
604 case '<': /* var < lit */
606 return CCR_ALWAYS_TRUE;
607 if (litVal <= minVal)
608 return CCR_ALWAYS_FALSE;
610 case LE_OP: /* var <= lit */
611 if (litVal >= maxVal)
612 return CCR_ALWAYS_TRUE;
614 return CCR_ALWAYS_FALSE;
617 return CCR_ALWAYS_FALSE;
622 /*-----------------------------------------------------------------*/
623 /* valueFromLit - creates a value from a literal */
624 /*-----------------------------------------------------------------*/
626 valueFromLit (double lit)
630 if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
632 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
633 return constVal (buffer);
636 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
637 return constFloatVal (buffer);
640 /*-----------------------------------------------------------------*/
641 /* constFloatVal - converts a FLOAT constant to value */
642 /*-----------------------------------------------------------------*/
644 constFloatVal (char *s)
646 value *val = newValue ();
649 if (sscanf (s, "%lf", &sval) != 1)
651 werror (E_INVALID_FLOAT_CONST, s);
652 return constVal ("0");
655 val->type = val->etype = newLink (SPECIFIER);
656 SPEC_NOUN (val->type) = V_FLOAT;
657 SPEC_SCLS (val->type) = S_LITERAL;
658 SPEC_CVAL (val->type).v_float = sval;
663 /*-----------------------------------------------------------------*/
664 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
665 /*-----------------------------------------------------------------*/
667 constFixed16x16Val (char *s)
669 value *val = newValue ();
672 if (sscanf (s, "%lf", &sval) != 1)
674 werror (E_INVALID_FLOAT_CONST, s);
675 return constVal ("0");
678 val->type = val->etype = newLink (SPECIFIER);
679 SPEC_NOUN (val->type) = V_FLOAT;
680 SPEC_SCLS (val->type) = S_LITERAL;
681 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
686 /*-----------------------------------------------------------------*/
687 /* constVal - converts an INTEGER constant into a cheapest value */
688 /*-----------------------------------------------------------------*/
689 value *constVal (const char *s)
692 short hex = 0, octal = 0;
695 val = newValue (); /* alloc space for value */
697 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
698 SPEC_SCLS (val->type) = S_LITERAL;
699 // let's start with a signed char
700 SPEC_NOUN (val->type) = V_CHAR;
701 SPEC_USIGN (val->type) = 0;
703 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
705 /* set the octal flag */
706 if (!hex && *s == '0' && *(s + 1))
712 sval = strtoul (s, NULL, 0);
716 werror (W_INVALID_INT_CONST, s, dval);
719 sscanf (s, "%lf", &dval);
722 /* Setup the flags first */
723 /* set the unsigned flag if 'uU' is found */
724 if (strchr (s, 'u') || strchr (s, 'U')) {
725 SPEC_USIGN (val->type) = 1;
728 /* set the b_long flag if 'lL' is found */
729 if (strchr (s, 'l') || strchr (s, 'L')) {
730 SPEC_NOUN (val->type) = V_INT;
731 SPEC_LONG (val->type) = 1;
733 if (dval<0) { // "-28u" will still be signed and negative
734 if (dval<-128) { // check if we have to promote to int
735 SPEC_NOUN (val->type) = V_INT;
737 if (dval<-32768) { // check if we have to promote to long int
738 SPEC_LONG (val->type) = 1;
741 if (dval>0xff || /* check if we have to promote to int */
742 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
743 char. After an integral promotion it will
744 be a signed int; this certainly isn't what
745 the programer wants */
746 SPEC_NOUN (val->type) = V_INT;
748 else { /* store char's always as unsigned; this helps other optimizations */
749 SPEC_USIGN (val->type) = 1;
751 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
752 SPEC_LONG (val->type) = 1;
754 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
755 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
757 SPEC_USIGN (val->type) = 1;
759 SPEC_LONG (val->type) = 1;
760 if (dval>0x7fffffff) {
761 SPEC_USIGN (val->type) = 1;
768 /* check for out of range */
769 if (dval<-2147483648.0) {
770 dval = -2147483648.0;
771 werror (W_INVALID_INT_CONST, s, dval);
773 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
775 werror (W_INVALID_INT_CONST, s, dval);
777 if (dval>4294967295.0) {
779 werror (W_INVALID_INT_CONST, s, dval);
782 if (SPEC_LONG (val->type))
784 if (SPEC_USIGN (val->type))
786 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG)dval;
790 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG)dval;
795 if (SPEC_USIGN (val->type))
797 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT)dval;
801 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT)dval;
808 /*------------------------------------------------------------------*/
809 /* strVal - converts a string constant to a value */
810 /*------------------------------------------------------------------*/
812 strVal (const char *s)
816 val = newValue (); /* get a new one */
818 /* get a declarator */
819 val->type = newLink (DECLARATOR);
820 DCL_TYPE (val->type) = ARRAY;
821 val->type->next = val->etype = newLink (SPECIFIER);
822 SPEC_NOUN (val->etype) = V_CHAR;
823 SPEC_SCLS (val->etype) = S_LITERAL;
825 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
826 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
832 /*------------------------------------------------------------------*/
833 /* reverseValWithType - reverses value chain with type & etype */
834 /*------------------------------------------------------------------*/
836 reverseValWithType (value * val)
844 /* save the type * etype chains */
848 /* set the current one 2b null */
849 val->type = val->etype = NULL;
850 val = reverseVal (val);
852 /* restore type & etype */
859 /*------------------------------------------------------------------*/
860 /* reverseVal - reverses the values for a value chain */
861 /*------------------------------------------------------------------*/
863 reverseVal (value * val)
865 value *prev, *curr, *next;
880 val->next = (void *) NULL;
884 /*------------------------------------------------------------------*/
885 /* copyValueChain - will copy a chain of values */
886 /*------------------------------------------------------------------*/
888 copyValueChain (value * src)
895 dest = copyValue (src);
896 dest->next = copyValueChain (src->next);
901 /*------------------------------------------------------------------*/
902 /* copyValue - copies contents of a value to a fresh one */
903 /*------------------------------------------------------------------*/
905 copyValue (value * src)
910 dest->sym = copySymbol (src->sym);
911 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
912 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
913 dest->etype = (src->type ? getSpec (dest->type) : NULL);
918 /*------------------------------------------------------------------*/
919 /* charVal - converts a character constant to a value */
920 /*------------------------------------------------------------------*/
922 charVal (const char *s)
928 val->type = val->etype = newLink (SPECIFIER);
929 SPEC_NOUN (val->type) = V_CHAR;
930 SPEC_USIGN(val->type) = 1;
931 SPEC_SCLS (val->type) = S_LITERAL;
933 s++; /* get rid of quotation */
934 /* if \ then special processing */
937 s++; /* go beyond the backslash */
941 SPEC_CVAL (val->type).v_uint = '\n';
944 SPEC_CVAL (val->type).v_uint = '\t';
947 SPEC_CVAL (val->type).v_uint = '\v';
950 SPEC_CVAL (val->type).v_uint = '\b';
953 SPEC_CVAL (val->type).v_uint = '\r';
956 SPEC_CVAL (val->type).v_uint = '\f';
959 SPEC_CVAL (val->type).v_uint = '\a';
962 SPEC_CVAL (val->type).v_uint = '\\';
965 SPEC_CVAL (val->type).v_uint = '\?';
968 SPEC_CVAL (val->type).v_uint = '\'';
971 SPEC_CVAL (val->type).v_uint = '\"';
982 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
986 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
990 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
994 else /* not a backslash */
995 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
1000 /*------------------------------------------------------------------*/
1001 /* valFromType - creates a value from type given */
1002 /*------------------------------------------------------------------*/
1004 valFromType (sym_link * type)
1006 value *val = newValue ();
1007 val->type = copyLinkChain (type);
1008 val->etype = getSpec (val->type);
1012 /*------------------------------------------------------------------*/
1013 /* floatFromVal - value to double float conversion */
1014 /*------------------------------------------------------------------*/
1016 floatFromVal (value * val)
1021 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1023 werror (E_CONST_EXPECTED, val->name);
1027 /* if it is not a specifier then we can assume that */
1028 /* it will be an unsigned long */
1029 if (!IS_SPEC (val->type))
1030 return (double) SPEC_CVAL (val->etype).v_ulong;
1032 if (SPEC_NOUN (val->etype) == V_FLOAT)
1033 return (double) SPEC_CVAL (val->etype).v_float;
1035 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1036 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1038 if (SPEC_LONG (val->etype))
1040 if (SPEC_USIGN (val->etype))
1041 return (double) SPEC_CVAL (val->etype).v_ulong;
1043 return (double) SPEC_CVAL (val->etype).v_long;
1046 if (SPEC_NOUN (val->etype) == V_INT) {
1047 if (SPEC_USIGN (val->etype))
1048 return (double) SPEC_CVAL (val->etype).v_uint;
1050 return (double) SPEC_CVAL (val->etype).v_int;
1053 if (SPEC_NOUN (val->etype) == V_CHAR) {
1054 if (SPEC_USIGN (val->etype))
1055 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1057 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1060 if (IS_BITVAR(val->etype)) {
1061 return (double) SPEC_CVAL (val->etype).v_uint;
1064 if (SPEC_NOUN (val->etype) == V_VOID) {
1065 return (double) SPEC_CVAL (val->etype).v_ulong;
1069 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1070 "floatFromVal: unknown value");
1074 /*-----------------------------------------------------------------*/
1075 /* doubleFromFixed16x16 - convert a fixed16x16 to double */
1076 /*-----------------------------------------------------------------*/
1077 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1080 /* This version is incorrect negative values. */
1081 double tmp=0, exp=2;
1083 tmp = (value & 0xffff0000) >> 16;
1087 if(value & 0x8000)tmp += 1/exp;
1094 return ((double)(value * 1.0) / (double)(1UL << 16));
1098 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1101 /* This version is incorrect negative values. */
1102 unsigned int tmp=0, pos=16;
1103 TYPE_TARGET_ULONG res;
1105 tmp = floor( value );
1112 if(value >= 1.0)tmp |= (1 << pos);
1113 value -= floor( value );
1120 return (TYPE_TARGET_ULONG)(value * (double)(1UL << 16));
1124 /*------------------------------------------------------------------*/
1125 /* valUnaryPM - does the unary +/- operation on a constant */
1126 /*------------------------------------------------------------------*/
1128 valUnaryPM (value * val)
1130 /* depending on type */
1131 if (SPEC_NOUN (val->etype) == V_FLOAT)
1132 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1133 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1134 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1137 if (SPEC_LONG (val->etype))
1139 if (SPEC_USIGN (val->etype))
1140 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1142 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1146 if (SPEC_USIGN (val->etype))
1147 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1149 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1151 if (SPEC_NOUN(val->etype) == V_CHAR)
1153 /* promote to 'signed int', cheapestVal() might reduce it again */
1154 SPEC_USIGN(val->etype) = 0;
1155 SPEC_NOUN(val->etype) = V_INT;
1157 return cheapestVal (val);
1163 /*------------------------------------------------------------------*/
1164 /* valueComplement - complements a constant */
1165 /*------------------------------------------------------------------*/
1167 valComplement (value * val)
1169 /* depending on type */
1170 if (SPEC_LONG (val->etype))
1172 if (SPEC_USIGN (val->etype))
1173 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1175 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1179 if (SPEC_USIGN (val->etype))
1180 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1182 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1184 if (SPEC_NOUN(val->etype) == V_CHAR)
1186 /* promote to 'signed int', cheapestVal() might reduce it again */
1187 SPEC_USIGN(val->etype) = 0;
1188 SPEC_NOUN(val->etype) = V_INT;
1190 return cheapestVal (val);
1195 /*------------------------------------------------------------------*/
1196 /* valueNot - complements a constant */
1197 /*------------------------------------------------------------------*/
1199 valNot (value * val)
1201 /* depending on type */
1202 if (SPEC_LONG (val->etype))
1204 if (SPEC_USIGN (val->etype))
1205 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1207 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1211 if (SPEC_USIGN (val->etype))
1212 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1214 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1217 /* ANSI: result type is int, value is 0 or 1 */
1218 /* sdcc will hold this in an 'unsigned char' */
1219 SPEC_USIGN(val->etype) = 1;
1220 SPEC_LONG (val->etype) = 0;
1221 SPEC_NOUN(val->etype) = V_CHAR;
1225 /*------------------------------------------------------------------*/
1226 /* valMult - multiply constants */
1227 /*------------------------------------------------------------------*/
1229 valMult (value * lval, value * rval)
1233 /* create a new value */
1235 val->type = val->etype = computeType (lval->etype,
1239 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1241 if (IS_FLOAT (val->type))
1242 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1244 if (IS_FIXED16X16 (val->type))
1245 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1246 /* signed and unsigned mul are the same, as long as the precision of the
1247 result isn't bigger than the precision of the operands. */
1248 else if (SPEC_LONG (val->type))
1249 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) *
1250 (TYPE_TARGET_ULONG) floatFromVal (rval);
1251 else if (SPEC_USIGN (val->type)) /* unsigned int */
1253 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) floatFromVal (lval) *
1254 (TYPE_TARGET_UINT) floatFromVal (rval);
1256 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1257 if (ul != (TYPE_TARGET_UINT) ul)
1260 else /* signed int */
1262 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1263 (TYPE_TARGET_INT) floatFromVal (rval);
1265 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1266 if (l != (TYPE_TARGET_INT) l)
1269 return cheapestVal (val);
1272 /*------------------------------------------------------------------*/
1273 /* valDiv - Divide constants */
1274 /*------------------------------------------------------------------*/
1276 valDiv (value * lval, value * rval)
1280 if (floatFromVal (rval) == 0)
1282 werror (E_DIVIDE_BY_ZERO);
1286 /* create a new value */
1288 val->type = val->etype = computeType (lval->etype,
1292 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1294 if (IS_FLOAT (val->type))
1295 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1297 if (IS_FIXED16X16 (val->type))
1298 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1299 else if (SPEC_LONG (val->type))
1301 if (SPEC_USIGN (val->type))
1302 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) /
1303 (TYPE_TARGET_ULONG) floatFromVal (rval);
1305 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) /
1306 (TYPE_TARGET_LONG) floatFromVal (rval);
1310 if (SPEC_USIGN (val->type))
1311 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) /
1312 (TYPE_TARGET_UINT) floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) /
1315 (TYPE_TARGET_INT) floatFromVal (rval);
1317 return cheapestVal (val);
1320 /*------------------------------------------------------------------*/
1321 /* valMod - Modulus constants */
1322 /*------------------------------------------------------------------*/
1324 valMod (value * lval, value * rval)
1328 /* create a new value */
1330 val->type = val->etype = computeType (lval->etype,
1334 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1336 if (SPEC_LONG (val->type))
1338 if (SPEC_USIGN (val->type))
1339 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) %
1340 (TYPE_TARGET_ULONG) floatFromVal (rval);
1342 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) %
1343 (TYPE_TARGET_LONG) floatFromVal (rval);
1347 if (SPEC_USIGN (val->type))
1348 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) %
1349 (TYPE_TARGET_UINT) floatFromVal (rval);
1351 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) %
1352 (TYPE_TARGET_INT) floatFromVal (rval);
1354 return cheapestVal (val);
1357 /*------------------------------------------------------------------*/
1358 /* valPlus - Addition constants */
1359 /*------------------------------------------------------------------*/
1361 valPlus (value * lval, value * rval)
1365 /* create a new value */
1367 val->type = val->etype = computeType (lval->etype,
1371 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1373 if (IS_FLOAT (val->type))
1374 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1376 if (IS_FIXED16X16 (val->type))
1377 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1378 else if (SPEC_LONG (val->type))
1380 if (SPEC_USIGN (val->type))
1381 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) +
1382 (TYPE_TARGET_ULONG) floatFromVal (rval);
1384 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) +
1385 (TYPE_TARGET_LONG) floatFromVal (rval);
1389 if (SPEC_USIGN (val->type))
1390 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) +
1391 (TYPE_TARGET_UINT) floatFromVal (rval);
1393 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) +
1394 (TYPE_TARGET_INT) floatFromVal (rval);
1396 return cheapestVal (val);
1399 /*------------------------------------------------------------------*/
1400 /* valMinus - Addition constants */
1401 /*------------------------------------------------------------------*/
1403 valMinus (value * lval, value * rval)
1407 /* create a new value */
1409 val->type = val->etype = computeType (lval->etype,
1413 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1415 if (IS_FLOAT (val->type))
1416 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1418 if (IS_FIXED16X16 (val->type))
1419 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1420 else if (SPEC_LONG (val->type))
1422 if (SPEC_USIGN (val->type))
1423 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) -
1424 (TYPE_TARGET_ULONG) floatFromVal (rval);
1426 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) -
1427 (TYPE_TARGET_LONG) floatFromVal (rval);
1431 if (SPEC_USIGN (val->type))
1432 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) -
1433 (TYPE_TARGET_UINT) floatFromVal (rval);
1435 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) -
1436 (TYPE_TARGET_INT) floatFromVal (rval);
1438 return cheapestVal (val);
1441 /*------------------------------------------------------------------*/
1442 /* valShift - Shift left or right */
1443 /*------------------------------------------------------------------*/
1445 valShift (value * lval, value * rval, int lr)
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 (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) floatFromVal (rval) &&
1460 /* right shift and unsigned */
1461 (!lr && SPEC_USIGN (rval->type))))
1463 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1466 if (SPEC_LONG (val->type))
1468 if (SPEC_USIGN (val->type))
1470 SPEC_CVAL (val->type).v_ulong = lr ?
1471 (TYPE_TARGET_ULONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1472 (TYPE_TARGET_ULONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1476 SPEC_CVAL (val->type).v_long = lr ?
1477 (TYPE_TARGET_LONG) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1478 (TYPE_TARGET_LONG) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1483 if (SPEC_USIGN (val->type))
1485 SPEC_CVAL (val->type).v_uint = lr ?
1486 (TYPE_TARGET_UINT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1487 (TYPE_TARGET_UINT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1491 SPEC_CVAL (val->type).v_int = lr ?
1492 (TYPE_TARGET_INT) floatFromVal (lval) << (TYPE_TARGET_ULONG) floatFromVal (rval) : \
1493 (TYPE_TARGET_INT) floatFromVal (lval) >> (TYPE_TARGET_ULONG) floatFromVal (rval);
1496 return cheapestVal (val);
1499 /*------------------------------------------------------------------*/
1500 /* valCompare- Compares two literal */
1501 /*------------------------------------------------------------------*/
1503 valCompare (value * lval, value * rval, int ctype)
1507 /* create a new value */
1509 val->type = val->etype = newCharLink ();
1510 val->type->class = SPECIFIER;
1511 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1512 SPEC_USIGN (val->type) = 1;
1513 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1518 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1522 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1526 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1530 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1534 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1535 SPEC_NOUN(rval->type) == V_FLOAT)
1537 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1540 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1541 SPEC_NOUN(rval->type) == V_FIXED16X16)
1543 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1547 /* integrals: ignore signedness */
1548 TYPE_TARGET_ULONG l, r;
1550 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1551 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1552 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1553 neccessary to strip them to 16 bit.
1554 Literals are reduced to their cheapest type, therefore left and
1555 right might have different types. It's neccessary to find a
1556 common type: int (used for char too) or long */
1557 if (!IS_LONG (lval->etype) &&
1558 !IS_LONG (rval->etype))
1560 r = (TYPE_TARGET_UINT) r;
1561 l = (TYPE_TARGET_UINT) l;
1563 SPEC_CVAL (val->type).v_int = l == r;
1567 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1568 SPEC_NOUN(rval->type) == V_FLOAT)
1570 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1573 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1574 SPEC_NOUN(rval->type) == V_FIXED16X16)
1576 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1580 /* integrals: ignore signedness */
1581 TYPE_TARGET_ULONG l, r;
1583 l = (TYPE_TARGET_ULONG) floatFromVal (lval);
1584 r = (TYPE_TARGET_ULONG) floatFromVal (rval);
1585 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1586 neccessary to strip them to 16 bit.
1587 Literals are reduced to their cheapest type, therefore left and
1588 right might have different types. It's neccessary to find a
1589 common type: int (used for char too) or long */
1590 if (!IS_LONG (lval->etype) &&
1591 !IS_LONG (rval->etype))
1593 r = (TYPE_TARGET_UINT) r;
1594 l = (TYPE_TARGET_UINT) l;
1596 SPEC_CVAL (val->type).v_int = l != r;
1605 /*------------------------------------------------------------------*/
1606 /* valBitwise - Bitwise operation */
1607 /*------------------------------------------------------------------*/
1609 valBitwise (value * lval, value * rval, int op)
1613 /* create a new value */
1615 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1616 val->etype = getSpec (val->type);
1617 SPEC_SCLS (val->etype) = S_LITERAL;
1622 if (SPEC_LONG (val->type))
1624 if (SPEC_USIGN (val->type))
1625 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) &
1626 (TYPE_TARGET_ULONG) floatFromVal (rval);
1628 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) &
1629 (TYPE_TARGET_LONG) floatFromVal (rval);
1633 if (SPEC_USIGN (val->type))
1634 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) &
1635 (TYPE_TARGET_UINT) floatFromVal (rval);
1637 SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) floatFromVal (lval) &
1638 (TYPE_TARGET_INT) floatFromVal (rval);
1643 if (SPEC_LONG (val->type))
1645 if (SPEC_USIGN (val->type))
1646 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) |
1647 (TYPE_TARGET_ULONG) floatFromVal (rval);
1649 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) |
1650 (TYPE_TARGET_LONG) floatFromVal (rval);
1654 if (SPEC_USIGN (val->type))
1655 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) |
1656 (TYPE_TARGET_UINT) floatFromVal (rval);
1658 SPEC_CVAL (val->type).v_int =
1659 (TYPE_TARGET_INT) floatFromVal (lval) | (TYPE_TARGET_INT) floatFromVal (rval);
1665 if (SPEC_LONG (val->type))
1667 if (SPEC_USIGN (val->type))
1668 SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) floatFromVal (lval) ^
1669 (TYPE_TARGET_ULONG) floatFromVal (rval);
1671 SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) floatFromVal (lval) ^
1672 (TYPE_TARGET_LONG) floatFromVal (rval);
1676 if (SPEC_USIGN (val->type))
1677 SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) floatFromVal (lval) ^
1678 (TYPE_TARGET_UINT) floatFromVal (rval);
1680 SPEC_CVAL (val->type).v_int =
1681 (TYPE_TARGET_INT) floatFromVal (lval) ^ (TYPE_TARGET_INT) floatFromVal (rval);
1686 return cheapestVal(val);
1689 /*------------------------------------------------------------------*/
1690 /* valAndOr - Generates code for and / or operation */
1691 /*------------------------------------------------------------------*/
1693 valLogicAndOr (value * lval, value * rval, int op)
1697 /* create a new value */
1699 val->type = val->etype = newCharLink ();
1700 val->type->class = SPECIFIER;
1701 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1702 SPEC_USIGN (val->type) = 1;
1707 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1711 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1719 /*------------------------------------------------------------------*/
1720 /* valCastLiteral - casts a literal value to another type */
1721 /*------------------------------------------------------------------*/
1723 valCastLiteral (sym_link * dtype, double fval)
1726 TYPE_TARGET_ULONG l = (TYPE_TARGET_ULONG)fval;
1733 val->etype = getSpec (val->type = copyLinkChain (dtype));
1736 val->etype = val->type = newLink (SPECIFIER);
1737 SPEC_NOUN (val->etype) = V_VOID;
1739 SPEC_SCLS (val->etype) = S_LITERAL;
1741 /* if it is not a specifier then we can assume that */
1742 /* it will be an unsigned long */
1743 if (!IS_SPEC (val->type)) {
1744 SPEC_CVAL (val->etype).v_ulong = l;
1748 if (SPEC_NOUN (val->etype) == V_FLOAT)
1749 SPEC_CVAL (val->etype).v_float = fval;
1750 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1751 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1752 else if (SPEC_NOUN (val->etype) == V_BIT ||
1753 SPEC_NOUN (val->etype) == V_SBIT)
1754 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1755 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1756 SPEC_CVAL (val->etype).v_uint = l &
1757 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1758 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1759 if (SPEC_USIGN (val->etype))
1760 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1762 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1764 if (SPEC_LONG (val->etype)) {
1765 if (SPEC_USIGN (val->etype))
1766 SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1768 SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1770 if (SPEC_USIGN (val->etype))
1771 SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT)l;
1773 SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT)l;
1779 /*------------------------------------------------------------------*/
1780 /* getNelements - determines # of elements from init list */
1781 /*------------------------------------------------------------------*/
1783 getNelements (sym_link * type, initList * ilist)
1790 if (ilist->type == INIT_DEEP)
1791 ilist = ilist->init.deep;
1793 /* if type is a character array and there is only one
1794 (string) initialiser then get the length of the string */
1795 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1797 ast *iast = ilist->init.node;
1798 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1801 werror (E_CONST_EXPECTED);
1805 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1806 // yep, it's a string
1808 return DCL_ELEM (v->type);
1816 ilist = ilist->next;
1821 /*-----------------------------------------------------------------*/
1822 /* valForArray - returns a value with name of array index */
1823 /*-----------------------------------------------------------------*/
1825 valForArray (ast * arrExpr)
1827 value *val, *lval = NULL;
1829 int size = getSize (arrExpr->left->ftype->next);
1830 /* if the right or left is an array
1832 if (IS_AST_OP (arrExpr->left))
1834 if (arrExpr->left->opval.op == '[')
1835 lval = valForArray (arrExpr->left);
1836 else if (arrExpr->left->opval.op == '.')
1837 lval = valForStructElem (arrExpr->left->left,
1838 arrExpr->left->right);
1839 else if (arrExpr->left->opval.op == PTR_OP &&
1840 IS_ADDRESS_OF_OP (arrExpr->left->left))
1841 lval = valForStructElem (arrExpr->left->left->left,
1842 arrExpr->left->right);
1847 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1850 if (!IS_AST_LIT_VALUE (arrExpr->right))
1856 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1860 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1863 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1864 (int) AST_LIT_VALUE (arrExpr->right) * size);
1866 val->type = newLink (DECLARATOR);
1867 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1868 DCL_TYPE (val->type) = CPOINTER;
1869 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1870 DCL_TYPE (val->type) = FPOINTER;
1871 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1872 DCL_TYPE (val->type) = PPOINTER;
1873 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1874 DCL_TYPE (val->type) = IPOINTER;
1875 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1876 DCL_TYPE (val->type) = EEPPOINTER;
1878 DCL_TYPE (val->type) = POINTER;
1879 val->type->next = arrExpr->left->ftype->next;
1880 val->etype = getSpec (val->type);
1884 /*-----------------------------------------------------------------*/
1885 /* valForStructElem - returns value with name of struct element */
1886 /*-----------------------------------------------------------------*/
1888 valForStructElem (ast * structT, ast * elemT)
1890 value *val, *lval = NULL;
1894 /* left could be furthur derefed */
1895 if (IS_AST_OP (structT))
1897 if (structT->opval.op == '[')
1898 lval = valForArray (structT);
1899 else if (structT->opval.op == '.')
1900 lval = valForStructElem (structT->left, structT->right);
1901 else if (structT->opval.op == PTR_OP &&
1902 IS_ADDRESS_OF_OP (structT->left))
1903 lval = valForStructElem (structT->left->left,
1909 if (!IS_AST_SYM_VALUE (elemT))
1912 if (!IS_STRUCT (structT->etype))
1915 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1916 AST_SYMBOL (elemT))) == NULL)
1924 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1928 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1931 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1934 val->type = newLink (DECLARATOR);
1935 if (SPEC_SCLS (structT->etype) == S_CODE)
1936 DCL_TYPE (val->type) = CPOINTER;
1937 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1938 DCL_TYPE (val->type) = FPOINTER;
1939 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1940 DCL_TYPE (val->type) = PPOINTER;
1941 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1942 DCL_TYPE (val->type) = IPOINTER;
1943 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1944 DCL_TYPE (val->type) = EEPPOINTER;
1946 DCL_TYPE (val->type) = POINTER;
1947 val->type->next = sym->type;
1948 val->etype = getSpec (val->type);
1952 /*-----------------------------------------------------------------*/
1953 /* valForCastAggr - will return value for a cast of an aggregate */
1954 /* plus minus a constant */
1955 /*-----------------------------------------------------------------*/
1957 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1961 if (!IS_AST_SYM_VALUE (aexpr))
1963 if (!IS_AST_LIT_VALUE (cnst))
1968 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1969 AST_SYMBOL (aexpr)->rname, op,
1970 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1973 val->etype = getSpec (val->type);
1977 /*-----------------------------------------------------------------*/
1978 /* valForCastAggr - will return value for a cast of an aggregate */
1979 /* with no constant */
1980 /*-----------------------------------------------------------------*/
1982 valForCastArr (ast * aexpr, sym_link * type)
1986 if (!IS_AST_SYM_VALUE (aexpr))
1991 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1992 AST_SYMBOL (aexpr)->rname);
1995 val->etype = getSpec (val->type);