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))))
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));
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 <= 127)
395 SPEC_NOUN(val->type) = V_CHAR;
397 /* this could be too aggressive:
398 'unsigned char' promotes to 'signed int', so that we can
399 reduce it the other way */
400 if (IS_INT(val->type) &&
401 !SPEC_USIGN(val->type) &&
402 !SPEC_LONG(val->type) &&
403 SPEC_CVAL(val->type).v_int >= 128 &&
404 SPEC_CVAL(val->type).v_int <= 255)
407 SPEC_NOUN(val->type) = V_CHAR;
408 SPEC_USIGN(val->type) = 1;
414 /*-----------------------------------------------------------------*/
415 /* valueFromLit - creates a value from a literal */
416 /*-----------------------------------------------------------------*/
418 valueFromLit (double lit)
422 if ((((TYPE_DWORD) lit) - lit) == 0)
424 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
425 return constVal (buffer);
428 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
429 return constFloatVal (buffer);
432 /*-----------------------------------------------------------------*/
433 /* constFloatVal - converts a FLOAT constant to value */
434 /*-----------------------------------------------------------------*/
436 constFloatVal (char *s)
438 value *val = newValue ();
441 if (sscanf (s, "%lf", &sval) != 1)
443 werror (E_INVALID_FLOAT_CONST, s);
444 return constVal ("0");
447 val->type = val->etype = newLink (SPECIFIER);
448 SPEC_NOUN (val->type) = V_FLOAT;
449 SPEC_SCLS (val->type) = S_LITERAL;
450 SPEC_CVAL (val->type).v_float = sval;
455 /*-----------------------------------------------------------------*/
456 /* constVal - converts an INTEGER constant into a cheapest value */
457 /*-----------------------------------------------------------------*/
458 value *constVal (char *s)
461 short hex = 0, octal = 0;
466 val = newValue (); /* alloc space for value */
468 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
469 SPEC_SCLS (val->type) = S_LITERAL;
470 // let's start with a signed char
471 SPEC_NOUN (val->type) = V_CHAR;
472 SPEC_USIGN (val->type) = 0;
474 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
476 /* set the octal flag */
477 if (!hex && *s == '0' && *(s + 1))
480 /* create the scan string */
481 scanFmt[scI++] = '%';
483 scanFmt[scI++] = 'l';
486 scanFmt[scI++] = 'o';
488 scanFmt[scI++] = 'x';
490 scanFmt[scI++] = 'f';
492 scanFmt[scI++] = '\0';
496 sscanf (s, scanFmt, &sval);
499 sscanf (s, scanFmt, &dval);
502 /* Setup the flags first */
503 /* set the _long flag if 'lL' is found */
504 if (strchr (s, 'l') || strchr (s, 'L')) {
505 SPEC_NOUN (val->type) = V_INT;
506 SPEC_LONG (val->type) = 1;
509 /* set the unsigned flag if 'uU' is found */
510 if (strchr (s, 'u') || strchr (s, 'U')) {
511 SPEC_USIGN (val->type) = 1;
514 if (dval<0) { // "-28u" will still be signed and negative
515 if (dval<-128) { // check if we have to promote to int
516 SPEC_NOUN (val->type) = V_INT;
518 if (dval<-32768) { // check if we have to promote to long int
519 SPEC_LONG (val->type) = 1;
522 if (dval>0xff || /* check if we have to promote to int */
523 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
524 char. After an integral promotion it will
525 be a signed int; this certainly isn't what
526 the programer wants */
527 SPEC_NOUN (val->type) = V_INT;
529 else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
531 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
533 SPEC_USIGN (val->type) = 1;
535 SPEC_NOUN (val->type) = V_INT;
538 /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
539 so that the signedness of a char shouldn't matter */
540 SPEC_USIGN (val->type) = 1;
543 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
544 SPEC_LONG (val->type) = 1;
546 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
547 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
549 SPEC_USIGN (val->type) = 1;
551 SPEC_LONG (val->type) = 1;
552 if (dval>0x7fffffff) {
553 SPEC_USIGN (val->type) = 1;
559 if (SPEC_LONG (val->type))
561 if (SPEC_USIGN (val->type))
563 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
567 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
572 if (SPEC_USIGN (val->type))
574 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
578 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
585 /*! /fn char hexEscape(char **src)
587 /param src Pointer to 'x' from start of hex character value
590 unsigned char hexEscape(char **src)
593 unsigned long value ;
595 (*src)++ ; /* Skip over the 'x' */
596 s = *src ; /* Save for error detection */
598 value = strtol (*src, src, 16);
601 // no valid hex found
602 werror(E_INVALID_HEX);
605 werror(W_ESC_SEQ_OOR_FOR_CHAR);
611 /*------------------------------------------------------------------*/
612 /* octalEscape - process an octal constant of max three digits */
613 /* return the octal value, throw a warning for illegal octal */
614 /* adjust src to point at the last proccesed char */
615 /*------------------------------------------------------------------*/
617 unsigned char octalEscape (char **str) {
621 for (digits=0; digits<3; digits++) {
622 if (**str>='0' && **str<='7') {
623 value = value*8 + (**str-'0');
630 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
631 werror (W_ESC_SEQ_OOR_FOR_CHAR);
638 /fn int copyStr (char *dest, char *src)
640 Copies a source string to a dest buffer interpreting escape sequences
641 and special characters
643 /param dest Buffer to receive the resultant string
644 /param src Buffer containing the source string with escape sequecnes
645 /return Number of characters in output string
650 copyStr (char *dest, char *src)
653 char *OriginalDest = dest ;
659 else if (*src == '\\')
694 *dest++ = octalEscape(&src);
699 *dest++ = hexEscape(&src) ;
726 return dest - OriginalDest ;
729 /*------------------------------------------------------------------*/
730 /* strVal - converts a string constant to a value */
731 /*------------------------------------------------------------------*/
737 val = newValue (); /* get a new one */
739 /* get a declarator */
740 val->type = newLink (DECLARATOR);
741 DCL_TYPE (val->type) = ARRAY;
742 val->type->next = val->etype = newLink (SPECIFIER);
743 SPEC_NOUN (val->etype) = V_CHAR;
744 SPEC_SCLS (val->etype) = S_LITERAL;
746 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
747 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
753 /*------------------------------------------------------------------*/
754 /* reverseValWithType - reverses value chain with type & etype */
755 /*------------------------------------------------------------------*/
757 reverseValWithType (value * val)
765 /* save the type * etype chains */
769 /* set the current one 2b null */
770 val->type = val->etype = NULL;
771 val = reverseVal (val);
773 /* restore type & etype */
780 /*------------------------------------------------------------------*/
781 /* reverseVal - reverses the values for a value chain */
782 /*------------------------------------------------------------------*/
784 reverseVal (value * val)
786 value *prev, *curr, *next;
801 val->next = (void *) NULL;
805 /*------------------------------------------------------------------*/
806 /* copyValueChain - will copy a chain of values */
807 /*------------------------------------------------------------------*/
809 copyValueChain (value * src)
816 dest = copyValue (src);
817 dest->next = copyValueChain (src->next);
822 /*------------------------------------------------------------------*/
823 /* copyValue - copies contents of a value to a fresh one */
824 /*------------------------------------------------------------------*/
826 copyValue (value * src)
831 dest->sym = copySymbol (src->sym);
832 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
833 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
834 dest->etype = (src->type ? getSpec (dest->type) : NULL);
839 /*------------------------------------------------------------------*/
840 /* charVal - converts a character constant to a value */
841 /*------------------------------------------------------------------*/
849 val->type = val->etype = newLink (SPECIFIER);
850 SPEC_NOUN (val->type) = V_CHAR;
851 SPEC_USIGN(val->type) = 1;
852 SPEC_SCLS (val->type) = S_LITERAL;
854 s++; /* get rid of quotation */
855 /* if \ then special processing */
858 s++; /* go beyond the backslash */
862 SPEC_CVAL (val->type).v_uint = '\n';
865 SPEC_CVAL (val->type).v_uint = '\t';
868 SPEC_CVAL (val->type).v_uint = '\v';
871 SPEC_CVAL (val->type).v_uint = '\b';
874 SPEC_CVAL (val->type).v_uint = '\r';
877 SPEC_CVAL (val->type).v_uint = '\f';
880 SPEC_CVAL (val->type).v_uint = '\a';
883 SPEC_CVAL (val->type).v_uint = '\\';
886 SPEC_CVAL (val->type).v_uint = '\?';
889 SPEC_CVAL (val->type).v_uint = '\'';
892 SPEC_CVAL (val->type).v_uint = '\"';
903 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
907 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
911 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
915 else /* not a backslash */
916 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
921 /*------------------------------------------------------------------*/
922 /* valFromType - creates a value from type given */
923 /*------------------------------------------------------------------*/
925 valFromType (sym_link * type)
927 value *val = newValue ();
928 val->type = copyLinkChain (type);
929 val->etype = getSpec (val->type);
933 /*------------------------------------------------------------------*/
934 /* floatFromVal - value to double float conversion */
935 /*------------------------------------------------------------------*/
937 floatFromVal (value * val)
942 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
944 werror (E_CONST_EXPECTED, val->name);
948 /* if it is not a specifier then we can assume that */
949 /* it will be an unsigned long */
950 if (!IS_SPEC (val->type))
951 return (double) SPEC_CVAL (val->etype).v_ulong;
953 if (SPEC_NOUN (val->etype) == V_FLOAT)
954 return (double) SPEC_CVAL (val->etype).v_float;
956 if (SPEC_LONG (val->etype))
958 if (SPEC_USIGN (val->etype))
959 return (double) SPEC_CVAL (val->etype).v_ulong;
961 return (double) SPEC_CVAL (val->etype).v_long;
964 if (SPEC_NOUN (val->etype) == V_INT) {
965 if (SPEC_USIGN (val->etype))
966 return (double) SPEC_CVAL (val->etype).v_uint;
968 return (double) SPEC_CVAL (val->etype).v_int;
971 if (SPEC_NOUN (val->etype) == V_CHAR) {
972 if (SPEC_USIGN (val->etype))
973 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
975 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
978 if (IS_BITVAR(val->etype)) {
979 return (double) SPEC_CVAL (val->etype).v_uint;
982 if (SPEC_NOUN (val->etype) == V_VOID) {
983 return (double) SPEC_CVAL (val->etype).v_ulong;
987 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
988 "floatFromVal: unknown value");
992 /*------------------------------------------------------------------*/
993 /* valUnaryPM - does the unary +/- operation on a constant */
994 /*------------------------------------------------------------------*/
996 valUnaryPM (value * val)
998 /* depending on type */
999 if (SPEC_NOUN (val->etype) == V_FLOAT)
1000 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1003 if (SPEC_LONG (val->etype))
1005 if (SPEC_USIGN (val->etype))
1006 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1008 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1012 if (SPEC_USIGN (val->etype))
1013 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1015 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1018 // -(unsigned 3) now really is signed
1019 SPEC_USIGN(val->etype)=0;
1020 // -(unsigned char)135 now really is an int
1021 if (SPEC_NOUN(val->etype) == V_CHAR) {
1022 if (SPEC_CVAL(val->etype).v_int < -128) {
1023 SPEC_NOUN(val->etype) = V_INT;
1029 /*------------------------------------------------------------------*/
1030 /* valueComplement - complements a constant */
1031 /*------------------------------------------------------------------*/
1033 valComplement (value * val)
1035 /* depending on type */
1036 if (SPEC_LONG (val->etype))
1038 if (SPEC_USIGN (val->etype))
1039 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1041 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1045 if (SPEC_USIGN (val->etype))
1046 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1048 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1050 // ~(unsigned 3) now really is signed
1051 SPEC_USIGN(val->etype)=0;
1055 /*------------------------------------------------------------------*/
1056 /* valueNot - complements a constant */
1057 /*------------------------------------------------------------------*/
1059 valNot (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;
1079 /*------------------------------------------------------------------*/
1080 /* valMult - multiply constants */
1081 /*------------------------------------------------------------------*/
1083 valMult (value * lval, value * rval)
1087 /* create a new value */
1089 val->type = val->etype = newLink (SPECIFIER);
1090 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1091 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1092 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1093 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1094 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
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 = newLink(SPECIFIER);
1142 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1143 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1144 SPEC_SCLS (val->etype) = S_LITERAL;
1145 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1146 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1150 if (IS_FLOAT (val->type))
1151 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1152 else if (SPEC_LONG (val->type))
1154 if (SPEC_USIGN (val->type))
1155 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1156 (TYPE_UDWORD) floatFromVal (rval);
1158 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1159 (TYPE_DWORD) floatFromVal (rval);
1163 if (SPEC_USIGN (val->type))
1164 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1165 (TYPE_UWORD) floatFromVal (rval);
1167 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1168 (TYPE_WORD) floatFromVal (rval);
1170 return cheapestVal (val);
1173 /*------------------------------------------------------------------*/
1174 /* valMod - Modulus constants */
1175 /*------------------------------------------------------------------*/
1177 valMod (value * lval, value * rval)
1181 /* create a new value */
1183 val->type = val->etype = newLink (SPECIFIER);
1184 SPEC_NOUN (val->type) = V_INT; /* type is int */
1185 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1186 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1187 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1191 if (SPEC_LONG (val->type))
1193 if (SPEC_USIGN (val->type))
1194 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1195 (TYPE_UDWORD) floatFromVal (rval);
1197 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1198 (TYPE_DWORD) floatFromVal (rval);
1202 if (SPEC_USIGN (val->type))
1203 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1204 (TYPE_UWORD) floatFromVal (rval);
1206 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1207 (TYPE_WORD) floatFromVal (rval);
1209 return cheapestVal (val);
1212 /*------------------------------------------------------------------*/
1213 /* valPlus - Addition constants */
1214 /*------------------------------------------------------------------*/
1216 valPlus (value * lval, value * rval)
1220 /* create a new value */
1222 val->type = val->etype = newLink (SPECIFIER);
1223 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1224 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1225 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1226 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1227 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1230 if (IS_FLOAT (val->type))
1231 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1232 else if (SPEC_LONG (val->type))
1234 if (SPEC_USIGN (val->type))
1235 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1236 (TYPE_UDWORD) floatFromVal (rval);
1238 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1239 (TYPE_DWORD) floatFromVal (rval);
1243 if (SPEC_USIGN (val->type))
1244 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1245 (TYPE_UWORD) floatFromVal (rval);
1247 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1248 (TYPE_WORD) floatFromVal (rval);
1250 return cheapestVal (val);
1253 /*------------------------------------------------------------------*/
1254 /* valMinus - Addition constants */
1255 /*------------------------------------------------------------------*/
1257 valMinus (value * lval, value * rval)
1261 /* create a new value */
1263 val->type = val->etype = newLink (SPECIFIER);
1264 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1265 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1266 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1267 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1268 SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype,
1271 if (IS_FLOAT (val->type))
1272 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1273 else if (SPEC_LONG (val->type))
1275 if (SPEC_USIGN (val->type))
1276 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1277 (TYPE_UDWORD) floatFromVal (rval);
1279 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1280 (TYPE_DWORD) floatFromVal (rval);
1284 if (SPEC_USIGN (val->type))
1285 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1286 (TYPE_UWORD) floatFromVal (rval);
1288 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1289 (TYPE_WORD) floatFromVal (rval);
1291 return cheapestVal (val);
1294 /*------------------------------------------------------------------*/
1295 /* valShift - Shift left or right */
1296 /*------------------------------------------------------------------*/
1298 valShift (value * lval, value * rval, int lr)
1302 /* create a new value */
1304 val->type = val->etype = newIntLink ();
1305 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1306 SPEC_NOUN (val->etype) = V_INT;
1307 /* 'unsigned char' promotes to 'signed int' */
1308 if (!IS_CHAR (lval->etype))
1309 SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1310 SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1312 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1315 /* right shift and unsigned */
1316 (!lr && SPEC_USIGN (rval->type))))
1318 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1321 if (SPEC_LONG (val->type))
1323 if (SPEC_USIGN (val->type))
1325 SPEC_CVAL (val->type).v_ulong = lr ?
1326 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1327 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1331 SPEC_CVAL (val->type).v_long = lr ?
1332 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1333 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1338 if (SPEC_USIGN (val->type))
1340 SPEC_CVAL (val->type).v_uint = lr ?
1341 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1342 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1346 SPEC_CVAL (val->type).v_int = lr ?
1347 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1348 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1351 return cheapestVal (val);
1354 /*------------------------------------------------------------------*/
1355 /* valCompare- Compares two literal */
1356 /*------------------------------------------------------------------*/
1358 valCompare (value * lval, value * rval, int ctype)
1362 /* create a new value */
1364 val->type = val->etype = newCharLink ();
1365 val->type->class = SPECIFIER;
1366 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1367 SPEC_USIGN (val->type) = 1;
1368 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1373 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1377 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1381 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1385 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1389 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1390 SPEC_NOUN(rval->type) == V_FLOAT)
1392 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1396 /* integrals: ignore signedness */
1399 l = (TYPE_UDWORD) floatFromVal (lval);
1400 r = (TYPE_UDWORD) floatFromVal (rval);
1401 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1402 neccessary to strip them to 16 bit.
1403 Literals are reduced to their cheapest type, therefore left and
1404 right might have different types. It's neccessary to find a
1405 common type: int (used for char too) or long */
1406 if (!IS_LONG (lval->etype) &&
1407 !IS_LONG (rval->etype))
1412 SPEC_CVAL (val->type).v_int = l == r;
1416 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1417 SPEC_NOUN(rval->type) == V_FLOAT)
1419 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1423 /* integrals: ignore signedness */
1426 l = (TYPE_UDWORD) floatFromVal (lval);
1427 r = (TYPE_UDWORD) floatFromVal (rval);
1428 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1429 neccessary to strip them to 16 bit.
1430 Literals are reduced to their cheapest type, therefore left and
1431 right might have different types. It's neccessary to find a
1432 common type: int (used for char too) or long */
1433 if (!IS_LONG (lval->etype) &&
1434 !IS_LONG (rval->etype))
1439 SPEC_CVAL (val->type).v_int = l != r;
1448 /*------------------------------------------------------------------*/
1449 /* valBitwise - Bitwise operation */
1450 /*------------------------------------------------------------------*/
1452 valBitwise (value * lval, value * rval, int op)
1456 /* create a new value */
1458 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1459 rval->type : lval->type);
1460 val->etype = getSpec (val->type);
1465 if (SPEC_LONG (val->type))
1467 if (SPEC_USIGN (val->type))
1468 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1469 (unsigned long) floatFromVal (rval);
1471 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1472 (long) floatFromVal (rval);
1476 if (SPEC_USIGN (val->type))
1477 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1478 (unsigned) floatFromVal (rval);
1480 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1485 if (SPEC_LONG (val->type))
1487 if (SPEC_USIGN (val->type))
1488 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1489 (unsigned long) floatFromVal (rval);
1491 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1492 (long) floatFromVal (rval);
1496 if (SPEC_USIGN (val->type))
1497 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1498 (unsigned) floatFromVal (rval);
1500 SPEC_CVAL (val->type).v_int =
1501 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1507 if (SPEC_LONG (val->type))
1509 if (SPEC_USIGN (val->type))
1510 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1511 (unsigned long) floatFromVal (rval);
1513 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1514 (long) floatFromVal (rval);
1518 if (SPEC_USIGN (val->type))
1519 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1520 (unsigned) floatFromVal (rval);
1522 SPEC_CVAL (val->type).v_int =
1523 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1528 return cheapestVal(val);
1531 /*------------------------------------------------------------------*/
1532 /* valAndOr - Generates code for and / or operation */
1533 /*------------------------------------------------------------------*/
1535 valLogicAndOr (value * lval, value * rval, int op)
1539 /* create a new value */
1541 val->type = val->etype = newCharLink ();
1542 val->type->class = SPECIFIER;
1543 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1544 SPEC_USIGN (val->type) = 0;
1549 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1553 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1561 /*------------------------------------------------------------------*/
1562 /* valCastLiteral - casts a literal value to another type */
1563 /*------------------------------------------------------------------*/
1565 valCastLiteral (sym_link * dtype, double fval)
1568 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1574 val->etype = getSpec (val->type = copyLinkChain (dtype));
1575 SPEC_SCLS (val->etype) = S_LITERAL;
1577 /* if it is not a specifier then we can assume that */
1578 /* it will be an unsigned long */
1579 if (!IS_SPEC (val->type)) {
1580 SPEC_CVAL (val->etype).v_ulong = l;
1584 if (SPEC_NOUN (val->etype) == V_FLOAT)
1585 SPEC_CVAL (val->etype).v_float = fval;
1586 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1587 if (SPEC_USIGN (val->etype))
1588 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1590 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1592 if (SPEC_LONG (val->etype)) {
1593 if (SPEC_USIGN (val->etype))
1594 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1596 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1598 if (SPEC_USIGN (val->etype))
1599 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1601 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1607 /*------------------------------------------------------------------*/
1608 /* getNelements - determines # of elements from init list */
1609 /*------------------------------------------------------------------*/
1611 getNelements (sym_link * type, initList * ilist)
1618 if (ilist->type == INIT_DEEP)
1619 ilist = ilist->init.deep;
1621 /* if type is a character array and there is only one
1622 (string) initialiser then get the length of the string */
1623 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1625 ast *iast = ilist->init.node;
1626 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1629 werror (E_CONST_EXPECTED);
1633 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1634 // yep, it's a string
1636 return DCL_ELEM (v->type);
1644 ilist = ilist->next;
1649 /*-----------------------------------------------------------------*/
1650 /* valForArray - returns a value with name of array index */
1651 /*-----------------------------------------------------------------*/
1653 valForArray (ast * arrExpr)
1655 value *val, *lval = NULL;
1657 int size = getSize (arrExpr->left->ftype->next);
1658 /* if the right or left is an array
1660 if (IS_AST_OP (arrExpr->left))
1662 if (arrExpr->left->opval.op == '[')
1663 lval = valForArray (arrExpr->left);
1664 else if (arrExpr->left->opval.op == '.')
1665 lval = valForStructElem (arrExpr->left->left,
1666 arrExpr->left->right);
1667 else if (arrExpr->left->opval.op == PTR_OP &&
1668 IS_ADDRESS_OF_OP (arrExpr->left->left))
1669 lval = valForStructElem (arrExpr->left->left->left,
1670 arrExpr->left->right);
1675 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1678 if (!IS_AST_LIT_VALUE (arrExpr->right))
1684 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1688 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1691 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1692 (int) AST_LIT_VALUE (arrExpr->right) * size);
1694 val->type = newLink (DECLARATOR);
1695 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1696 DCL_TYPE (val->type) = CPOINTER;
1697 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1698 DCL_TYPE (val->type) = FPOINTER;
1699 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1700 DCL_TYPE (val->type) = PPOINTER;
1701 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1702 DCL_TYPE (val->type) = IPOINTER;
1703 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1704 DCL_TYPE (val->type) = EEPPOINTER;
1706 DCL_TYPE (val->type) = POINTER;
1707 val->type->next = arrExpr->left->ftype;
1708 val->etype = getSpec (val->type);
1712 /*-----------------------------------------------------------------*/
1713 /* valForStructElem - returns value with name of struct element */
1714 /*-----------------------------------------------------------------*/
1716 valForStructElem (ast * structT, ast * elemT)
1718 value *val, *lval = NULL;
1722 /* left could be furthur derefed */
1723 if (IS_AST_OP (structT))
1725 if (structT->opval.op == '[')
1726 lval = valForArray (structT);
1727 else if (structT->opval.op == '.')
1728 lval = valForStructElem (structT->left, structT->right);
1729 else if (structT->opval.op == PTR_OP &&
1730 IS_ADDRESS_OF_OP (structT->left))
1731 lval = valForStructElem (structT->left->left,
1737 if (!IS_AST_SYM_VALUE (elemT))
1740 if (!IS_STRUCT (structT->etype))
1743 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1744 AST_SYMBOL (elemT))) == NULL)
1752 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1756 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1759 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1762 val->type = newLink (DECLARATOR);
1763 if (SPEC_SCLS (structT->etype) == S_CODE)
1764 DCL_TYPE (val->type) = CPOINTER;
1765 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1766 DCL_TYPE (val->type) = FPOINTER;
1767 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1768 DCL_TYPE (val->type) = PPOINTER;
1769 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1770 DCL_TYPE (val->type) = IPOINTER;
1771 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1772 DCL_TYPE (val->type) = EEPPOINTER;
1774 DCL_TYPE (val->type) = POINTER;
1775 val->type->next = sym->type;
1776 val->etype = getSpec (val->type);
1780 /*-----------------------------------------------------------------*/
1781 /* valForCastAggr - will return value for a cast of an aggregate */
1782 /* plus minus a constant */
1783 /*-----------------------------------------------------------------*/
1785 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1789 if (!IS_AST_SYM_VALUE (aexpr))
1791 if (!IS_AST_LIT_VALUE (cnst))
1796 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1797 AST_SYMBOL (aexpr)->rname, op,
1798 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1801 val->etype = getSpec (val->type);
1805 /*-----------------------------------------------------------------*/
1806 /* valForCastAggr - will return value for a cast of an aggregate */
1807 /* with no constant */
1808 /*-----------------------------------------------------------------*/
1810 valForCastArr (ast * aexpr, sym_link * type)
1814 if (!IS_AST_SYM_VALUE (aexpr))
1819 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1820 AST_SYMBOL (aexpr)->rname);
1823 val->etype = getSpec (val->type);