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 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_alloc (sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->lineno = mylineno;
60 nilist->filename = currFname;
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)
105 literalList *head, *last, *newL;
109 if (!src || src->type != INIT_DEEP)
114 iLoop = src->init.deep;
118 if (iLoop->type != INIT_NODE)
123 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_CHECK)))
130 // We've now established that the initializer list contains only literal values.
132 iLoop = src->init.deep;
135 double val = AST_LIT_VALUE(iLoop->init.node);
137 if (last && last->literalValue == val)
143 newL = Safe_alloc(sizeof(literalList));
144 newL->literalValue = val;
171 copyLiteralList(literalList *src)
173 literalList *head, *prev, *newL;
179 newL = Safe_alloc(sizeof(literalList));
181 newL->literalValue = src->literalValue;
182 newL->count = src->count;
202 /*------------------------------------------------------------------*/
203 /* copyIlist - copy initializer list */
204 /*------------------------------------------------------------------*/
206 copyIlist (initList * src)
208 initList *dest = NULL;
216 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
219 dest = newiList (INIT_NODE, copyAst (src->init.node));
224 dest->next = copyIlist (src->next);
229 /*------------------------------------------------------------------*/
230 /* list2int - converts the first element of the list to value */
231 /*------------------------------------------------------------------*/
233 list2int (initList * val)
237 if (i->type == INIT_DEEP)
238 return list2int (val->init.deep);
240 return floatFromVal (constExprValue (val->init.node, TRUE));
243 /*------------------------------------------------------------------*/
244 /* list2val - converts the first element of the list to value */
245 /*------------------------------------------------------------------*/
247 list2val (initList * val)
252 if (val->type == INIT_DEEP)
253 return list2val (val->init.deep);
255 return constExprValue (val->init.node, TRUE);
258 /*------------------------------------------------------------------*/
259 /* list2expr - returns the first expression in the initializer list */
260 /*------------------------------------------------------------------*/
262 list2expr (initList * ilist)
264 if (ilist->type == INIT_DEEP)
265 return list2expr (ilist->init.deep);
266 return ilist->init.node;
269 /*------------------------------------------------------------------*/
270 /* resolveIvalSym - resolve symbols in initial values */
271 /*------------------------------------------------------------------*/
273 resolveIvalSym (initList * ilist, sym_link * type)
275 RESULT_TYPE resultType;
280 if (ilist->type == INIT_NODE)
283 resultType = RESULT_TYPE_NONE;
285 resultType = getResultTypeFromType (getSpec (type));
286 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
290 if (ilist->type == INIT_DEEP)
291 resolveIvalSym (ilist->init.deep, type);
293 resolveIvalSym (ilist->next, type);
296 /*-----------------------------------------------------------------*/
297 /* symbolVal - creates a value for a symbol */
298 /*-----------------------------------------------------------------*/
300 symbolVal (symbol * sym)
312 val->type = sym->type;
313 val->etype = getSpec (val->type);
318 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
322 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
328 #if defined(REDUCE_LITERALS)
329 /*--------------------------------------------------------------------*/
330 /* cheapestVal - convert a val to the cheapest as possible value */
331 /*--------------------------------------------------------------------*/
332 static value *cheapestVal (value *val) {
336 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
339 if (SPEC_LONG(val->type)) {
340 if (SPEC_USIGN(val->type)) {
341 uval=SPEC_CVAL(val->type).v_ulong;
343 sval=SPEC_CVAL(val->type).v_long;
346 if (SPEC_USIGN(val->type)) {
347 uval=SPEC_CVAL(val->type).v_uint;
349 sval=SPEC_CVAL(val->type).v_int;
353 if (SPEC_USIGN(val->type)) {
355 SPEC_LONG(val->type)=0;
356 SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
358 SPEC_NOUN(val->type)=V_CHAR;
361 } else { // not unsigned
364 SPEC_LONG(val->type)=0;
365 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
367 SPEC_NOUN(val->type)=V_CHAR;
372 SPEC_LONG(val->type)=0;
373 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
375 SPEC_NOUN(val->type)=V_CHAR;
385 static value *cheapestVal (value *val)
387 if (IS_FLOAT (val->type) || IS_CHAR (val->type))
390 /* - signed/unsigned must not be changed.
391 - long must not be changed.
393 the only possible reduction is from signed int to signed char,
394 because it's automatically promoted back to signed int.
396 a reduction from unsigned int to unsigned char is a bug,
397 because an _unsigned_ char is promoted to _signed_ int! */
398 if (IS_INT(val->type) &&
399 !SPEC_USIGN(val->type) &&
400 !SPEC_LONG(val->type) &&
401 SPEC_CVAL(val->type).v_int >= -128 &&
402 SPEC_CVAL(val->type).v_int < 0)
405 SPEC_NOUN(val->type) = V_CHAR;
407 /* 'unsigned char' promotes to 'signed int', so that we can
408 reduce it the other way */
409 if (IS_INT(val->type) &&
410 !SPEC_USIGN(val->type) &&
411 !SPEC_LONG(val->type) &&
412 SPEC_CVAL(val->type).v_int >= 0 &&
413 SPEC_CVAL(val->type).v_int <= 255)
416 SPEC_NOUN(val->type) = V_CHAR;
417 SPEC_USIGN(val->type) = 1;
423 /*-----------------------------------------------------------------*/
424 /* valueFromLit - creates a value from a literal */
425 /*-----------------------------------------------------------------*/
427 valueFromLit (double lit)
431 if ((((TYPE_DWORD) lit) - lit) == 0)
433 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
434 return constVal (buffer);
437 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
438 return constFloatVal (buffer);
441 /*-----------------------------------------------------------------*/
442 /* constFloatVal - converts a FLOAT constant to value */
443 /*-----------------------------------------------------------------*/
445 constFloatVal (char *s)
447 value *val = newValue ();
450 if (sscanf (s, "%lf", &sval) != 1)
452 werror (E_INVALID_FLOAT_CONST, s);
453 return constVal ("0");
456 val->type = val->etype = newLink (SPECIFIER);
457 SPEC_NOUN (val->type) = V_FLOAT;
458 SPEC_SCLS (val->type) = S_LITERAL;
459 SPEC_CVAL (val->type).v_float = sval;
464 /*-----------------------------------------------------------------*/
465 /* constVal - converts an INTEGER constant into a cheapest value */
466 /*-----------------------------------------------------------------*/
467 value *constVal (char *s)
470 short hex = 0, octal = 0;
475 val = newValue (); /* alloc space for value */
477 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
478 SPEC_SCLS (val->type) = S_LITERAL;
479 // let's start with a signed char
480 SPEC_NOUN (val->type) = V_CHAR;
481 SPEC_USIGN (val->type) = 0;
483 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
485 /* set the octal flag */
486 if (!hex && *s == '0' && *(s + 1))
489 /* create the scan string */
490 scanFmt[scI++] = '%';
492 scanFmt[scI++] = 'l';
495 scanFmt[scI++] = 'o';
497 scanFmt[scI++] = 'x';
499 scanFmt[scI++] = 'f';
501 scanFmt[scI++] = '\0';
505 sscanf (s, scanFmt, &sval);
508 sscanf (s, scanFmt, &dval);
511 /* Setup the flags first */
512 /* set the _long flag if 'lL' is found */
513 if (strchr (s, 'l') || strchr (s, 'L')) {
514 SPEC_NOUN (val->type) = V_INT;
515 SPEC_LONG (val->type) = 1;
518 /* set the unsigned flag if 'uU' is found */
519 if (strchr (s, 'u') || strchr (s, 'U')) {
520 SPEC_USIGN (val->type) = 1;
523 if (dval<0) { // "-28u" will still be signed and negative
524 if (dval<-128) { // check if we have to promote to int
525 SPEC_NOUN (val->type) = V_INT;
527 if (dval<-32768) { // check if we have to promote to long int
528 SPEC_LONG (val->type) = 1;
531 if (dval>0xff || /* check if we have to promote to int */
532 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
533 char. After an integral promotion it will
534 be a signed int; this certainly isn't what
535 the programer wants */
536 SPEC_NOUN (val->type) = V_INT;
538 else { /* store char's always as unsigned; this helps other optimizations */
539 SPEC_USIGN (val->type) = 1;
541 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
542 SPEC_LONG (val->type) = 1;
544 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
545 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
547 SPEC_USIGN (val->type) = 1;
549 SPEC_LONG (val->type) = 1;
550 if (dval>0x7fffffff) {
551 SPEC_USIGN (val->type) = 1;
557 if (SPEC_LONG (val->type))
559 if (SPEC_USIGN (val->type))
561 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
565 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
570 if (SPEC_USIGN (val->type))
572 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
576 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
583 /*! /fn char hexEscape(char **src)
585 /param src Pointer to 'x' from start of hex character value
588 unsigned char hexEscape(char **src)
591 unsigned long value ;
593 (*src)++ ; /* Skip over the 'x' */
594 s = *src ; /* Save for error detection */
596 value = strtol (*src, src, 16);
599 // no valid hex found
600 werror(E_INVALID_HEX);
603 werror(W_ESC_SEQ_OOR_FOR_CHAR);
609 /*------------------------------------------------------------------*/
610 /* octalEscape - process an octal constant of max three digits */
611 /* return the octal value, throw a warning for illegal octal */
612 /* adjust src to point at the last proccesed char */
613 /*------------------------------------------------------------------*/
615 unsigned char octalEscape (char **str) {
619 for (digits=0; digits<3; digits++) {
620 if (**str>='0' && **str<='7') {
621 value = value*8 + (**str-'0');
628 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
629 werror (W_ESC_SEQ_OOR_FOR_CHAR);
636 /fn int copyStr (char *dest, char *src)
638 Copies a source string to a dest buffer interpreting escape sequences
639 and special characters
641 /param dest Buffer to receive the resultant string
642 /param src Buffer containing the source string with escape sequecnes
643 /return Number of characters in output string
648 copyStr (char *dest, char *src)
651 char *OriginalDest = dest ;
657 else if (*src == '\\')
692 *dest++ = octalEscape(&src);
697 *dest++ = hexEscape(&src) ;
724 return dest - OriginalDest ;
727 /*------------------------------------------------------------------*/
728 /* strVal - converts a string constant to a value */
729 /*------------------------------------------------------------------*/
735 val = newValue (); /* get a new one */
737 /* get a declarator */
738 val->type = newLink (DECLARATOR);
739 DCL_TYPE (val->type) = ARRAY;
740 val->type->next = val->etype = newLink (SPECIFIER);
741 SPEC_NOUN (val->etype) = V_CHAR;
742 SPEC_SCLS (val->etype) = S_LITERAL;
744 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
745 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
751 /*------------------------------------------------------------------*/
752 /* reverseValWithType - reverses value chain with type & etype */
753 /*------------------------------------------------------------------*/
755 reverseValWithType (value * val)
763 /* save the type * etype chains */
767 /* set the current one 2b null */
768 val->type = val->etype = NULL;
769 val = reverseVal (val);
771 /* restore type & etype */
778 /*------------------------------------------------------------------*/
779 /* reverseVal - reverses the values for a value chain */
780 /*------------------------------------------------------------------*/
782 reverseVal (value * val)
784 value *prev, *curr, *next;
799 val->next = (void *) NULL;
803 /*------------------------------------------------------------------*/
804 /* copyValueChain - will copy a chain of values */
805 /*------------------------------------------------------------------*/
807 copyValueChain (value * src)
814 dest = copyValue (src);
815 dest->next = copyValueChain (src->next);
820 /*------------------------------------------------------------------*/
821 /* copyValue - copies contents of a value to a fresh one */
822 /*------------------------------------------------------------------*/
824 copyValue (value * src)
829 dest->sym = copySymbol (src->sym);
830 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
831 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
832 dest->etype = (src->type ? getSpec (dest->type) : NULL);
837 /*------------------------------------------------------------------*/
838 /* charVal - converts a character constant to a value */
839 /*------------------------------------------------------------------*/
847 val->type = val->etype = newLink (SPECIFIER);
848 SPEC_NOUN (val->type) = V_CHAR;
849 SPEC_USIGN(val->type) = 1;
850 SPEC_SCLS (val->type) = S_LITERAL;
852 s++; /* get rid of quotation */
853 /* if \ then special processing */
856 s++; /* go beyond the backslash */
860 SPEC_CVAL (val->type).v_uint = '\n';
863 SPEC_CVAL (val->type).v_uint = '\t';
866 SPEC_CVAL (val->type).v_uint = '\v';
869 SPEC_CVAL (val->type).v_uint = '\b';
872 SPEC_CVAL (val->type).v_uint = '\r';
875 SPEC_CVAL (val->type).v_uint = '\f';
878 SPEC_CVAL (val->type).v_uint = '\a';
881 SPEC_CVAL (val->type).v_uint = '\\';
884 SPEC_CVAL (val->type).v_uint = '\?';
887 SPEC_CVAL (val->type).v_uint = '\'';
890 SPEC_CVAL (val->type).v_uint = '\"';
901 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
905 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
909 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
913 else /* not a backslash */
914 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
919 /*------------------------------------------------------------------*/
920 /* valFromType - creates a value from type given */
921 /*------------------------------------------------------------------*/
923 valFromType (sym_link * type)
925 value *val = newValue ();
926 val->type = copyLinkChain (type);
927 val->etype = getSpec (val->type);
931 /*------------------------------------------------------------------*/
932 /* floatFromVal - value to double float conversion */
933 /*------------------------------------------------------------------*/
935 floatFromVal (value * val)
940 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
942 werror (E_CONST_EXPECTED, val->name);
946 /* if it is not a specifier then we can assume that */
947 /* it will be an unsigned long */
948 if (!IS_SPEC (val->type))
949 return (double) SPEC_CVAL (val->etype).v_ulong;
951 if (SPEC_NOUN (val->etype) == V_FLOAT)
952 return (double) SPEC_CVAL (val->etype).v_float;
954 if (SPEC_LONG (val->etype))
956 if (SPEC_USIGN (val->etype))
957 return (double) SPEC_CVAL (val->etype).v_ulong;
959 return (double) SPEC_CVAL (val->etype).v_long;
962 if (SPEC_NOUN (val->etype) == V_INT) {
963 if (SPEC_USIGN (val->etype))
964 return (double) SPEC_CVAL (val->etype).v_uint;
966 return (double) SPEC_CVAL (val->etype).v_int;
969 if (SPEC_NOUN (val->etype) == V_CHAR) {
970 if (SPEC_USIGN (val->etype))
971 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
973 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
976 if (IS_BITVAR(val->etype)) {
977 return (double) SPEC_CVAL (val->etype).v_uint;
980 if (SPEC_NOUN (val->etype) == V_VOID) {
981 return (double) SPEC_CVAL (val->etype).v_ulong;
985 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
986 "floatFromVal: unknown value");
990 /*------------------------------------------------------------------*/
991 /* valUnaryPM - does the unary +/- operation on a constant */
992 /*------------------------------------------------------------------*/
994 valUnaryPM (value * val)
996 /* depending on type */
997 if (SPEC_NOUN (val->etype) == V_FLOAT)
998 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1001 if (SPEC_LONG (val->etype))
1003 if (SPEC_USIGN (val->etype))
1004 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1006 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1010 if (SPEC_USIGN (val->etype))
1011 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1013 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1016 // -(unsigned 3) now really is signed
1017 SPEC_USIGN(val->etype)=0;
1018 // -(unsigned char)135 now really is an int
1019 if (SPEC_NOUN(val->etype) == V_CHAR) {
1020 if (SPEC_CVAL(val->etype).v_int < -128) {
1021 SPEC_NOUN(val->etype) = V_INT;
1027 /*------------------------------------------------------------------*/
1028 /* valueComplement - complements a constant */
1029 /*------------------------------------------------------------------*/
1031 valComplement (value * val)
1033 /* depending on type */
1034 if (SPEC_LONG (val->etype))
1036 if (SPEC_USIGN (val->etype))
1037 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1039 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1043 if (SPEC_USIGN (val->etype))
1044 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1046 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1048 // ~(unsigned 3) now really is signed
1049 SPEC_USIGN(val->etype)=0;
1053 /*------------------------------------------------------------------*/
1054 /* valueNot - complements a constant */
1055 /*------------------------------------------------------------------*/
1057 valNot (value * val)
1059 /* depending on type */
1060 if (SPEC_LONG (val->etype))
1062 if (SPEC_USIGN (val->etype))
1063 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1065 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1069 if (SPEC_USIGN (val->etype))
1070 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1072 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1077 /*------------------------------------------------------------------*/
1078 /* valMult - multiply constants */
1079 /*------------------------------------------------------------------*/
1081 valMult (value * lval, value * rval)
1085 /* create a new value */
1087 val->type = val->etype = newLink (SPECIFIER);
1088 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1089 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1090 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1091 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1092 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1095 if (IS_FLOAT (val->type))
1096 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1097 /* signed and unsigned mul are the same, as long as the precision of the
1098 result isn't bigger than the precision of the operands. */
1099 else if (SPEC_LONG (val->type))
1100 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1101 (TYPE_UDWORD) floatFromVal (rval);
1102 else if (SPEC_USIGN (val->type)) /* unsigned int */
1104 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1105 (TYPE_UWORD) floatFromVal (rval);
1107 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1108 if (ul != (TYPE_UWORD) ul)
1111 else /* signed int */
1113 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1114 (TYPE_WORD) floatFromVal (rval);
1116 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1117 if (l != (TYPE_WORD) l)
1120 return cheapestVal (val);
1123 /*------------------------------------------------------------------*/
1124 /* valDiv - Divide constants */
1125 /*------------------------------------------------------------------*/
1127 valDiv (value * lval, value * rval)
1131 if (floatFromVal (rval) == 0)
1133 werror (E_DIVIDE_BY_ZERO);
1137 /* create a new value */
1139 val->type = val->etype = newLink(SPECIFIER);
1140 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1141 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1142 SPEC_SCLS (val->etype) = S_LITERAL;
1143 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1144 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1148 if (IS_FLOAT (val->type))
1149 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1150 else if (SPEC_LONG (val->type))
1152 if (SPEC_USIGN (val->type))
1153 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1154 (TYPE_UDWORD) floatFromVal (rval);
1156 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1157 (TYPE_DWORD) floatFromVal (rval);
1161 if (SPEC_USIGN (val->type))
1162 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1163 (TYPE_UWORD) floatFromVal (rval);
1165 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1166 (TYPE_WORD) floatFromVal (rval);
1168 return cheapestVal (val);
1171 /*------------------------------------------------------------------*/
1172 /* valMod - Modulus constants */
1173 /*------------------------------------------------------------------*/
1175 valMod (value * lval, value * rval)
1179 /* create a new value */
1181 val->type = val->etype = newLink (SPECIFIER);
1182 SPEC_NOUN (val->type) = V_INT; /* type is int */
1183 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1184 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1185 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1189 if (SPEC_LONG (val->type))
1191 if (SPEC_USIGN (val->type))
1192 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1193 (TYPE_UDWORD) floatFromVal (rval);
1195 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1196 (TYPE_DWORD) floatFromVal (rval);
1200 if (SPEC_USIGN (val->type))
1201 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1202 (TYPE_UWORD) floatFromVal (rval);
1204 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1205 (TYPE_WORD) floatFromVal (rval);
1207 return cheapestVal (val);
1210 /*------------------------------------------------------------------*/
1211 /* valPlus - Addition constants */
1212 /*------------------------------------------------------------------*/
1214 valPlus (value * lval, value * rval)
1218 /* create a new value */
1220 val->type = val->etype = newLink (SPECIFIER);
1221 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1222 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1223 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1224 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1225 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1228 if (IS_FLOAT (val->type))
1229 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1230 else if (SPEC_LONG (val->type))
1232 if (SPEC_USIGN (val->type))
1233 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1234 (TYPE_UDWORD) floatFromVal (rval);
1236 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1237 (TYPE_DWORD) floatFromVal (rval);
1241 if (SPEC_USIGN (val->type))
1242 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1243 (TYPE_UWORD) floatFromVal (rval);
1245 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1246 (TYPE_WORD) floatFromVal (rval);
1248 return cheapestVal (val);
1251 /*------------------------------------------------------------------*/
1252 /* valMinus - Addition constants */
1253 /*------------------------------------------------------------------*/
1255 valMinus (value * lval, value * rval)
1259 /* create a new value */
1261 val->type = val->etype = newLink (SPECIFIER);
1262 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1263 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1264 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1265 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1266 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1269 if (IS_FLOAT (val->type))
1270 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1271 else if (SPEC_LONG (val->type))
1273 if (SPEC_USIGN (val->type))
1274 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1275 (TYPE_UDWORD) floatFromVal (rval);
1277 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1278 (TYPE_DWORD) floatFromVal (rval);
1282 if (SPEC_USIGN (val->type))
1283 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1284 (TYPE_UWORD) floatFromVal (rval);
1286 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1287 (TYPE_WORD) floatFromVal (rval);
1289 return cheapestVal (val);
1292 /*------------------------------------------------------------------*/
1293 /* valShift - Shift left or right */
1294 /*------------------------------------------------------------------*/
1296 valShift (value * lval, value * rval, int lr)
1300 /* create a new value */
1302 val->type = val->etype = newIntLink ();
1303 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1304 SPEC_NOUN (val->etype) = V_INT;
1305 /* 'unsigned char' promotes to 'signed int' */
1306 if (!IS_CHAR (lval->etype))
1307 SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1308 SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1310 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1313 /* right shift and unsigned */
1314 (!lr && SPEC_USIGN (rval->type))))
1316 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1319 if (SPEC_LONG (val->type))
1321 if (SPEC_USIGN (val->type))
1323 SPEC_CVAL (val->type).v_ulong = lr ?
1324 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1325 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1329 SPEC_CVAL (val->type).v_long = lr ?
1330 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1331 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1336 if (SPEC_USIGN (val->type))
1338 SPEC_CVAL (val->type).v_uint = lr ?
1339 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1340 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1344 SPEC_CVAL (val->type).v_int = lr ?
1345 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1346 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1349 return cheapestVal (val);
1352 /*------------------------------------------------------------------*/
1353 /* valCompare- Compares two literal */
1354 /*------------------------------------------------------------------*/
1356 valCompare (value * lval, value * rval, int ctype)
1360 /* create a new value */
1362 val->type = val->etype = newCharLink ();
1363 val->type->class = SPECIFIER;
1364 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1365 SPEC_USIGN (val->type) = 1;
1366 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1371 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1375 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1379 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1383 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1387 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1388 SPEC_NOUN(rval->type) == V_FLOAT)
1390 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1394 /* integrals: ignore signedness */
1397 l = (TYPE_UDWORD) floatFromVal (lval);
1398 r = (TYPE_UDWORD) floatFromVal (rval);
1399 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1400 neccessary to strip them to 16 bit.
1401 Literals are reduced to their cheapest type, therefore left and
1402 right might have different types. It's neccessary to find a
1403 common type: int (used for char too) or long */
1404 if (!IS_LONG (lval->etype) &&
1405 !IS_LONG (rval->etype))
1410 SPEC_CVAL (val->type).v_int = l == r;
1414 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1415 SPEC_NOUN(rval->type) == V_FLOAT)
1417 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1421 /* integrals: ignore signedness */
1424 l = (TYPE_UDWORD) floatFromVal (lval);
1425 r = (TYPE_UDWORD) floatFromVal (rval);
1426 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1427 neccessary to strip them to 16 bit.
1428 Literals are reduced to their cheapest type, therefore left and
1429 right might have different types. It's neccessary to find a
1430 common type: int (used for char too) or long */
1431 if (!IS_LONG (lval->etype) &&
1432 !IS_LONG (rval->etype))
1437 SPEC_CVAL (val->type).v_int = l != r;
1446 /*------------------------------------------------------------------*/
1447 /* valBitwise - Bitwise operation */
1448 /*------------------------------------------------------------------*/
1450 valBitwise (value * lval, value * rval, int op)
1454 /* create a new value */
1456 val->type = computeType (lval->etype, rval->etype, FALSE);
1457 val->etype = getSpec (val->type);
1458 SPEC_SCLS (val->etype) = S_LITERAL;
1463 if (SPEC_LONG (val->type))
1465 if (SPEC_USIGN (val->type))
1466 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1467 (TYPE_UDWORD) floatFromVal (rval);
1469 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1470 (TYPE_DWORD) floatFromVal (rval);
1474 if (SPEC_USIGN (val->type))
1475 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1476 (TYPE_UWORD) floatFromVal (rval);
1478 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1483 if (SPEC_LONG (val->type))
1485 if (SPEC_USIGN (val->type))
1486 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1487 (TYPE_UDWORD) floatFromVal (rval);
1489 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1490 (TYPE_DWORD) floatFromVal (rval);
1494 if (SPEC_USIGN (val->type))
1495 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1496 (TYPE_UWORD) floatFromVal (rval);
1498 SPEC_CVAL (val->type).v_int =
1499 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1505 if (SPEC_LONG (val->type))
1507 if (SPEC_USIGN (val->type))
1508 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1509 (TYPE_UDWORD) floatFromVal (rval);
1511 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1512 (TYPE_DWORD) floatFromVal (rval);
1516 if (SPEC_USIGN (val->type))
1517 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1518 (TYPE_UWORD) floatFromVal (rval);
1520 SPEC_CVAL (val->type).v_int =
1521 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1526 return cheapestVal(val);
1529 /*------------------------------------------------------------------*/
1530 /* valAndOr - Generates code for and / or operation */
1531 /*------------------------------------------------------------------*/
1533 valLogicAndOr (value * lval, value * rval, int op)
1537 /* create a new value */
1539 val->type = val->etype = newCharLink ();
1540 val->type->class = SPECIFIER;
1541 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1542 SPEC_USIGN (val->type) = 1;
1547 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1551 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1559 /*------------------------------------------------------------------*/
1560 /* valCastLiteral - casts a literal value to another type */
1561 /*------------------------------------------------------------------*/
1563 valCastLiteral (sym_link * dtype, double fval)
1566 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1572 val->etype = getSpec (val->type = copyLinkChain (dtype));
1573 SPEC_SCLS (val->etype) = S_LITERAL;
1575 /* if it is not a specifier then we can assume that */
1576 /* it will be an unsigned long */
1577 if (!IS_SPEC (val->type)) {
1578 SPEC_CVAL (val->etype).v_ulong = l;
1582 if (SPEC_NOUN (val->etype) == V_FLOAT)
1583 SPEC_CVAL (val->etype).v_float = fval;
1584 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1585 if (SPEC_USIGN (val->etype))
1586 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1588 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1590 if (SPEC_LONG (val->etype)) {
1591 if (SPEC_USIGN (val->etype))
1592 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1594 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1596 if (SPEC_USIGN (val->etype))
1597 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1599 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1605 /*------------------------------------------------------------------*/
1606 /* getNelements - determines # of elements from init list */
1607 /*------------------------------------------------------------------*/
1609 getNelements (sym_link * type, initList * ilist)
1616 if (ilist->type == INIT_DEEP)
1617 ilist = ilist->init.deep;
1619 /* if type is a character array and there is only one
1620 (string) initialiser then get the length of the string */
1621 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1623 ast *iast = ilist->init.node;
1624 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1627 werror (E_CONST_EXPECTED);
1631 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1632 // yep, it's a string
1634 return DCL_ELEM (v->type);
1642 ilist = ilist->next;
1647 /*-----------------------------------------------------------------*/
1648 /* valForArray - returns a value with name of array index */
1649 /*-----------------------------------------------------------------*/
1651 valForArray (ast * arrExpr)
1653 value *val, *lval = NULL;
1655 int size = getSize (arrExpr->left->ftype->next);
1656 /* if the right or left is an array
1658 if (IS_AST_OP (arrExpr->left))
1660 if (arrExpr->left->opval.op == '[')
1661 lval = valForArray (arrExpr->left);
1662 else if (arrExpr->left->opval.op == '.')
1663 lval = valForStructElem (arrExpr->left->left,
1664 arrExpr->left->right);
1665 else if (arrExpr->left->opval.op == PTR_OP &&
1666 IS_ADDRESS_OF_OP (arrExpr->left->left))
1667 lval = valForStructElem (arrExpr->left->left->left,
1668 arrExpr->left->right);
1673 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1676 if (!IS_AST_LIT_VALUE (arrExpr->right))
1682 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1686 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1689 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1690 (int) AST_LIT_VALUE (arrExpr->right) * size);
1692 val->type = newLink (DECLARATOR);
1693 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1694 DCL_TYPE (val->type) = CPOINTER;
1695 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1696 DCL_TYPE (val->type) = FPOINTER;
1697 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1698 DCL_TYPE (val->type) = PPOINTER;
1699 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1700 DCL_TYPE (val->type) = IPOINTER;
1701 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1702 DCL_TYPE (val->type) = EEPPOINTER;
1704 DCL_TYPE (val->type) = POINTER;
1705 val->type->next = arrExpr->left->ftype;
1706 val->etype = getSpec (val->type);
1710 /*-----------------------------------------------------------------*/
1711 /* valForStructElem - returns value with name of struct element */
1712 /*-----------------------------------------------------------------*/
1714 valForStructElem (ast * structT, ast * elemT)
1716 value *val, *lval = NULL;
1720 /* left could be furthur derefed */
1721 if (IS_AST_OP (structT))
1723 if (structT->opval.op == '[')
1724 lval = valForArray (structT);
1725 else if (structT->opval.op == '.')
1726 lval = valForStructElem (structT->left, structT->right);
1727 else if (structT->opval.op == PTR_OP &&
1728 IS_ADDRESS_OF_OP (structT->left))
1729 lval = valForStructElem (structT->left->left,
1735 if (!IS_AST_SYM_VALUE (elemT))
1738 if (!IS_STRUCT (structT->etype))
1741 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1742 AST_SYMBOL (elemT))) == NULL)
1750 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1754 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1757 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1760 val->type = newLink (DECLARATOR);
1761 if (SPEC_SCLS (structT->etype) == S_CODE)
1762 DCL_TYPE (val->type) = CPOINTER;
1763 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1764 DCL_TYPE (val->type) = FPOINTER;
1765 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1766 DCL_TYPE (val->type) = PPOINTER;
1767 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1768 DCL_TYPE (val->type) = IPOINTER;
1769 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1770 DCL_TYPE (val->type) = EEPPOINTER;
1772 DCL_TYPE (val->type) = POINTER;
1773 val->type->next = sym->type;
1774 val->etype = getSpec (val->type);
1778 /*-----------------------------------------------------------------*/
1779 /* valForCastAggr - will return value for a cast of an aggregate */
1780 /* plus minus a constant */
1781 /*-----------------------------------------------------------------*/
1783 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1787 if (!IS_AST_SYM_VALUE (aexpr))
1789 if (!IS_AST_LIT_VALUE (cnst))
1794 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1795 AST_SYMBOL (aexpr)->rname, op,
1796 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1799 val->etype = getSpec (val->type);
1803 /*-----------------------------------------------------------------*/
1804 /* valForCastAggr - will return value for a cast of an aggregate */
1805 /* with no constant */
1806 /*-----------------------------------------------------------------*/
1808 valForCastArr (ast * aexpr, sym_link * type)
1812 if (!IS_AST_SYM_VALUE (aexpr))
1817 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1818 AST_SYMBOL (aexpr)->rname);
1821 val->etype = getSpec (val->type);