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;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_CHECK)))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_alloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_alloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node), RESULT_CHECK);
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
308 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
312 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
318 #if defined(REDUCE_LITERALS)
319 /*--------------------------------------------------------------------*/
320 /* cheapestVal - convert a val to the cheapest as possible value */
321 /*--------------------------------------------------------------------*/
322 static value *cheapestVal (value *val) {
326 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
329 if (SPEC_LONG(val->type)) {
330 if (SPEC_USIGN(val->type)) {
331 uval=SPEC_CVAL(val->type).v_ulong;
333 sval=SPEC_CVAL(val->type).v_long;
336 if (SPEC_USIGN(val->type)) {
337 uval=SPEC_CVAL(val->type).v_uint;
339 sval=SPEC_CVAL(val->type).v_int;
343 if (SPEC_USIGN(val->type)) {
345 SPEC_LONG(val->type)=0;
346 SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
348 SPEC_NOUN(val->type)=V_CHAR;
351 } else { // not unsigned
354 SPEC_LONG(val->type)=0;
355 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
357 SPEC_NOUN(val->type)=V_CHAR;
362 SPEC_LONG(val->type)=0;
363 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
365 SPEC_NOUN(val->type)=V_CHAR;
375 static value *cheapestVal (value *val)
377 if (IS_FLOAT (val->type) || IS_CHAR (val->type))
380 /* - signed/unsigned must not be changed.
381 - long must not be changed.
383 the only possible reduction is from signed int to signed char,
384 because it's automatically promoted back to signed int.
386 a reduction from unsigned int to unsigned char is a bug,
387 because an _unsigned_ char is promoted to _signed_ int! */
388 if (IS_INT(val->type) &&
389 !SPEC_USIGN(val->type) &&
390 !SPEC_LONG(val->type) &&
391 SPEC_CVAL(val->type).v_int >= -128 &&
392 SPEC_CVAL(val->type).v_int < 0)
395 SPEC_NOUN(val->type) = V_CHAR;
397 /* 'unsigned char' promotes to 'signed int', so that we can
398 reduce it the other way */
399 if (IS_INT(val->type) &&
400 !SPEC_USIGN(val->type) &&
401 !SPEC_LONG(val->type) &&
402 SPEC_CVAL(val->type).v_int >= 0 &&
403 SPEC_CVAL(val->type).v_int <= 255)
406 SPEC_NOUN(val->type) = V_CHAR;
407 SPEC_USIGN(val->type) = 1;
413 /*-----------------------------------------------------------------*/
414 /* valueFromLit - creates a value from a literal */
415 /*-----------------------------------------------------------------*/
417 valueFromLit (double lit)
421 if ((((TYPE_DWORD) lit) - lit) == 0)
423 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
424 return constVal (buffer);
427 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
428 return constFloatVal (buffer);
431 /*-----------------------------------------------------------------*/
432 /* constFloatVal - converts a FLOAT constant to value */
433 /*-----------------------------------------------------------------*/
435 constFloatVal (char *s)
437 value *val = newValue ();
440 if (sscanf (s, "%lf", &sval) != 1)
442 werror (E_INVALID_FLOAT_CONST, s);
443 return constVal ("0");
446 val->type = val->etype = newLink (SPECIFIER);
447 SPEC_NOUN (val->type) = V_FLOAT;
448 SPEC_SCLS (val->type) = S_LITERAL;
449 SPEC_CVAL (val->type).v_float = sval;
454 /*-----------------------------------------------------------------*/
455 /* constVal - converts an INTEGER constant into a cheapest value */
456 /*-----------------------------------------------------------------*/
457 value *constVal (char *s)
460 short hex = 0, octal = 0;
465 val = newValue (); /* alloc space for value */
467 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
468 SPEC_SCLS (val->type) = S_LITERAL;
469 // let's start with a signed char
470 SPEC_NOUN (val->type) = V_CHAR;
471 SPEC_USIGN (val->type) = 0;
473 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
475 /* set the octal flag */
476 if (!hex && *s == '0' && *(s + 1))
479 /* create the scan string */
480 scanFmt[scI++] = '%';
482 scanFmt[scI++] = 'l';
485 scanFmt[scI++] = 'o';
487 scanFmt[scI++] = 'x';
489 scanFmt[scI++] = 'f';
491 scanFmt[scI++] = '\0';
495 sscanf (s, scanFmt, &sval);
498 sscanf (s, scanFmt, &dval);
501 /* Setup the flags first */
502 /* set the _long flag if 'lL' is found */
503 if (strchr (s, 'l') || strchr (s, 'L')) {
504 SPEC_NOUN (val->type) = V_INT;
505 SPEC_LONG (val->type) = 1;
508 /* set the unsigned flag if 'uU' is found */
509 if (strchr (s, 'u') || strchr (s, 'U')) {
510 SPEC_USIGN (val->type) = 1;
513 if (dval<0) { // "-28u" will still be signed and negative
514 if (dval<-128) { // check if we have to promote to int
515 SPEC_NOUN (val->type) = V_INT;
517 if (dval<-32768) { // check if we have to promote to long int
518 SPEC_LONG (val->type) = 1;
521 if (dval>0xff || /* check if we have to promote to int */
522 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
523 char. After an integral promotion it will
524 be a signed int; this certainly isn't what
525 the programer wants */
526 SPEC_NOUN (val->type) = V_INT;
528 else { /* store char's always as unsigned; this helps other optimizations */
529 SPEC_USIGN (val->type) = 1;
531 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
532 SPEC_LONG (val->type) = 1;
534 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
535 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
537 SPEC_USIGN (val->type) = 1;
539 SPEC_LONG (val->type) = 1;
540 if (dval>0x7fffffff) {
541 SPEC_USIGN (val->type) = 1;
547 if (SPEC_LONG (val->type))
549 if (SPEC_USIGN (val->type))
551 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
555 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
560 if (SPEC_USIGN (val->type))
562 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
566 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
573 /*! /fn char hexEscape(char **src)
575 /param src Pointer to 'x' from start of hex character value
578 unsigned char hexEscape(char **src)
581 unsigned long value ;
583 (*src)++ ; /* Skip over the 'x' */
584 s = *src ; /* Save for error detection */
586 value = strtol (*src, src, 16);
589 // no valid hex found
590 werror(E_INVALID_HEX);
593 werror(W_ESC_SEQ_OOR_FOR_CHAR);
599 /*------------------------------------------------------------------*/
600 /* octalEscape - process an octal constant of max three digits */
601 /* return the octal value, throw a warning for illegal octal */
602 /* adjust src to point at the last proccesed char */
603 /*------------------------------------------------------------------*/
605 unsigned char octalEscape (char **str) {
609 for (digits=0; digits<3; digits++) {
610 if (**str>='0' && **str<='7') {
611 value = value*8 + (**str-'0');
618 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
619 werror (W_ESC_SEQ_OOR_FOR_CHAR);
626 /fn int copyStr (char *dest, char *src)
628 Copies a source string to a dest buffer interpreting escape sequences
629 and special characters
631 /param dest Buffer to receive the resultant string
632 /param src Buffer containing the source string with escape sequecnes
633 /return Number of characters in output string
638 copyStr (char *dest, char *src)
641 char *OriginalDest = dest ;
647 else if (*src == '\\')
682 *dest++ = octalEscape(&src);
687 *dest++ = hexEscape(&src) ;
714 return dest - OriginalDest ;
717 /*------------------------------------------------------------------*/
718 /* strVal - converts a string constant to a value */
719 /*------------------------------------------------------------------*/
725 val = newValue (); /* get a new one */
727 /* get a declarator */
728 val->type = newLink (DECLARATOR);
729 DCL_TYPE (val->type) = ARRAY;
730 val->type->next = val->etype = newLink (SPECIFIER);
731 SPEC_NOUN (val->etype) = V_CHAR;
732 SPEC_SCLS (val->etype) = S_LITERAL;
734 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
735 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
741 /*------------------------------------------------------------------*/
742 /* reverseValWithType - reverses value chain with type & etype */
743 /*------------------------------------------------------------------*/
745 reverseValWithType (value * val)
753 /* save the type * etype chains */
757 /* set the current one 2b null */
758 val->type = val->etype = NULL;
759 val = reverseVal (val);
761 /* restore type & etype */
768 /*------------------------------------------------------------------*/
769 /* reverseVal - reverses the values for a value chain */
770 /*------------------------------------------------------------------*/
772 reverseVal (value * val)
774 value *prev, *curr, *next;
789 val->next = (void *) NULL;
793 /*------------------------------------------------------------------*/
794 /* copyValueChain - will copy a chain of values */
795 /*------------------------------------------------------------------*/
797 copyValueChain (value * src)
804 dest = copyValue (src);
805 dest->next = copyValueChain (src->next);
810 /*------------------------------------------------------------------*/
811 /* copyValue - copies contents of a value to a fresh one */
812 /*------------------------------------------------------------------*/
814 copyValue (value * src)
819 dest->sym = copySymbol (src->sym);
820 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
821 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
822 dest->etype = (src->type ? getSpec (dest->type) : NULL);
827 /*------------------------------------------------------------------*/
828 /* charVal - converts a character constant to a value */
829 /*------------------------------------------------------------------*/
837 val->type = val->etype = newLink (SPECIFIER);
838 SPEC_NOUN (val->type) = V_CHAR;
839 SPEC_USIGN(val->type) = 1;
840 SPEC_SCLS (val->type) = S_LITERAL;
842 s++; /* get rid of quotation */
843 /* if \ then special processing */
846 s++; /* go beyond the backslash */
850 SPEC_CVAL (val->type).v_uint = '\n';
853 SPEC_CVAL (val->type).v_uint = '\t';
856 SPEC_CVAL (val->type).v_uint = '\v';
859 SPEC_CVAL (val->type).v_uint = '\b';
862 SPEC_CVAL (val->type).v_uint = '\r';
865 SPEC_CVAL (val->type).v_uint = '\f';
868 SPEC_CVAL (val->type).v_uint = '\a';
871 SPEC_CVAL (val->type).v_uint = '\\';
874 SPEC_CVAL (val->type).v_uint = '\?';
877 SPEC_CVAL (val->type).v_uint = '\'';
880 SPEC_CVAL (val->type).v_uint = '\"';
891 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
895 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
899 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
903 else /* not a backslash */
904 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
909 /*------------------------------------------------------------------*/
910 /* valFromType - creates a value from type given */
911 /*------------------------------------------------------------------*/
913 valFromType (sym_link * type)
915 value *val = newValue ();
916 val->type = copyLinkChain (type);
917 val->etype = getSpec (val->type);
921 /*------------------------------------------------------------------*/
922 /* floatFromVal - value to double float conversion */
923 /*------------------------------------------------------------------*/
925 floatFromVal (value * val)
930 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
932 werror (E_CONST_EXPECTED, val->name);
936 /* if it is not a specifier then we can assume that */
937 /* it will be an unsigned long */
938 if (!IS_SPEC (val->type))
939 return (double) SPEC_CVAL (val->etype).v_ulong;
941 if (SPEC_NOUN (val->etype) == V_FLOAT)
942 return (double) SPEC_CVAL (val->etype).v_float;
944 if (SPEC_LONG (val->etype))
946 if (SPEC_USIGN (val->etype))
947 return (double) SPEC_CVAL (val->etype).v_ulong;
949 return (double) SPEC_CVAL (val->etype).v_long;
952 if (SPEC_NOUN (val->etype) == V_INT) {
953 if (SPEC_USIGN (val->etype))
954 return (double) SPEC_CVAL (val->etype).v_uint;
956 return (double) SPEC_CVAL (val->etype).v_int;
959 if (SPEC_NOUN (val->etype) == V_CHAR) {
960 if (SPEC_USIGN (val->etype))
961 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
963 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
966 if (IS_BITVAR(val->etype)) {
967 return (double) SPEC_CVAL (val->etype).v_uint;
970 if (SPEC_NOUN (val->etype) == V_VOID) {
971 return (double) SPEC_CVAL (val->etype).v_ulong;
975 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
976 "floatFromVal: unknown value");
980 /*------------------------------------------------------------------*/
981 /* valUnaryPM - does the unary +/- operation on a constant */
982 /*------------------------------------------------------------------*/
984 valUnaryPM (value * val)
986 /* depending on type */
987 if (SPEC_NOUN (val->etype) == V_FLOAT)
988 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
991 if (SPEC_LONG (val->etype))
993 if (SPEC_USIGN (val->etype))
994 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
996 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1000 if (SPEC_USIGN (val->etype))
1001 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1003 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1006 // -(unsigned 3) now really is signed
1007 SPEC_USIGN(val->etype)=0;
1008 // -(unsigned char)135 now really is an int
1009 if (SPEC_NOUN(val->etype) == V_CHAR) {
1010 if (SPEC_CVAL(val->etype).v_int < -128) {
1011 SPEC_NOUN(val->etype) = V_INT;
1017 /*------------------------------------------------------------------*/
1018 /* valueComplement - complements a constant */
1019 /*------------------------------------------------------------------*/
1021 valComplement (value * val)
1023 /* depending on type */
1024 if (SPEC_LONG (val->etype))
1026 if (SPEC_USIGN (val->etype))
1027 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1029 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1033 if (SPEC_USIGN (val->etype))
1034 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1036 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1038 // ~(unsigned 3) now really is signed
1039 SPEC_USIGN(val->etype)=0;
1043 /*------------------------------------------------------------------*/
1044 /* valueNot - complements a constant */
1045 /*------------------------------------------------------------------*/
1047 valNot (value * val)
1049 /* depending on type */
1050 if (SPEC_LONG (val->etype))
1052 if (SPEC_USIGN (val->etype))
1053 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1055 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1059 if (SPEC_USIGN (val->etype))
1060 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1062 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1067 /*------------------------------------------------------------------*/
1068 /* valMult - multiply constants */
1069 /*------------------------------------------------------------------*/
1071 valMult (value * lval, value * rval)
1075 /* create a new value */
1077 val->type = val->etype = newLink (SPECIFIER);
1078 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1079 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1080 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1081 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1082 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1085 if (IS_FLOAT (val->type))
1086 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1087 /* signed and unsigned mul are the same, as long as the precision of the
1088 result isn't bigger than the precision of the operands. */
1089 else if (SPEC_LONG (val->type))
1090 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1091 (TYPE_UDWORD) floatFromVal (rval);
1092 else if (SPEC_USIGN (val->type)) /* unsigned int */
1094 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1095 (TYPE_UWORD) floatFromVal (rval);
1097 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1098 if (ul != (TYPE_UWORD) ul)
1101 else /* signed int */
1103 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1104 (TYPE_WORD) floatFromVal (rval);
1106 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1107 if (l != (TYPE_WORD) l)
1110 return cheapestVal (val);
1113 /*------------------------------------------------------------------*/
1114 /* valDiv - Divide constants */
1115 /*------------------------------------------------------------------*/
1117 valDiv (value * lval, value * rval)
1121 if (floatFromVal (rval) == 0)
1123 werror (E_DIVIDE_BY_ZERO);
1127 /* create a new value */
1129 val->type = val->etype = newLink(SPECIFIER);
1130 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1131 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1132 SPEC_SCLS (val->etype) = S_LITERAL;
1133 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1134 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1138 if (IS_FLOAT (val->type))
1139 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1140 else if (SPEC_LONG (val->type))
1142 if (SPEC_USIGN (val->type))
1143 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1144 (TYPE_UDWORD) floatFromVal (rval);
1146 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1147 (TYPE_DWORD) floatFromVal (rval);
1151 if (SPEC_USIGN (val->type))
1152 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1153 (TYPE_UWORD) floatFromVal (rval);
1155 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1156 (TYPE_WORD) floatFromVal (rval);
1158 return cheapestVal (val);
1161 /*------------------------------------------------------------------*/
1162 /* valMod - Modulus constants */
1163 /*------------------------------------------------------------------*/
1165 valMod (value * lval, value * rval)
1169 /* create a new value */
1171 val->type = val->etype = newLink (SPECIFIER);
1172 SPEC_NOUN (val->type) = V_INT; /* type is int */
1173 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1174 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1175 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1179 if (SPEC_LONG (val->type))
1181 if (SPEC_USIGN (val->type))
1182 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1183 (TYPE_UDWORD) floatFromVal (rval);
1185 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1186 (TYPE_DWORD) floatFromVal (rval);
1190 if (SPEC_USIGN (val->type))
1191 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1192 (TYPE_UWORD) floatFromVal (rval);
1194 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1195 (TYPE_WORD) floatFromVal (rval);
1197 return cheapestVal (val);
1200 /*------------------------------------------------------------------*/
1201 /* valPlus - Addition constants */
1202 /*------------------------------------------------------------------*/
1204 valPlus (value * lval, value * rval)
1208 /* create a new value */
1210 val->type = val->etype = newLink (SPECIFIER);
1211 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1212 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1213 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1214 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1215 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1218 if (IS_FLOAT (val->type))
1219 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1220 else if (SPEC_LONG (val->type))
1222 if (SPEC_USIGN (val->type))
1223 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1224 (TYPE_UDWORD) floatFromVal (rval);
1226 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1227 (TYPE_DWORD) floatFromVal (rval);
1231 if (SPEC_USIGN (val->type))
1232 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1233 (TYPE_UWORD) floatFromVal (rval);
1235 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1236 (TYPE_WORD) floatFromVal (rval);
1238 return cheapestVal (val);
1241 /*------------------------------------------------------------------*/
1242 /* valMinus - Addition constants */
1243 /*------------------------------------------------------------------*/
1245 valMinus (value * lval, value * rval)
1249 /* create a new value */
1251 val->type = val->etype = newLink (SPECIFIER);
1252 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1253 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1254 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1255 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1256 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1259 if (IS_FLOAT (val->type))
1260 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1261 else if (SPEC_LONG (val->type))
1263 if (SPEC_USIGN (val->type))
1264 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1265 (TYPE_UDWORD) floatFromVal (rval);
1267 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1268 (TYPE_DWORD) floatFromVal (rval);
1272 if (SPEC_USIGN (val->type))
1273 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1274 (TYPE_UWORD) floatFromVal (rval);
1276 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1277 (TYPE_WORD) floatFromVal (rval);
1279 return cheapestVal (val);
1282 /*------------------------------------------------------------------*/
1283 /* valShift - Shift left or right */
1284 /*------------------------------------------------------------------*/
1286 valShift (value * lval, value * rval, int lr)
1290 /* create a new value */
1292 val->type = val->etype = newIntLink ();
1293 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1294 SPEC_NOUN (val->etype) = V_INT;
1295 /* 'unsigned char' promotes to 'signed int' */
1296 if (!IS_CHAR (lval->etype))
1297 SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1298 SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1300 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1303 /* right shift and unsigned */
1304 (!lr && SPEC_USIGN (rval->type))))
1306 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1309 if (SPEC_LONG (val->type))
1311 if (SPEC_USIGN (val->type))
1313 SPEC_CVAL (val->type).v_ulong = lr ?
1314 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1315 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1319 SPEC_CVAL (val->type).v_long = lr ?
1320 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1321 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1326 if (SPEC_USIGN (val->type))
1328 SPEC_CVAL (val->type).v_uint = lr ?
1329 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1330 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1334 SPEC_CVAL (val->type).v_int = lr ?
1335 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1336 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1339 return cheapestVal (val);
1342 /*------------------------------------------------------------------*/
1343 /* valCompare- Compares two literal */
1344 /*------------------------------------------------------------------*/
1346 valCompare (value * lval, value * rval, int ctype)
1350 /* create a new value */
1352 val->type = val->etype = newCharLink ();
1353 val->type->class = SPECIFIER;
1354 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1355 SPEC_USIGN (val->type) = 1;
1356 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1361 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1365 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1369 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1373 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1377 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1378 SPEC_NOUN(rval->type) == V_FLOAT)
1380 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1384 /* integrals: ignore signedness */
1387 l = (TYPE_UDWORD) floatFromVal (lval);
1388 r = (TYPE_UDWORD) floatFromVal (rval);
1389 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1390 neccessary to strip them to 16 bit.
1391 Literals are reduced to their cheapest type, therefore left and
1392 right might have different types. It's neccessary to find a
1393 common type: int (used for char too) or long */
1394 if (!IS_LONG (lval->etype) &&
1395 !IS_LONG (rval->etype))
1400 SPEC_CVAL (val->type).v_int = l == r;
1404 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1405 SPEC_NOUN(rval->type) == V_FLOAT)
1407 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1411 /* integrals: ignore signedness */
1414 l = (TYPE_UDWORD) floatFromVal (lval);
1415 r = (TYPE_UDWORD) floatFromVal (rval);
1416 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1417 neccessary to strip them to 16 bit.
1418 Literals are reduced to their cheapest type, therefore left and
1419 right might have different types. It's neccessary to find a
1420 common type: int (used for char too) or long */
1421 if (!IS_LONG (lval->etype) &&
1422 !IS_LONG (rval->etype))
1427 SPEC_CVAL (val->type).v_int = l != r;
1436 /*------------------------------------------------------------------*/
1437 /* valBitwise - Bitwise operation */
1438 /*------------------------------------------------------------------*/
1440 valBitwise (value * lval, value * rval, int op)
1444 /* create a new value */
1446 val->type = computeType (lval->etype, rval->etype, FALSE);
1447 val->etype = getSpec (val->type);
1448 SPEC_SCLS (val->etype) = S_LITERAL;
1453 if (SPEC_LONG (val->type))
1455 if (SPEC_USIGN (val->type))
1456 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1457 (TYPE_UDWORD) floatFromVal (rval);
1459 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1460 (TYPE_DWORD) floatFromVal (rval);
1464 if (SPEC_USIGN (val->type))
1465 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1466 (TYPE_UWORD) floatFromVal (rval);
1468 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1473 if (SPEC_LONG (val->type))
1475 if (SPEC_USIGN (val->type))
1476 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1477 (TYPE_UDWORD) floatFromVal (rval);
1479 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1480 (TYPE_DWORD) floatFromVal (rval);
1484 if (SPEC_USIGN (val->type))
1485 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1486 (TYPE_UWORD) floatFromVal (rval);
1488 SPEC_CVAL (val->type).v_int =
1489 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1495 if (SPEC_LONG (val->type))
1497 if (SPEC_USIGN (val->type))
1498 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1499 (TYPE_UDWORD) floatFromVal (rval);
1501 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1502 (TYPE_DWORD) floatFromVal (rval);
1506 if (SPEC_USIGN (val->type))
1507 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1508 (TYPE_UWORD) floatFromVal (rval);
1510 SPEC_CVAL (val->type).v_int =
1511 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1516 return cheapestVal(val);
1519 /*------------------------------------------------------------------*/
1520 /* valAndOr - Generates code for and / or operation */
1521 /*------------------------------------------------------------------*/
1523 valLogicAndOr (value * lval, value * rval, int op)
1527 /* create a new value */
1529 val->type = val->etype = newCharLink ();
1530 val->type->class = SPECIFIER;
1531 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1532 SPEC_USIGN (val->type) = 1;
1537 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1541 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1549 /*------------------------------------------------------------------*/
1550 /* valCastLiteral - casts a literal value to another type */
1551 /*------------------------------------------------------------------*/
1553 valCastLiteral (sym_link * dtype, double fval)
1556 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1562 val->etype = getSpec (val->type = copyLinkChain (dtype));
1563 SPEC_SCLS (val->etype) = S_LITERAL;
1565 /* if it is not a specifier then we can assume that */
1566 /* it will be an unsigned long */
1567 if (!IS_SPEC (val->type)) {
1568 SPEC_CVAL (val->etype).v_ulong = l;
1572 if (SPEC_NOUN (val->etype) == V_FLOAT)
1573 SPEC_CVAL (val->etype).v_float = fval;
1574 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1575 if (SPEC_USIGN (val->etype))
1576 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1578 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1580 if (SPEC_LONG (val->etype)) {
1581 if (SPEC_USIGN (val->etype))
1582 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1584 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1586 if (SPEC_USIGN (val->etype))
1587 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1589 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1595 /*------------------------------------------------------------------*/
1596 /* getNelements - determines # of elements from init list */
1597 /*------------------------------------------------------------------*/
1599 getNelements (sym_link * type, initList * ilist)
1606 if (ilist->type == INIT_DEEP)
1607 ilist = ilist->init.deep;
1609 /* if type is a character array and there is only one
1610 (string) initialiser then get the length of the string */
1611 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1613 ast *iast = ilist->init.node;
1614 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1617 werror (E_CONST_EXPECTED);
1621 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1622 // yep, it's a string
1624 return DCL_ELEM (v->type);
1632 ilist = ilist->next;
1637 /*-----------------------------------------------------------------*/
1638 /* valForArray - returns a value with name of array index */
1639 /*-----------------------------------------------------------------*/
1641 valForArray (ast * arrExpr)
1643 value *val, *lval = NULL;
1645 int size = getSize (arrExpr->left->ftype->next);
1646 /* if the right or left is an array
1648 if (IS_AST_OP (arrExpr->left))
1650 if (arrExpr->left->opval.op == '[')
1651 lval = valForArray (arrExpr->left);
1652 else if (arrExpr->left->opval.op == '.')
1653 lval = valForStructElem (arrExpr->left->left,
1654 arrExpr->left->right);
1655 else if (arrExpr->left->opval.op == PTR_OP &&
1656 IS_ADDRESS_OF_OP (arrExpr->left->left))
1657 lval = valForStructElem (arrExpr->left->left->left,
1658 arrExpr->left->right);
1663 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1666 if (!IS_AST_LIT_VALUE (arrExpr->right))
1672 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1676 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1679 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1680 (int) AST_LIT_VALUE (arrExpr->right) * size);
1682 val->type = newLink (DECLARATOR);
1683 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1684 DCL_TYPE (val->type) = CPOINTER;
1685 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1686 DCL_TYPE (val->type) = FPOINTER;
1687 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1688 DCL_TYPE (val->type) = PPOINTER;
1689 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1690 DCL_TYPE (val->type) = IPOINTER;
1691 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1692 DCL_TYPE (val->type) = EEPPOINTER;
1694 DCL_TYPE (val->type) = POINTER;
1695 val->type->next = arrExpr->left->ftype;
1696 val->etype = getSpec (val->type);
1700 /*-----------------------------------------------------------------*/
1701 /* valForStructElem - returns value with name of struct element */
1702 /*-----------------------------------------------------------------*/
1704 valForStructElem (ast * structT, ast * elemT)
1706 value *val, *lval = NULL;
1710 /* left could be furthur derefed */
1711 if (IS_AST_OP (structT))
1713 if (structT->opval.op == '[')
1714 lval = valForArray (structT);
1715 else if (structT->opval.op == '.')
1716 lval = valForStructElem (structT->left, structT->right);
1717 else if (structT->opval.op == PTR_OP &&
1718 IS_ADDRESS_OF_OP (structT->left))
1719 lval = valForStructElem (structT->left->left,
1725 if (!IS_AST_SYM_VALUE (elemT))
1728 if (!IS_STRUCT (structT->etype))
1731 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1732 AST_SYMBOL (elemT))) == NULL)
1740 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1744 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1747 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1750 val->type = newLink (DECLARATOR);
1751 if (SPEC_SCLS (structT->etype) == S_CODE)
1752 DCL_TYPE (val->type) = CPOINTER;
1753 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1754 DCL_TYPE (val->type) = FPOINTER;
1755 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1756 DCL_TYPE (val->type) = PPOINTER;
1757 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1758 DCL_TYPE (val->type) = IPOINTER;
1759 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1760 DCL_TYPE (val->type) = EEPPOINTER;
1762 DCL_TYPE (val->type) = POINTER;
1763 val->type->next = sym->type;
1764 val->etype = getSpec (val->type);
1768 /*-----------------------------------------------------------------*/
1769 /* valForCastAggr - will return value for a cast of an aggregate */
1770 /* plus minus a constant */
1771 /*-----------------------------------------------------------------*/
1773 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1777 if (!IS_AST_SYM_VALUE (aexpr))
1779 if (!IS_AST_LIT_VALUE (cnst))
1784 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1785 AST_SYMBOL (aexpr)->rname, op,
1786 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1789 val->etype = getSpec (val->type);
1793 /*-----------------------------------------------------------------*/
1794 /* valForCastAggr - will return value for a cast of an aggregate */
1795 /* with no constant */
1796 /*-----------------------------------------------------------------*/
1798 valForCastArr (ast * aexpr, sym_link * type)
1802 if (!IS_AST_SYM_VALUE (aexpr))
1807 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1808 AST_SYMBOL (aexpr)->rname);
1811 val->etype = getSpec (val->type);