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_TYPE_NONE)))
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_FIXED(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_FIXED (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 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
466 /*-----------------------------------------------------------------*/
468 constFixed16x16Val (char *s)
470 value *val = newValue ();
473 if (sscanf (s, "%lf", &sval) != 1)
475 werror (E_INVALID_FLOAT_CONST, s);
476 return constVal ("0");
479 val->type = val->etype = newLink (SPECIFIER);
480 SPEC_NOUN (val->type) = V_FLOAT;
481 SPEC_SCLS (val->type) = S_LITERAL;
482 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
487 /*-----------------------------------------------------------------*/
488 /* constVal - converts an INTEGER constant into a cheapest value */
489 /*-----------------------------------------------------------------*/
490 value *constVal (char *s)
493 short hex = 0, octal = 0;
498 val = newValue (); /* alloc space for value */
500 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
501 SPEC_SCLS (val->type) = S_LITERAL;
502 // let's start with a signed char
503 SPEC_NOUN (val->type) = V_CHAR;
504 SPEC_USIGN (val->type) = 0;
506 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
508 /* set the octal flag */
509 if (!hex && *s == '0' && *(s + 1))
512 /* create the scan string */
513 scanFmt[scI++] = '%';
515 scanFmt[scI++] = 'l';
518 scanFmt[scI++] = 'o';
520 scanFmt[scI++] = 'x';
522 scanFmt[scI++] = 'f';
524 scanFmt[scI++] = '\0';
528 sscanf (s, scanFmt, &sval);
531 sscanf (s, scanFmt, &dval);
534 /* Setup the flags first */
535 /* set the _long flag if 'lL' is found */
536 if (strchr (s, 'l') || strchr (s, 'L')) {
537 SPEC_NOUN (val->type) = V_INT;
538 SPEC_LONG (val->type) = 1;
541 /* set the unsigned flag if 'uU' is found */
542 if (strchr (s, 'u') || strchr (s, 'U')) {
543 SPEC_USIGN (val->type) = 1;
546 if (dval<0) { // "-28u" will still be signed and negative
547 if (dval<-128) { // check if we have to promote to int
548 SPEC_NOUN (val->type) = V_INT;
550 if (dval<-32768) { // check if we have to promote to long int
551 SPEC_LONG (val->type) = 1;
554 if (dval>0xff || /* check if we have to promote to int */
555 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
556 char. After an integral promotion it will
557 be a signed int; this certainly isn't what
558 the programer wants */
559 SPEC_NOUN (val->type) = V_INT;
561 else { /* store char's always as unsigned; this helps other optimizations */
562 SPEC_USIGN (val->type) = 1;
564 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
565 SPEC_LONG (val->type) = 1;
567 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
568 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
570 SPEC_USIGN (val->type) = 1;
572 SPEC_LONG (val->type) = 1;
573 if (dval>0x7fffffff) {
574 SPEC_USIGN (val->type) = 1;
580 if (SPEC_LONG (val->type))
582 if (SPEC_USIGN (val->type))
584 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
588 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
593 if (SPEC_USIGN (val->type))
595 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
599 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
606 /*! /fn char hexEscape(char **src)
608 /param src Pointer to 'x' from start of hex character value
611 unsigned char hexEscape(char **src)
614 unsigned long value ;
616 (*src)++ ; /* Skip over the 'x' */
617 s = *src ; /* Save for error detection */
619 value = strtol (*src, src, 16);
622 // no valid hex found
623 werror(E_INVALID_HEX);
626 werror(W_ESC_SEQ_OOR_FOR_CHAR);
632 /*------------------------------------------------------------------*/
633 /* octalEscape - process an octal constant of max three digits */
634 /* return the octal value, throw a warning for illegal octal */
635 /* adjust src to point at the last proccesed char */
636 /*------------------------------------------------------------------*/
638 unsigned char octalEscape (char **str) {
642 for (digits=0; digits<3; digits++) {
643 if (**str>='0' && **str<='7') {
644 value = value*8 + (**str-'0');
651 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
652 werror (W_ESC_SEQ_OOR_FOR_CHAR);
659 /fn int copyStr (char *dest, char *src)
661 Copies a source string to a dest buffer interpreting escape sequences
662 and special characters
664 /param dest Buffer to receive the resultant string
665 /param src Buffer containing the source string with escape sequecnes
666 /return Number of characters in output string
671 copyStr (char *dest, char *src)
674 char *OriginalDest = dest ;
680 else if (*src == '\\')
715 *dest++ = octalEscape(&src);
720 *dest++ = hexEscape(&src) ;
747 return dest - OriginalDest ;
750 /*------------------------------------------------------------------*/
751 /* strVal - converts a string constant to a value */
752 /*------------------------------------------------------------------*/
758 val = newValue (); /* get a new one */
760 /* get a declarator */
761 val->type = newLink (DECLARATOR);
762 DCL_TYPE (val->type) = ARRAY;
763 val->type->next = val->etype = newLink (SPECIFIER);
764 SPEC_NOUN (val->etype) = V_CHAR;
765 SPEC_SCLS (val->etype) = S_LITERAL;
767 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
768 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
774 /*------------------------------------------------------------------*/
775 /* reverseValWithType - reverses value chain with type & etype */
776 /*------------------------------------------------------------------*/
778 reverseValWithType (value * val)
786 /* save the type * etype chains */
790 /* set the current one 2b null */
791 val->type = val->etype = NULL;
792 val = reverseVal (val);
794 /* restore type & etype */
801 /*------------------------------------------------------------------*/
802 /* reverseVal - reverses the values for a value chain */
803 /*------------------------------------------------------------------*/
805 reverseVal (value * val)
807 value *prev, *curr, *next;
822 val->next = (void *) NULL;
826 /*------------------------------------------------------------------*/
827 /* copyValueChain - will copy a chain of values */
828 /*------------------------------------------------------------------*/
830 copyValueChain (value * src)
837 dest = copyValue (src);
838 dest->next = copyValueChain (src->next);
843 /*------------------------------------------------------------------*/
844 /* copyValue - copies contents of a value to a fresh one */
845 /*------------------------------------------------------------------*/
847 copyValue (value * src)
852 dest->sym = copySymbol (src->sym);
853 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
854 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
855 dest->etype = (src->type ? getSpec (dest->type) : NULL);
860 /*------------------------------------------------------------------*/
861 /* charVal - converts a character constant to a value */
862 /*------------------------------------------------------------------*/
870 val->type = val->etype = newLink (SPECIFIER);
871 SPEC_NOUN (val->type) = V_CHAR;
872 SPEC_USIGN(val->type) = 1;
873 SPEC_SCLS (val->type) = S_LITERAL;
875 s++; /* get rid of quotation */
876 /* if \ then special processing */
879 s++; /* go beyond the backslash */
883 SPEC_CVAL (val->type).v_uint = '\n';
886 SPEC_CVAL (val->type).v_uint = '\t';
889 SPEC_CVAL (val->type).v_uint = '\v';
892 SPEC_CVAL (val->type).v_uint = '\b';
895 SPEC_CVAL (val->type).v_uint = '\r';
898 SPEC_CVAL (val->type).v_uint = '\f';
901 SPEC_CVAL (val->type).v_uint = '\a';
904 SPEC_CVAL (val->type).v_uint = '\\';
907 SPEC_CVAL (val->type).v_uint = '\?';
910 SPEC_CVAL (val->type).v_uint = '\'';
913 SPEC_CVAL (val->type).v_uint = '\"';
924 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
928 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
932 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
936 else /* not a backslash */
937 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
942 /*------------------------------------------------------------------*/
943 /* valFromType - creates a value from type given */
944 /*------------------------------------------------------------------*/
946 valFromType (sym_link * type)
948 value *val = newValue ();
949 val->type = copyLinkChain (type);
950 val->etype = getSpec (val->type);
954 /*------------------------------------------------------------------*/
955 /* floatFromVal - value to double float conversion */
956 /*------------------------------------------------------------------*/
958 floatFromVal (value * val)
963 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
965 werror (E_CONST_EXPECTED, val->name);
969 /* if it is not a specifier then we can assume that */
970 /* it will be an unsigned long */
971 if (!IS_SPEC (val->type))
972 return (double) SPEC_CVAL (val->etype).v_ulong;
974 if (SPEC_NOUN (val->etype) == V_FLOAT)
975 return (double) SPEC_CVAL (val->etype).v_float;
977 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
978 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
980 if (SPEC_LONG (val->etype))
982 if (SPEC_USIGN (val->etype))
983 return (double) SPEC_CVAL (val->etype).v_ulong;
985 return (double) SPEC_CVAL (val->etype).v_long;
988 if (SPEC_NOUN (val->etype) == V_INT) {
989 if (SPEC_USIGN (val->etype))
990 return (double) SPEC_CVAL (val->etype).v_uint;
992 return (double) SPEC_CVAL (val->etype).v_int;
995 if (SPEC_NOUN (val->etype) == V_CHAR) {
996 if (SPEC_USIGN (val->etype))
997 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
999 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1002 if (IS_BITVAR(val->etype)) {
1003 return (double) SPEC_CVAL (val->etype).v_uint;
1006 if (SPEC_NOUN (val->etype) == V_VOID) {
1007 return (double) SPEC_CVAL (val->etype).v_ulong;
1011 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1012 "floatFromVal: unknown value");
1016 /*------------------------------------------------------------------*/
1017 /* valUnaryPM - does the unary +/- operation on a constant */
1018 /*------------------------------------------------------------------*/
1020 valUnaryPM (value * val)
1022 /* depending on type */
1023 if (SPEC_NOUN (val->etype) == V_FLOAT)
1024 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1025 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1026 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1029 if (SPEC_LONG (val->etype))
1031 if (SPEC_USIGN (val->etype))
1032 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1034 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1038 if (SPEC_USIGN (val->etype))
1039 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1041 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1044 // -(unsigned 3) now really is signed
1045 SPEC_USIGN(val->etype)=0;
1046 // -(unsigned char)135 now really is an int
1047 if (SPEC_NOUN(val->etype) == V_CHAR) {
1048 if (SPEC_CVAL(val->etype).v_int < -128) {
1049 SPEC_NOUN(val->etype) = V_INT;
1055 /*------------------------------------------------------------------*/
1056 /* valueComplement - complements a constant */
1057 /*------------------------------------------------------------------*/
1059 valComplement (value * val)
1061 /* depending on type */
1062 if (SPEC_LONG (val->etype))
1064 if (SPEC_USIGN (val->etype))
1065 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1067 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1071 if (SPEC_USIGN (val->etype))
1072 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1074 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1075 if (SPEC_NOUN(val->etype) == V_CHAR)
1076 if ( SPEC_CVAL(val->etype).v_int < -128
1077 || SPEC_CVAL(val->etype).v_int > 127)
1078 SPEC_NOUN(val->etype) = V_INT;
1080 // ~(unsigned 3) now really is signed
1081 SPEC_USIGN(val->etype)=0;
1085 /*------------------------------------------------------------------*/
1086 /* valueNot - complements a constant */
1087 /*------------------------------------------------------------------*/
1089 valNot (value * val)
1091 /* depending on type */
1092 if (SPEC_LONG (val->etype))
1094 if (SPEC_USIGN (val->etype))
1095 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1097 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1101 if (SPEC_USIGN (val->etype))
1102 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1104 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1109 /*------------------------------------------------------------------*/
1110 /* valMult - multiply constants */
1111 /*------------------------------------------------------------------*/
1113 valMult (value * lval, value * rval)
1117 /* create a new value */
1119 val->type = val->etype = computeType (lval->etype,
1123 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1125 if (IS_FLOAT (val->type))
1126 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1128 if (IS_FIXED16X16 (val->type))
1129 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1130 /* signed and unsigned mul are the same, as long as the precision of the
1131 result isn't bigger than the precision of the operands. */
1132 else if (SPEC_LONG (val->type))
1133 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1134 (TYPE_UDWORD) floatFromVal (rval);
1135 else if (SPEC_USIGN (val->type)) /* unsigned int */
1137 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1138 (TYPE_UWORD) floatFromVal (rval);
1140 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1147 (TYPE_WORD) floatFromVal (rval);
1149 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1150 if (l != (TYPE_WORD) l)
1153 return cheapestVal (val);
1156 /*------------------------------------------------------------------*/
1157 /* valDiv - Divide constants */
1158 /*------------------------------------------------------------------*/
1160 valDiv (value * lval, value * rval)
1164 if (floatFromVal (rval) == 0)
1166 werror (E_DIVIDE_BY_ZERO);
1170 /* create a new value */
1172 val->type = val->etype = computeType (lval->etype,
1176 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1178 if (IS_FLOAT (val->type))
1179 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1181 if (IS_FIXED16X16 (val->type))
1182 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1183 else if (SPEC_LONG (val->type))
1185 if (SPEC_USIGN (val->type))
1186 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1187 (TYPE_UDWORD) floatFromVal (rval);
1189 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1190 (TYPE_DWORD) floatFromVal (rval);
1194 if (SPEC_USIGN (val->type))
1195 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1196 (TYPE_UWORD) floatFromVal (rval);
1198 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1199 (TYPE_WORD) floatFromVal (rval);
1201 return cheapestVal (val);
1204 /*------------------------------------------------------------------*/
1205 /* valMod - Modulus constants */
1206 /*------------------------------------------------------------------*/
1208 valMod (value * lval, value * rval)
1212 /* create a new value */
1214 val->type = val->etype = computeType (lval->etype,
1218 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1220 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 /* valPlus - Addition constants */
1243 /*------------------------------------------------------------------*/
1245 valPlus (value * lval, value * rval)
1249 /* create a new value */
1251 val->type = val->etype = computeType (lval->etype,
1255 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1257 if (IS_FLOAT (val->type))
1258 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1260 if (IS_FIXED16X16 (val->type))
1261 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1262 else if (SPEC_LONG (val->type))
1264 if (SPEC_USIGN (val->type))
1265 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1266 (TYPE_UDWORD) floatFromVal (rval);
1268 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1269 (TYPE_DWORD) floatFromVal (rval);
1273 if (SPEC_USIGN (val->type))
1274 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1275 (TYPE_UWORD) floatFromVal (rval);
1277 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1278 (TYPE_WORD) floatFromVal (rval);
1280 return cheapestVal (val);
1283 /*------------------------------------------------------------------*/
1284 /* valMinus - Addition constants */
1285 /*------------------------------------------------------------------*/
1287 valMinus (value * lval, value * rval)
1291 /* create a new value */
1293 val->type = val->etype = computeType (lval->etype,
1297 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1299 if (IS_FLOAT (val->type))
1300 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1302 if (IS_FIXED16X16 (val->type))
1303 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1304 else if (SPEC_LONG (val->type))
1306 if (SPEC_USIGN (val->type))
1307 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1308 (TYPE_UDWORD) floatFromVal (rval);
1310 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1311 (TYPE_DWORD) floatFromVal (rval);
1315 if (SPEC_USIGN (val->type))
1316 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1317 (TYPE_UWORD) floatFromVal (rval);
1319 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1320 (TYPE_WORD) floatFromVal (rval);
1322 return cheapestVal (val);
1325 /*------------------------------------------------------------------*/
1326 /* valShift - Shift left or right */
1327 /*------------------------------------------------------------------*/
1329 valShift (value * lval, value * rval, int lr)
1333 /* create a new value */
1335 val->type = val->etype = computeType (lval->etype,
1339 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1341 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1344 /* right shift and unsigned */
1345 (!lr && SPEC_USIGN (rval->type))))
1347 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1350 if (SPEC_LONG (val->type))
1352 if (SPEC_USIGN (val->type))
1354 SPEC_CVAL (val->type).v_ulong = lr ?
1355 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1356 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1360 SPEC_CVAL (val->type).v_long = lr ?
1361 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1362 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1367 if (SPEC_USIGN (val->type))
1369 SPEC_CVAL (val->type).v_uint = lr ?
1370 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1371 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1375 SPEC_CVAL (val->type).v_int = lr ?
1376 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1377 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1380 return cheapestVal (val);
1383 /*------------------------------------------------------------------*/
1384 /* valCompare- Compares two literal */
1385 /*------------------------------------------------------------------*/
1387 valCompare (value * lval, value * rval, int ctype)
1391 /* create a new value */
1393 val->type = val->etype = newCharLink ();
1394 val->type->class = SPECIFIER;
1395 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1396 SPEC_USIGN (val->type) = 1;
1397 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1402 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1406 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1410 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1414 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1418 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1419 SPEC_NOUN(rval->type) == V_FLOAT)
1421 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1424 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1425 SPEC_NOUN(rval->type) == V_FIXED16X16)
1427 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1431 /* integrals: ignore signedness */
1434 l = (TYPE_UDWORD) floatFromVal (lval);
1435 r = (TYPE_UDWORD) floatFromVal (rval);
1436 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1437 neccessary to strip them to 16 bit.
1438 Literals are reduced to their cheapest type, therefore left and
1439 right might have different types. It's neccessary to find a
1440 common type: int (used for char too) or long */
1441 if (!IS_LONG (lval->etype) &&
1442 !IS_LONG (rval->etype))
1447 SPEC_CVAL (val->type).v_int = l == r;
1451 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1452 SPEC_NOUN(rval->type) == V_FLOAT)
1454 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1457 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1458 SPEC_NOUN(rval->type) == V_FIXED16X16)
1460 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1464 /* integrals: ignore signedness */
1467 l = (TYPE_UDWORD) floatFromVal (lval);
1468 r = (TYPE_UDWORD) floatFromVal (rval);
1469 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1470 neccessary to strip them to 16 bit.
1471 Literals are reduced to their cheapest type, therefore left and
1472 right might have different types. It's neccessary to find a
1473 common type: int (used for char too) or long */
1474 if (!IS_LONG (lval->etype) &&
1475 !IS_LONG (rval->etype))
1480 SPEC_CVAL (val->type).v_int = l != r;
1489 /*------------------------------------------------------------------*/
1490 /* valBitwise - Bitwise operation */
1491 /*------------------------------------------------------------------*/
1493 valBitwise (value * lval, value * rval, int op)
1497 /* create a new value */
1499 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1500 val->etype = getSpec (val->type);
1501 SPEC_SCLS (val->etype) = S_LITERAL;
1506 if (SPEC_LONG (val->type))
1508 if (SPEC_USIGN (val->type))
1509 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1510 (TYPE_UDWORD) floatFromVal (rval);
1512 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1513 (TYPE_DWORD) floatFromVal (rval);
1517 if (SPEC_USIGN (val->type))
1518 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1519 (TYPE_UWORD) floatFromVal (rval);
1521 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1526 if (SPEC_LONG (val->type))
1528 if (SPEC_USIGN (val->type))
1529 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1530 (TYPE_UDWORD) floatFromVal (rval);
1532 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1533 (TYPE_DWORD) floatFromVal (rval);
1537 if (SPEC_USIGN (val->type))
1538 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1539 (TYPE_UWORD) floatFromVal (rval);
1541 SPEC_CVAL (val->type).v_int =
1542 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1548 if (SPEC_LONG (val->type))
1550 if (SPEC_USIGN (val->type))
1551 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1552 (TYPE_UDWORD) floatFromVal (rval);
1554 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1555 (TYPE_DWORD) floatFromVal (rval);
1559 if (SPEC_USIGN (val->type))
1560 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1561 (TYPE_UWORD) floatFromVal (rval);
1563 SPEC_CVAL (val->type).v_int =
1564 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1569 return cheapestVal(val);
1572 /*------------------------------------------------------------------*/
1573 /* valAndOr - Generates code for and / or operation */
1574 /*------------------------------------------------------------------*/
1576 valLogicAndOr (value * lval, value * rval, int op)
1580 /* create a new value */
1582 val->type = val->etype = newCharLink ();
1583 val->type->class = SPECIFIER;
1584 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1585 SPEC_USIGN (val->type) = 1;
1590 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1594 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1602 /*------------------------------------------------------------------*/
1603 /* valCastLiteral - casts a literal value to another type */
1604 /*------------------------------------------------------------------*/
1606 valCastLiteral (sym_link * dtype, double fval)
1609 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1616 val->etype = getSpec (val->type = copyLinkChain (dtype));
1619 val->etype = val->type = newLink (SPECIFIER);
1620 SPEC_NOUN (val->etype) = V_VOID;
1622 SPEC_SCLS (val->etype) = S_LITERAL;
1624 /* if it is not a specifier then we can assume that */
1625 /* it will be an unsigned long */
1626 if (!IS_SPEC (val->type)) {
1627 SPEC_CVAL (val->etype).v_ulong = l;
1631 if (SPEC_NOUN (val->etype) == V_FLOAT)
1632 SPEC_CVAL (val->etype).v_float = fval;
1633 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1634 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1635 else if (SPEC_NOUN (val->etype) == V_BIT ||
1636 SPEC_NOUN (val->etype) == V_SBIT)
1637 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1638 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1639 SPEC_CVAL (val->etype).v_uint = l &
1640 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1641 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1642 if (SPEC_USIGN (val->etype))
1643 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1645 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1647 if (SPEC_LONG (val->etype)) {
1648 if (SPEC_USIGN (val->etype))
1649 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1651 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1653 if (SPEC_USIGN (val->etype))
1654 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1656 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1662 /*------------------------------------------------------------------*/
1663 /* getNelements - determines # of elements from init list */
1664 /*------------------------------------------------------------------*/
1666 getNelements (sym_link * type, initList * ilist)
1673 if (ilist->type == INIT_DEEP)
1674 ilist = ilist->init.deep;
1676 /* if type is a character array and there is only one
1677 (string) initialiser then get the length of the string */
1678 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1680 ast *iast = ilist->init.node;
1681 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1684 werror (E_CONST_EXPECTED);
1688 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1689 // yep, it's a string
1691 return DCL_ELEM (v->type);
1699 ilist = ilist->next;
1704 /*-----------------------------------------------------------------*/
1705 /* valForArray - returns a value with name of array index */
1706 /*-----------------------------------------------------------------*/
1708 valForArray (ast * arrExpr)
1710 value *val, *lval = NULL;
1712 int size = getSize (arrExpr->left->ftype->next);
1713 /* if the right or left is an array
1715 if (IS_AST_OP (arrExpr->left))
1717 if (arrExpr->left->opval.op == '[')
1718 lval = valForArray (arrExpr->left);
1719 else if (arrExpr->left->opval.op == '.')
1720 lval = valForStructElem (arrExpr->left->left,
1721 arrExpr->left->right);
1722 else if (arrExpr->left->opval.op == PTR_OP &&
1723 IS_ADDRESS_OF_OP (arrExpr->left->left))
1724 lval = valForStructElem (arrExpr->left->left->left,
1725 arrExpr->left->right);
1730 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1733 if (!IS_AST_LIT_VALUE (arrExpr->right))
1739 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1743 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1746 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1747 (int) AST_LIT_VALUE (arrExpr->right) * size);
1749 val->type = newLink (DECLARATOR);
1750 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1751 DCL_TYPE (val->type) = CPOINTER;
1752 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1753 DCL_TYPE (val->type) = FPOINTER;
1754 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1755 DCL_TYPE (val->type) = PPOINTER;
1756 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1757 DCL_TYPE (val->type) = IPOINTER;
1758 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1759 DCL_TYPE (val->type) = EEPPOINTER;
1761 DCL_TYPE (val->type) = POINTER;
1762 val->type->next = arrExpr->left->ftype->next;
1763 val->etype = getSpec (val->type);
1767 /*-----------------------------------------------------------------*/
1768 /* valForStructElem - returns value with name of struct element */
1769 /*-----------------------------------------------------------------*/
1771 valForStructElem (ast * structT, ast * elemT)
1773 value *val, *lval = NULL;
1777 /* left could be furthur derefed */
1778 if (IS_AST_OP (structT))
1780 if (structT->opval.op == '[')
1781 lval = valForArray (structT);
1782 else if (structT->opval.op == '.')
1783 lval = valForStructElem (structT->left, structT->right);
1784 else if (structT->opval.op == PTR_OP &&
1785 IS_ADDRESS_OF_OP (structT->left))
1786 lval = valForStructElem (structT->left->left,
1792 if (!IS_AST_SYM_VALUE (elemT))
1795 if (!IS_STRUCT (structT->etype))
1798 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1799 AST_SYMBOL (elemT))) == NULL)
1807 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1811 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1814 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1817 val->type = newLink (DECLARATOR);
1818 if (SPEC_SCLS (structT->etype) == S_CODE)
1819 DCL_TYPE (val->type) = CPOINTER;
1820 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1821 DCL_TYPE (val->type) = FPOINTER;
1822 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1823 DCL_TYPE (val->type) = PPOINTER;
1824 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1825 DCL_TYPE (val->type) = IPOINTER;
1826 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1827 DCL_TYPE (val->type) = EEPPOINTER;
1829 DCL_TYPE (val->type) = POINTER;
1830 val->type->next = sym->type;
1831 val->etype = getSpec (val->type);
1835 /*-----------------------------------------------------------------*/
1836 /* valForCastAggr - will return value for a cast of an aggregate */
1837 /* plus minus a constant */
1838 /*-----------------------------------------------------------------*/
1840 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1844 if (!IS_AST_SYM_VALUE (aexpr))
1846 if (!IS_AST_LIT_VALUE (cnst))
1851 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1852 AST_SYMBOL (aexpr)->rname, op,
1853 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1856 val->etype = getSpec (val->type);
1860 /*-----------------------------------------------------------------*/
1861 /* valForCastAggr - will return value for a cast of an aggregate */
1862 /* with no constant */
1863 /*-----------------------------------------------------------------*/
1865 valForCastArr (ast * aexpr, sym_link * type)
1869 if (!IS_AST_SYM_VALUE (aexpr))
1874 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1875 AST_SYMBOL (aexpr)->rname);
1878 val->etype = getSpec (val->type);