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_INT;
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;
1047 if (SPEC_NOUN(val->etype) == V_CHAR)
1048 if ( SPEC_CVAL(val->etype).v_int < -128
1049 || SPEC_CVAL(val->etype).v_int > 127)
1050 SPEC_NOUN(val->etype) = V_INT;
1052 // ~(unsigned 3) now really is signed
1053 SPEC_USIGN(val->etype)=0;
1057 /*------------------------------------------------------------------*/
1058 /* valueNot - complements a constant */
1059 /*------------------------------------------------------------------*/
1061 valNot (value * val)
1063 /* depending on type */
1064 if (SPEC_LONG (val->etype))
1066 if (SPEC_USIGN (val->etype))
1067 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1069 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1073 if (SPEC_USIGN (val->etype))
1074 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1076 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1081 /*------------------------------------------------------------------*/
1082 /* valMult - multiply constants */
1083 /*------------------------------------------------------------------*/
1085 valMult (value * lval, value * rval)
1089 /* create a new value */
1091 val->type = val->etype = computeType (lval->etype,
1095 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1097 if (IS_FLOAT (val->type))
1098 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1099 /* signed and unsigned mul are the same, as long as the precision of the
1100 result isn't bigger than the precision of the operands. */
1101 else if (SPEC_LONG (val->type))
1102 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1103 (TYPE_UDWORD) floatFromVal (rval);
1104 else if (SPEC_USIGN (val->type)) /* unsigned int */
1106 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1107 (TYPE_UWORD) floatFromVal (rval);
1109 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1110 if (ul != (TYPE_UWORD) ul)
1113 else /* signed int */
1115 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1116 (TYPE_WORD) floatFromVal (rval);
1118 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1119 if (l != (TYPE_WORD) l)
1122 return cheapestVal (val);
1125 /*------------------------------------------------------------------*/
1126 /* valDiv - Divide constants */
1127 /*------------------------------------------------------------------*/
1129 valDiv (value * lval, value * rval)
1133 if (floatFromVal (rval) == 0)
1135 werror (E_DIVIDE_BY_ZERO);
1139 /* create a new value */
1141 val->type = val->etype = computeType (lval->etype,
1145 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1147 if (IS_FLOAT (val->type))
1148 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1149 else if (SPEC_LONG (val->type))
1151 if (SPEC_USIGN (val->type))
1152 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1153 (TYPE_UDWORD) floatFromVal (rval);
1155 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1156 (TYPE_DWORD) floatFromVal (rval);
1160 if (SPEC_USIGN (val->type))
1161 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1162 (TYPE_UWORD) floatFromVal (rval);
1164 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1165 (TYPE_WORD) floatFromVal (rval);
1167 return cheapestVal (val);
1170 /*------------------------------------------------------------------*/
1171 /* valMod - Modulus constants */
1172 /*------------------------------------------------------------------*/
1174 valMod (value * lval, value * rval)
1178 /* create a new value */
1180 val->type = val->etype = computeType (lval->etype,
1184 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1186 if (SPEC_LONG (val->type))
1188 if (SPEC_USIGN (val->type))
1189 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1190 (TYPE_UDWORD) floatFromVal (rval);
1192 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1193 (TYPE_DWORD) floatFromVal (rval);
1197 if (SPEC_USIGN (val->type))
1198 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1199 (TYPE_UWORD) floatFromVal (rval);
1201 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1202 (TYPE_WORD) floatFromVal (rval);
1204 return cheapestVal (val);
1207 /*------------------------------------------------------------------*/
1208 /* valPlus - Addition constants */
1209 /*------------------------------------------------------------------*/
1211 valPlus (value * lval, value * rval)
1215 /* create a new value */
1217 val->type = val->etype = computeType (lval->etype,
1221 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1223 if (IS_FLOAT (val->type))
1224 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1225 else if (SPEC_LONG (val->type))
1227 if (SPEC_USIGN (val->type))
1228 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1229 (TYPE_UDWORD) floatFromVal (rval);
1231 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1232 (TYPE_DWORD) floatFromVal (rval);
1236 if (SPEC_USIGN (val->type))
1237 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1238 (TYPE_UWORD) floatFromVal (rval);
1240 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1241 (TYPE_WORD) floatFromVal (rval);
1243 return cheapestVal (val);
1246 /*------------------------------------------------------------------*/
1247 /* valMinus - Addition constants */
1248 /*------------------------------------------------------------------*/
1250 valMinus (value * lval, value * rval)
1254 /* create a new value */
1256 val->type = val->etype = computeType (lval->etype,
1260 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1262 if (IS_FLOAT (val->type))
1263 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1264 else if (SPEC_LONG (val->type))
1266 if (SPEC_USIGN (val->type))
1267 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1268 (TYPE_UDWORD) floatFromVal (rval);
1270 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1271 (TYPE_DWORD) floatFromVal (rval);
1275 if (SPEC_USIGN (val->type))
1276 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1277 (TYPE_UWORD) floatFromVal (rval);
1279 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1280 (TYPE_WORD) floatFromVal (rval);
1282 return cheapestVal (val);
1285 /*------------------------------------------------------------------*/
1286 /* valShift - Shift left or right */
1287 /*------------------------------------------------------------------*/
1289 valShift (value * lval, value * rval, int lr)
1293 /* create a new value */
1295 val->type = val->etype = computeType (lval->etype,
1299 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1301 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1304 /* right shift and unsigned */
1305 (!lr && SPEC_USIGN (rval->type))))
1307 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1310 if (SPEC_LONG (val->type))
1312 if (SPEC_USIGN (val->type))
1314 SPEC_CVAL (val->type).v_ulong = lr ?
1315 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1316 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1320 SPEC_CVAL (val->type).v_long = lr ?
1321 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1322 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1327 if (SPEC_USIGN (val->type))
1329 SPEC_CVAL (val->type).v_uint = lr ?
1330 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1331 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1335 SPEC_CVAL (val->type).v_int = lr ?
1336 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1337 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1340 return cheapestVal (val);
1343 /*------------------------------------------------------------------*/
1344 /* valCompare- Compares two literal */
1345 /*------------------------------------------------------------------*/
1347 valCompare (value * lval, value * rval, int ctype)
1351 /* create a new value */
1353 val->type = val->etype = newCharLink ();
1354 val->type->class = SPECIFIER;
1355 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1356 SPEC_USIGN (val->type) = 1;
1357 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1362 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1366 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1370 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1374 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1378 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1379 SPEC_NOUN(rval->type) == V_FLOAT)
1381 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1385 /* integrals: ignore signedness */
1388 l = (TYPE_UDWORD) floatFromVal (lval);
1389 r = (TYPE_UDWORD) floatFromVal (rval);
1390 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1391 neccessary to strip them to 16 bit.
1392 Literals are reduced to their cheapest type, therefore left and
1393 right might have different types. It's neccessary to find a
1394 common type: int (used for char too) or long */
1395 if (!IS_LONG (lval->etype) &&
1396 !IS_LONG (rval->etype))
1401 SPEC_CVAL (val->type).v_int = l == r;
1405 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1406 SPEC_NOUN(rval->type) == V_FLOAT)
1408 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1412 /* integrals: ignore signedness */
1415 l = (TYPE_UDWORD) floatFromVal (lval);
1416 r = (TYPE_UDWORD) floatFromVal (rval);
1417 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1418 neccessary to strip them to 16 bit.
1419 Literals are reduced to their cheapest type, therefore left and
1420 right might have different types. It's neccessary to find a
1421 common type: int (used for char too) or long */
1422 if (!IS_LONG (lval->etype) &&
1423 !IS_LONG (rval->etype))
1428 SPEC_CVAL (val->type).v_int = l != r;
1437 /*------------------------------------------------------------------*/
1438 /* valBitwise - Bitwise operation */
1439 /*------------------------------------------------------------------*/
1441 valBitwise (value * lval, value * rval, int op)
1445 /* create a new value */
1447 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1448 val->etype = getSpec (val->type);
1449 SPEC_SCLS (val->etype) = S_LITERAL;
1454 if (SPEC_LONG (val->type))
1456 if (SPEC_USIGN (val->type))
1457 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1458 (TYPE_UDWORD) floatFromVal (rval);
1460 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1461 (TYPE_DWORD) floatFromVal (rval);
1465 if (SPEC_USIGN (val->type))
1466 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1467 (TYPE_UWORD) floatFromVal (rval);
1469 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1474 if (SPEC_LONG (val->type))
1476 if (SPEC_USIGN (val->type))
1477 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1478 (TYPE_UDWORD) floatFromVal (rval);
1480 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1481 (TYPE_DWORD) floatFromVal (rval);
1485 if (SPEC_USIGN (val->type))
1486 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1487 (TYPE_UWORD) floatFromVal (rval);
1489 SPEC_CVAL (val->type).v_int =
1490 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1496 if (SPEC_LONG (val->type))
1498 if (SPEC_USIGN (val->type))
1499 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1500 (TYPE_UDWORD) floatFromVal (rval);
1502 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1503 (TYPE_DWORD) floatFromVal (rval);
1507 if (SPEC_USIGN (val->type))
1508 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1509 (TYPE_UWORD) floatFromVal (rval);
1511 SPEC_CVAL (val->type).v_int =
1512 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1517 return cheapestVal(val);
1520 /*------------------------------------------------------------------*/
1521 /* valAndOr - Generates code for and / or operation */
1522 /*------------------------------------------------------------------*/
1524 valLogicAndOr (value * lval, value * rval, int op)
1528 /* create a new value */
1530 val->type = val->etype = newCharLink ();
1531 val->type->class = SPECIFIER;
1532 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1533 SPEC_USIGN (val->type) = 1;
1538 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1542 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1550 /*------------------------------------------------------------------*/
1551 /* valCastLiteral - casts a literal value to another type */
1552 /*------------------------------------------------------------------*/
1554 valCastLiteral (sym_link * dtype, double fval)
1557 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1563 val->etype = getSpec (val->type = copyLinkChain (dtype));
1564 SPEC_SCLS (val->etype) = S_LITERAL;
1566 /* if it is not a specifier then we can assume that */
1567 /* it will be an unsigned long */
1568 if (!IS_SPEC (val->type)) {
1569 SPEC_CVAL (val->etype).v_ulong = l;
1573 if (SPEC_NOUN (val->etype) == V_FLOAT)
1574 SPEC_CVAL (val->etype).v_float = fval;
1575 else if (SPEC_NOUN (val->etype) == V_BIT ||
1576 SPEC_NOUN (val->etype) == V_SBIT)
1577 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1578 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1579 SPEC_CVAL (val->etype).v_uint = l &
1580 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1581 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1582 if (SPEC_USIGN (val->etype))
1583 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1585 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1587 if (SPEC_LONG (val->etype)) {
1588 if (SPEC_USIGN (val->etype))
1589 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1591 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1593 if (SPEC_USIGN (val->etype))
1594 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1596 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1602 /*------------------------------------------------------------------*/
1603 /* getNelements - determines # of elements from init list */
1604 /*------------------------------------------------------------------*/
1606 getNelements (sym_link * type, initList * ilist)
1613 if (ilist->type == INIT_DEEP)
1614 ilist = ilist->init.deep;
1616 /* if type is a character array and there is only one
1617 (string) initialiser then get the length of the string */
1618 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1620 ast *iast = ilist->init.node;
1621 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1624 werror (E_CONST_EXPECTED);
1628 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1629 // yep, it's a string
1631 return DCL_ELEM (v->type);
1639 ilist = ilist->next;
1644 /*-----------------------------------------------------------------*/
1645 /* valForArray - returns a value with name of array index */
1646 /*-----------------------------------------------------------------*/
1648 valForArray (ast * arrExpr)
1650 value *val, *lval = NULL;
1652 int size = getSize (arrExpr->left->ftype->next);
1653 /* if the right or left is an array
1655 if (IS_AST_OP (arrExpr->left))
1657 if (arrExpr->left->opval.op == '[')
1658 lval = valForArray (arrExpr->left);
1659 else if (arrExpr->left->opval.op == '.')
1660 lval = valForStructElem (arrExpr->left->left,
1661 arrExpr->left->right);
1662 else if (arrExpr->left->opval.op == PTR_OP &&
1663 IS_ADDRESS_OF_OP (arrExpr->left->left))
1664 lval = valForStructElem (arrExpr->left->left->left,
1665 arrExpr->left->right);
1670 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1673 if (!IS_AST_LIT_VALUE (arrExpr->right))
1679 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1683 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1686 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1687 (int) AST_LIT_VALUE (arrExpr->right) * size);
1689 val->type = newLink (DECLARATOR);
1690 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1691 DCL_TYPE (val->type) = CPOINTER;
1692 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1693 DCL_TYPE (val->type) = FPOINTER;
1694 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1695 DCL_TYPE (val->type) = PPOINTER;
1696 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1697 DCL_TYPE (val->type) = IPOINTER;
1698 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1699 DCL_TYPE (val->type) = EEPPOINTER;
1701 DCL_TYPE (val->type) = POINTER;
1702 val->type->next = arrExpr->left->ftype->next;
1703 val->etype = getSpec (val->type);
1707 /*-----------------------------------------------------------------*/
1708 /* valForStructElem - returns value with name of struct element */
1709 /*-----------------------------------------------------------------*/
1711 valForStructElem (ast * structT, ast * elemT)
1713 value *val, *lval = NULL;
1717 /* left could be furthur derefed */
1718 if (IS_AST_OP (structT))
1720 if (structT->opval.op == '[')
1721 lval = valForArray (structT);
1722 else if (structT->opval.op == '.')
1723 lval = valForStructElem (structT->left, structT->right);
1724 else if (structT->opval.op == PTR_OP &&
1725 IS_ADDRESS_OF_OP (structT->left))
1726 lval = valForStructElem (structT->left->left,
1732 if (!IS_AST_SYM_VALUE (elemT))
1735 if (!IS_STRUCT (structT->etype))
1738 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1739 AST_SYMBOL (elemT))) == NULL)
1747 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1751 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1754 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1757 val->type = newLink (DECLARATOR);
1758 if (SPEC_SCLS (structT->etype) == S_CODE)
1759 DCL_TYPE (val->type) = CPOINTER;
1760 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1761 DCL_TYPE (val->type) = FPOINTER;
1762 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1763 DCL_TYPE (val->type) = PPOINTER;
1764 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1765 DCL_TYPE (val->type) = IPOINTER;
1766 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1767 DCL_TYPE (val->type) = EEPPOINTER;
1769 DCL_TYPE (val->type) = POINTER;
1770 val->type->next = sym->type;
1771 val->etype = getSpec (val->type);
1775 /*-----------------------------------------------------------------*/
1776 /* valForCastAggr - will return value for a cast of an aggregate */
1777 /* plus minus a constant */
1778 /*-----------------------------------------------------------------*/
1780 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1784 if (!IS_AST_SYM_VALUE (aexpr))
1786 if (!IS_AST_LIT_VALUE (cnst))
1791 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1792 AST_SYMBOL (aexpr)->rname, op,
1793 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1796 val->etype = getSpec (val->type);
1800 /*-----------------------------------------------------------------*/
1801 /* valForCastAggr - will return value for a cast of an aggregate */
1802 /* with no constant */
1803 /*-----------------------------------------------------------------*/
1805 valForCastArr (ast * aexpr, sym_link * type)
1809 if (!IS_AST_SYM_VALUE (aexpr))
1814 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1815 AST_SYMBOL (aexpr)->rname);
1818 val->etype = getSpec (val->type);