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;
1048 // ~(unsigned 3) now really is signed
1049 SPEC_USIGN(val->etype)=0;
1053 /*------------------------------------------------------------------*/
1054 /* valueNot - complements a constant */
1055 /*------------------------------------------------------------------*/
1057 valNot (value * val)
1059 /* depending on type */
1060 if (SPEC_LONG (val->etype))
1062 if (SPEC_USIGN (val->etype))
1063 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1065 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1069 if (SPEC_USIGN (val->etype))
1070 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1072 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1077 /*------------------------------------------------------------------*/
1078 /* valMult - multiply constants */
1079 /*------------------------------------------------------------------*/
1081 valMult (value * lval, value * rval)
1085 /* create a new value */
1087 val->type = val->etype = computeType (lval->etype,
1091 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1093 if (IS_FLOAT (val->type))
1094 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1095 /* signed and unsigned mul are the same, as long as the precision of the
1096 result isn't bigger than the precision of the operands. */
1097 else if (SPEC_LONG (val->type))
1098 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1099 (TYPE_UDWORD) floatFromVal (rval);
1100 else if (SPEC_USIGN (val->type)) /* unsigned int */
1102 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1103 (TYPE_UWORD) floatFromVal (rval);
1105 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1106 if (ul != (TYPE_UWORD) ul)
1109 else /* signed int */
1111 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1112 (TYPE_WORD) floatFromVal (rval);
1114 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1115 if (l != (TYPE_WORD) l)
1118 return cheapestVal (val);
1121 /*------------------------------------------------------------------*/
1122 /* valDiv - Divide constants */
1123 /*------------------------------------------------------------------*/
1125 valDiv (value * lval, value * rval)
1129 if (floatFromVal (rval) == 0)
1131 werror (E_DIVIDE_BY_ZERO);
1135 /* create a new value */
1137 val->type = val->etype = computeType (lval->etype,
1141 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1143 if (IS_FLOAT (val->type))
1144 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1145 else if (SPEC_LONG (val->type))
1147 if (SPEC_USIGN (val->type))
1148 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1149 (TYPE_UDWORD) floatFromVal (rval);
1151 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1152 (TYPE_DWORD) floatFromVal (rval);
1156 if (SPEC_USIGN (val->type))
1157 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1158 (TYPE_UWORD) floatFromVal (rval);
1160 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1161 (TYPE_WORD) floatFromVal (rval);
1163 return cheapestVal (val);
1166 /*------------------------------------------------------------------*/
1167 /* valMod - Modulus constants */
1168 /*------------------------------------------------------------------*/
1170 valMod (value * lval, value * rval)
1174 /* create a new value */
1176 val->type = val->etype = computeType (lval->etype,
1180 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1182 if (SPEC_LONG (val->type))
1184 if (SPEC_USIGN (val->type))
1185 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1186 (TYPE_UDWORD) floatFromVal (rval);
1188 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1189 (TYPE_DWORD) floatFromVal (rval);
1193 if (SPEC_USIGN (val->type))
1194 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1195 (TYPE_UWORD) floatFromVal (rval);
1197 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1198 (TYPE_WORD) floatFromVal (rval);
1200 return cheapestVal (val);
1203 /*------------------------------------------------------------------*/
1204 /* valPlus - Addition constants */
1205 /*------------------------------------------------------------------*/
1207 valPlus (value * lval, value * rval)
1211 /* create a new value */
1213 val->type = val->etype = computeType (lval->etype,
1217 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1219 if (IS_FLOAT (val->type))
1220 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1221 else if (SPEC_LONG (val->type))
1223 if (SPEC_USIGN (val->type))
1224 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1225 (TYPE_UDWORD) floatFromVal (rval);
1227 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1228 (TYPE_DWORD) floatFromVal (rval);
1232 if (SPEC_USIGN (val->type))
1233 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1234 (TYPE_UWORD) floatFromVal (rval);
1236 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1237 (TYPE_WORD) floatFromVal (rval);
1239 return cheapestVal (val);
1242 /*------------------------------------------------------------------*/
1243 /* valMinus - Addition constants */
1244 /*------------------------------------------------------------------*/
1246 valMinus (value * lval, value * rval)
1250 /* create a new value */
1252 val->type = val->etype = computeType (lval->etype,
1256 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1258 if (IS_FLOAT (val->type))
1259 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1260 else if (SPEC_LONG (val->type))
1262 if (SPEC_USIGN (val->type))
1263 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1264 (TYPE_UDWORD) floatFromVal (rval);
1266 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1267 (TYPE_DWORD) floatFromVal (rval);
1271 if (SPEC_USIGN (val->type))
1272 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1273 (TYPE_UWORD) floatFromVal (rval);
1275 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1276 (TYPE_WORD) floatFromVal (rval);
1278 return cheapestVal (val);
1281 /*------------------------------------------------------------------*/
1282 /* valShift - Shift left or right */
1283 /*------------------------------------------------------------------*/
1285 valShift (value * lval, value * rval, int lr)
1289 /* create a new value */
1291 val->type = val->etype = computeType (lval->etype,
1295 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1297 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1300 /* right shift and unsigned */
1301 (!lr && SPEC_USIGN (rval->type))))
1303 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1306 if (SPEC_LONG (val->type))
1308 if (SPEC_USIGN (val->type))
1310 SPEC_CVAL (val->type).v_ulong = lr ?
1311 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1312 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1316 SPEC_CVAL (val->type).v_long = lr ?
1317 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1318 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1323 if (SPEC_USIGN (val->type))
1325 SPEC_CVAL (val->type).v_uint = lr ?
1326 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1327 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1331 SPEC_CVAL (val->type).v_int = lr ?
1332 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1333 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1336 return cheapestVal (val);
1339 /*------------------------------------------------------------------*/
1340 /* valCompare- Compares two literal */
1341 /*------------------------------------------------------------------*/
1343 valCompare (value * lval, value * rval, int ctype)
1347 /* create a new value */
1349 val->type = val->etype = newCharLink ();
1350 val->type->class = SPECIFIER;
1351 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1352 SPEC_USIGN (val->type) = 1;
1353 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1358 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
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 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1375 SPEC_NOUN(rval->type) == V_FLOAT)
1377 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1381 /* integrals: ignore signedness */
1384 l = (TYPE_UDWORD) floatFromVal (lval);
1385 r = (TYPE_UDWORD) floatFromVal (rval);
1386 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1387 neccessary to strip them to 16 bit.
1388 Literals are reduced to their cheapest type, therefore left and
1389 right might have different types. It's neccessary to find a
1390 common type: int (used for char too) or long */
1391 if (!IS_LONG (lval->etype) &&
1392 !IS_LONG (rval->etype))
1397 SPEC_CVAL (val->type).v_int = l == r;
1401 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1402 SPEC_NOUN(rval->type) == V_FLOAT)
1404 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1408 /* integrals: ignore signedness */
1411 l = (TYPE_UDWORD) floatFromVal (lval);
1412 r = (TYPE_UDWORD) floatFromVal (rval);
1413 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1414 neccessary to strip them to 16 bit.
1415 Literals are reduced to their cheapest type, therefore left and
1416 right might have different types. It's neccessary to find a
1417 common type: int (used for char too) or long */
1418 if (!IS_LONG (lval->etype) &&
1419 !IS_LONG (rval->etype))
1424 SPEC_CVAL (val->type).v_int = l != r;
1433 /*------------------------------------------------------------------*/
1434 /* valBitwise - Bitwise operation */
1435 /*------------------------------------------------------------------*/
1437 valBitwise (value * lval, value * rval, int op)
1441 /* create a new value */
1443 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1444 val->etype = getSpec (val->type);
1445 SPEC_SCLS (val->etype) = S_LITERAL;
1450 if (SPEC_LONG (val->type))
1452 if (SPEC_USIGN (val->type))
1453 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1454 (TYPE_UDWORD) floatFromVal (rval);
1456 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1457 (TYPE_DWORD) floatFromVal (rval);
1461 if (SPEC_USIGN (val->type))
1462 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1463 (TYPE_UWORD) floatFromVal (rval);
1465 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1470 if (SPEC_LONG (val->type))
1472 if (SPEC_USIGN (val->type))
1473 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1474 (TYPE_UDWORD) floatFromVal (rval);
1476 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1477 (TYPE_DWORD) floatFromVal (rval);
1481 if (SPEC_USIGN (val->type))
1482 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1483 (TYPE_UWORD) floatFromVal (rval);
1485 SPEC_CVAL (val->type).v_int =
1486 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1492 if (SPEC_LONG (val->type))
1494 if (SPEC_USIGN (val->type))
1495 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1496 (TYPE_UDWORD) floatFromVal (rval);
1498 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1499 (TYPE_DWORD) floatFromVal (rval);
1503 if (SPEC_USIGN (val->type))
1504 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1505 (TYPE_UWORD) floatFromVal (rval);
1507 SPEC_CVAL (val->type).v_int =
1508 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1513 return cheapestVal(val);
1516 /*------------------------------------------------------------------*/
1517 /* valAndOr - Generates code for and / or operation */
1518 /*------------------------------------------------------------------*/
1520 valLogicAndOr (value * lval, value * rval, int op)
1524 /* create a new value */
1526 val->type = val->etype = newCharLink ();
1527 val->type->class = SPECIFIER;
1528 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1529 SPEC_USIGN (val->type) = 1;
1534 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1538 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1546 /*------------------------------------------------------------------*/
1547 /* valCastLiteral - casts a literal value to another type */
1548 /*------------------------------------------------------------------*/
1550 valCastLiteral (sym_link * dtype, double fval)
1553 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1559 val->etype = getSpec (val->type = copyLinkChain (dtype));
1560 SPEC_SCLS (val->etype) = S_LITERAL;
1562 /* if it is not a specifier then we can assume that */
1563 /* it will be an unsigned long */
1564 if (!IS_SPEC (val->type)) {
1565 SPEC_CVAL (val->etype).v_ulong = l;
1569 if (SPEC_NOUN (val->etype) == V_FLOAT)
1570 SPEC_CVAL (val->etype).v_float = fval;
1571 else if (SPEC_NOUN (val->etype) == V_BIT ||
1572 SPEC_NOUN (val->etype) == V_SBIT)
1573 SPEC_CVAL (val->etype).v_uint = l & 1;
1574 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1575 SPEC_CVAL (val->etype).v_uint = l &
1576 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1577 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1578 if (SPEC_USIGN (val->etype))
1579 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1581 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1583 if (SPEC_LONG (val->etype)) {
1584 if (SPEC_USIGN (val->etype))
1585 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1587 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1589 if (SPEC_USIGN (val->etype))
1590 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1592 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1598 /*------------------------------------------------------------------*/
1599 /* getNelements - determines # of elements from init list */
1600 /*------------------------------------------------------------------*/
1602 getNelements (sym_link * type, initList * ilist)
1609 if (ilist->type == INIT_DEEP)
1610 ilist = ilist->init.deep;
1612 /* if type is a character array and there is only one
1613 (string) initialiser then get the length of the string */
1614 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1616 ast *iast = ilist->init.node;
1617 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1620 werror (E_CONST_EXPECTED);
1624 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1625 // yep, it's a string
1627 return DCL_ELEM (v->type);
1635 ilist = ilist->next;
1640 /*-----------------------------------------------------------------*/
1641 /* valForArray - returns a value with name of array index */
1642 /*-----------------------------------------------------------------*/
1644 valForArray (ast * arrExpr)
1646 value *val, *lval = NULL;
1648 int size = getSize (arrExpr->left->ftype->next);
1649 /* if the right or left is an array
1651 if (IS_AST_OP (arrExpr->left))
1653 if (arrExpr->left->opval.op == '[')
1654 lval = valForArray (arrExpr->left);
1655 else if (arrExpr->left->opval.op == '.')
1656 lval = valForStructElem (arrExpr->left->left,
1657 arrExpr->left->right);
1658 else if (arrExpr->left->opval.op == PTR_OP &&
1659 IS_ADDRESS_OF_OP (arrExpr->left->left))
1660 lval = valForStructElem (arrExpr->left->left->left,
1661 arrExpr->left->right);
1666 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1669 if (!IS_AST_LIT_VALUE (arrExpr->right))
1675 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1679 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1682 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1683 (int) AST_LIT_VALUE (arrExpr->right) * size);
1685 val->type = newLink (DECLARATOR);
1686 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1687 DCL_TYPE (val->type) = CPOINTER;
1688 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1689 DCL_TYPE (val->type) = FPOINTER;
1690 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1691 DCL_TYPE (val->type) = PPOINTER;
1692 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1693 DCL_TYPE (val->type) = IPOINTER;
1694 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1695 DCL_TYPE (val->type) = EEPPOINTER;
1697 DCL_TYPE (val->type) = POINTER;
1698 val->type->next = arrExpr->left->ftype;
1699 val->etype = getSpec (val->type);
1703 /*-----------------------------------------------------------------*/
1704 /* valForStructElem - returns value with name of struct element */
1705 /*-----------------------------------------------------------------*/
1707 valForStructElem (ast * structT, ast * elemT)
1709 value *val, *lval = NULL;
1713 /* left could be furthur derefed */
1714 if (IS_AST_OP (structT))
1716 if (structT->opval.op == '[')
1717 lval = valForArray (structT);
1718 else if (structT->opval.op == '.')
1719 lval = valForStructElem (structT->left, structT->right);
1720 else if (structT->opval.op == PTR_OP &&
1721 IS_ADDRESS_OF_OP (structT->left))
1722 lval = valForStructElem (structT->left->left,
1728 if (!IS_AST_SYM_VALUE (elemT))
1731 if (!IS_STRUCT (structT->etype))
1734 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1735 AST_SYMBOL (elemT))) == NULL)
1743 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1747 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1750 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1753 val->type = newLink (DECLARATOR);
1754 if (SPEC_SCLS (structT->etype) == S_CODE)
1755 DCL_TYPE (val->type) = CPOINTER;
1756 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1757 DCL_TYPE (val->type) = FPOINTER;
1758 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1759 DCL_TYPE (val->type) = PPOINTER;
1760 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1761 DCL_TYPE (val->type) = IPOINTER;
1762 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1763 DCL_TYPE (val->type) = EEPPOINTER;
1765 DCL_TYPE (val->type) = POINTER;
1766 val->type->next = sym->type;
1767 val->etype = getSpec (val->type);
1771 /*-----------------------------------------------------------------*/
1772 /* valForCastAggr - will return value for a cast of an aggregate */
1773 /* plus minus a constant */
1774 /*-----------------------------------------------------------------*/
1776 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1780 if (!IS_AST_SYM_VALUE (aexpr))
1782 if (!IS_AST_LIT_VALUE (cnst))
1787 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1788 AST_SYMBOL (aexpr)->rname, op,
1789 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1792 val->etype = getSpec (val->type);
1796 /*-----------------------------------------------------------------*/
1797 /* valForCastAggr - will return value for a cast of an aggregate */
1798 /* with no constant */
1799 /*-----------------------------------------------------------------*/
1801 valForCastArr (ast * aexpr, sym_link * type)
1805 if (!IS_AST_SYM_VALUE (aexpr))
1810 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1811 AST_SYMBOL (aexpr)->rname);
1814 val->etype = getSpec (val->type);