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_NONE;
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,
1090 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1092 if (IS_FLOAT (val->type))
1093 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1094 /* signed and unsigned mul are the same, as long as the precision of the
1095 result isn't bigger than the precision of the operands. */
1096 else if (SPEC_LONG (val->type))
1097 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1098 (TYPE_UDWORD) floatFromVal (rval);
1099 else if (SPEC_USIGN (val->type)) /* unsigned int */
1101 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1102 (TYPE_UWORD) floatFromVal (rval);
1104 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1105 if (ul != (TYPE_UWORD) ul)
1108 else /* signed int */
1110 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1111 (TYPE_WORD) floatFromVal (rval);
1113 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1114 if (l != (TYPE_WORD) l)
1117 return cheapestVal (val);
1120 /*------------------------------------------------------------------*/
1121 /* valDiv - Divide constants */
1122 /*------------------------------------------------------------------*/
1124 valDiv (value * lval, value * rval)
1128 if (floatFromVal (rval) == 0)
1130 werror (E_DIVIDE_BY_ZERO);
1134 /* create a new value */
1136 val->type = val->etype = computeType (lval->etype,
1139 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1141 if (IS_FLOAT (val->type))
1142 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1143 else if (SPEC_LONG (val->type))
1145 if (SPEC_USIGN (val->type))
1146 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1147 (TYPE_UDWORD) floatFromVal (rval);
1149 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1150 (TYPE_DWORD) floatFromVal (rval);
1154 if (SPEC_USIGN (val->type))
1155 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1156 (TYPE_UWORD) floatFromVal (rval);
1158 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1159 (TYPE_WORD) floatFromVal (rval);
1161 return cheapestVal (val);
1164 /*------------------------------------------------------------------*/
1165 /* valMod - Modulus constants */
1166 /*------------------------------------------------------------------*/
1168 valMod (value * lval, value * rval)
1172 /* create a new value */
1174 val->type = val->etype = computeType (lval->etype,
1177 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1179 if (SPEC_LONG (val->type))
1181 if (SPEC_USIGN (val->type))
1182 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1183 (TYPE_UDWORD) floatFromVal (rval);
1185 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1186 (TYPE_DWORD) floatFromVal (rval);
1190 if (SPEC_USIGN (val->type))
1191 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1192 (TYPE_UWORD) floatFromVal (rval);
1194 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1195 (TYPE_WORD) floatFromVal (rval);
1197 return cheapestVal (val);
1200 /*------------------------------------------------------------------*/
1201 /* valPlus - Addition constants */
1202 /*------------------------------------------------------------------*/
1204 valPlus (value * lval, value * rval)
1208 /* create a new value */
1210 val->type = val->etype = computeType (lval->etype,
1213 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1215 if (IS_FLOAT (val->type))
1216 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1217 else if (SPEC_LONG (val->type))
1219 if (SPEC_USIGN (val->type))
1220 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1221 (TYPE_UDWORD) floatFromVal (rval);
1223 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1224 (TYPE_DWORD) floatFromVal (rval);
1228 if (SPEC_USIGN (val->type))
1229 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1230 (TYPE_UWORD) floatFromVal (rval);
1232 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1233 (TYPE_WORD) floatFromVal (rval);
1235 return cheapestVal (val);
1238 /*------------------------------------------------------------------*/
1239 /* valMinus - Addition constants */
1240 /*------------------------------------------------------------------*/
1242 valMinus (value * lval, value * rval)
1246 /* create a new value */
1248 val->type = val->etype = computeType (lval->etype,
1251 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1253 if (IS_FLOAT (val->type))
1254 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1255 else if (SPEC_LONG (val->type))
1257 if (SPEC_USIGN (val->type))
1258 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1259 (TYPE_UDWORD) floatFromVal (rval);
1261 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1262 (TYPE_DWORD) floatFromVal (rval);
1266 if (SPEC_USIGN (val->type))
1267 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1268 (TYPE_UWORD) floatFromVal (rval);
1270 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1271 (TYPE_WORD) floatFromVal (rval);
1273 return cheapestVal (val);
1276 /*------------------------------------------------------------------*/
1277 /* valShift - Shift left or right */
1278 /*------------------------------------------------------------------*/
1280 valShift (value * lval, value * rval, int lr)
1284 /* create a new value */
1286 val->type = val->etype = computeType (lval->etype,
1288 /* promote left shift */
1290 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1292 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1295 /* right shift and unsigned */
1296 (!lr && SPEC_USIGN (rval->type))))
1298 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1301 if (SPEC_LONG (val->type))
1303 if (SPEC_USIGN (val->type))
1305 SPEC_CVAL (val->type).v_ulong = lr ?
1306 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1307 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1311 SPEC_CVAL (val->type).v_long = lr ?
1312 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1313 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1318 if (SPEC_USIGN (val->type))
1320 SPEC_CVAL (val->type).v_uint = lr ?
1321 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1322 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1326 SPEC_CVAL (val->type).v_int = lr ?
1327 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1328 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1331 return cheapestVal (val);
1334 /*------------------------------------------------------------------*/
1335 /* valCompare- Compares two literal */
1336 /*------------------------------------------------------------------*/
1338 valCompare (value * lval, value * rval, int ctype)
1342 /* create a new value */
1344 val->type = val->etype = newCharLink ();
1345 val->type->class = SPECIFIER;
1346 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1347 SPEC_USIGN (val->type) = 1;
1348 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1353 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1357 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1361 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1365 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1369 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1370 SPEC_NOUN(rval->type) == V_FLOAT)
1372 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1376 /* integrals: ignore signedness */
1379 l = (TYPE_UDWORD) floatFromVal (lval);
1380 r = (TYPE_UDWORD) floatFromVal (rval);
1381 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1382 neccessary to strip them to 16 bit.
1383 Literals are reduced to their cheapest type, therefore left and
1384 right might have different types. It's neccessary to find a
1385 common type: int (used for char too) or long */
1386 if (!IS_LONG (lval->etype) &&
1387 !IS_LONG (rval->etype))
1392 SPEC_CVAL (val->type).v_int = l == r;
1396 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1397 SPEC_NOUN(rval->type) == V_FLOAT)
1399 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1403 /* integrals: ignore signedness */
1406 l = (TYPE_UDWORD) floatFromVal (lval);
1407 r = (TYPE_UDWORD) floatFromVal (rval);
1408 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1409 neccessary to strip them to 16 bit.
1410 Literals are reduced to their cheapest type, therefore left and
1411 right might have different types. It's neccessary to find a
1412 common type: int (used for char too) or long */
1413 if (!IS_LONG (lval->etype) &&
1414 !IS_LONG (rval->etype))
1419 SPEC_CVAL (val->type).v_int = l != r;
1428 /*------------------------------------------------------------------*/
1429 /* valBitwise - Bitwise operation */
1430 /*------------------------------------------------------------------*/
1432 valBitwise (value * lval, value * rval, int op)
1436 /* create a new value */
1438 val->type = computeType (lval->etype, rval->etype, FALSE);
1439 val->etype = getSpec (val->type);
1440 SPEC_SCLS (val->etype) = S_LITERAL;
1445 if (SPEC_LONG (val->type))
1447 if (SPEC_USIGN (val->type))
1448 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1449 (TYPE_UDWORD) floatFromVal (rval);
1451 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1452 (TYPE_DWORD) floatFromVal (rval);
1456 if (SPEC_USIGN (val->type))
1457 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1458 (TYPE_UWORD) floatFromVal (rval);
1460 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1465 if (SPEC_LONG (val->type))
1467 if (SPEC_USIGN (val->type))
1468 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1469 (TYPE_UDWORD) floatFromVal (rval);
1471 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1472 (TYPE_DWORD) floatFromVal (rval);
1476 if (SPEC_USIGN (val->type))
1477 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1478 (TYPE_UWORD) floatFromVal (rval);
1480 SPEC_CVAL (val->type).v_int =
1481 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1487 if (SPEC_LONG (val->type))
1489 if (SPEC_USIGN (val->type))
1490 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1491 (TYPE_UDWORD) floatFromVal (rval);
1493 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1494 (TYPE_DWORD) floatFromVal (rval);
1498 if (SPEC_USIGN (val->type))
1499 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1500 (TYPE_UWORD) floatFromVal (rval);
1502 SPEC_CVAL (val->type).v_int =
1503 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1508 return cheapestVal(val);
1511 /*------------------------------------------------------------------*/
1512 /* valAndOr - Generates code for and / or operation */
1513 /*------------------------------------------------------------------*/
1515 valLogicAndOr (value * lval, value * rval, int op)
1519 /* create a new value */
1521 val->type = val->etype = newCharLink ();
1522 val->type->class = SPECIFIER;
1523 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1524 SPEC_USIGN (val->type) = 1;
1529 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1533 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1541 /*------------------------------------------------------------------*/
1542 /* valCastLiteral - casts a literal value to another type */
1543 /*------------------------------------------------------------------*/
1545 valCastLiteral (sym_link * dtype, double fval)
1548 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1554 val->etype = getSpec (val->type = copyLinkChain (dtype));
1555 SPEC_SCLS (val->etype) = S_LITERAL;
1557 /* if it is not a specifier then we can assume that */
1558 /* it will be an unsigned long */
1559 if (!IS_SPEC (val->type)) {
1560 SPEC_CVAL (val->etype).v_ulong = l;
1564 if (SPEC_NOUN (val->etype) == V_FLOAT)
1565 SPEC_CVAL (val->etype).v_float = fval;
1566 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1567 if (SPEC_USIGN (val->etype))
1568 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1570 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1572 if (SPEC_LONG (val->etype)) {
1573 if (SPEC_USIGN (val->etype))
1574 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1576 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1578 if (SPEC_USIGN (val->etype))
1579 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1581 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1587 /*------------------------------------------------------------------*/
1588 /* getNelements - determines # of elements from init list */
1589 /*------------------------------------------------------------------*/
1591 getNelements (sym_link * type, initList * ilist)
1598 if (ilist->type == INIT_DEEP)
1599 ilist = ilist->init.deep;
1601 /* if type is a character array and there is only one
1602 (string) initialiser then get the length of the string */
1603 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1605 ast *iast = ilist->init.node;
1606 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1609 werror (E_CONST_EXPECTED);
1613 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1614 // yep, it's a string
1616 return DCL_ELEM (v->type);
1624 ilist = ilist->next;
1629 /*-----------------------------------------------------------------*/
1630 /* valForArray - returns a value with name of array index */
1631 /*-----------------------------------------------------------------*/
1633 valForArray (ast * arrExpr)
1635 value *val, *lval = NULL;
1637 int size = getSize (arrExpr->left->ftype->next);
1638 /* if the right or left is an array
1640 if (IS_AST_OP (arrExpr->left))
1642 if (arrExpr->left->opval.op == '[')
1643 lval = valForArray (arrExpr->left);
1644 else if (arrExpr->left->opval.op == '.')
1645 lval = valForStructElem (arrExpr->left->left,
1646 arrExpr->left->right);
1647 else if (arrExpr->left->opval.op == PTR_OP &&
1648 IS_ADDRESS_OF_OP (arrExpr->left->left))
1649 lval = valForStructElem (arrExpr->left->left->left,
1650 arrExpr->left->right);
1655 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1658 if (!IS_AST_LIT_VALUE (arrExpr->right))
1664 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1668 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1671 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1672 (int) AST_LIT_VALUE (arrExpr->right) * size);
1674 val->type = newLink (DECLARATOR);
1675 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1676 DCL_TYPE (val->type) = CPOINTER;
1677 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1678 DCL_TYPE (val->type) = FPOINTER;
1679 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1680 DCL_TYPE (val->type) = PPOINTER;
1681 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1682 DCL_TYPE (val->type) = IPOINTER;
1683 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1684 DCL_TYPE (val->type) = EEPPOINTER;
1686 DCL_TYPE (val->type) = POINTER;
1687 val->type->next = arrExpr->left->ftype;
1688 val->etype = getSpec (val->type);
1692 /*-----------------------------------------------------------------*/
1693 /* valForStructElem - returns value with name of struct element */
1694 /*-----------------------------------------------------------------*/
1696 valForStructElem (ast * structT, ast * elemT)
1698 value *val, *lval = NULL;
1702 /* left could be furthur derefed */
1703 if (IS_AST_OP (structT))
1705 if (structT->opval.op == '[')
1706 lval = valForArray (structT);
1707 else if (structT->opval.op == '.')
1708 lval = valForStructElem (structT->left, structT->right);
1709 else if (structT->opval.op == PTR_OP &&
1710 IS_ADDRESS_OF_OP (structT->left))
1711 lval = valForStructElem (structT->left->left,
1717 if (!IS_AST_SYM_VALUE (elemT))
1720 if (!IS_STRUCT (structT->etype))
1723 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1724 AST_SYMBOL (elemT))) == NULL)
1732 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1736 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1739 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1742 val->type = newLink (DECLARATOR);
1743 if (SPEC_SCLS (structT->etype) == S_CODE)
1744 DCL_TYPE (val->type) = CPOINTER;
1745 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1746 DCL_TYPE (val->type) = FPOINTER;
1747 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1748 DCL_TYPE (val->type) = PPOINTER;
1749 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1750 DCL_TYPE (val->type) = IPOINTER;
1751 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1752 DCL_TYPE (val->type) = EEPPOINTER;
1754 DCL_TYPE (val->type) = POINTER;
1755 val->type->next = sym->type;
1756 val->etype = getSpec (val->type);
1760 /*-----------------------------------------------------------------*/
1761 /* valForCastAggr - will return value for a cast of an aggregate */
1762 /* plus minus a constant */
1763 /*-----------------------------------------------------------------*/
1765 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1769 if (!IS_AST_SYM_VALUE (aexpr))
1771 if (!IS_AST_LIT_VALUE (cnst))
1776 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1777 AST_SYMBOL (aexpr)->rname, op,
1778 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1781 val->etype = getSpec (val->type);
1785 /*-----------------------------------------------------------------*/
1786 /* valForCastAggr - will return value for a cast of an aggregate */
1787 /* with no constant */
1788 /*-----------------------------------------------------------------*/
1790 valForCastArr (ast * aexpr, sym_link * type)
1794 if (!IS_AST_SYM_VALUE (aexpr))
1799 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1800 AST_SYMBOL (aexpr)->rname);
1803 val->etype = getSpec (val->type);