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;
374 /*-----------------------------------------------------------------*/
375 /* valueFromLit - creates a value from a literal */
376 /*-----------------------------------------------------------------*/
378 valueFromLit (double lit)
382 if ((((TYPE_DWORD) lit) - lit) == 0)
384 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
385 return constVal (buffer);
388 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
389 return constFloatVal (buffer);
392 /*-----------------------------------------------------------------*/
393 /* constFloatVal - converts a FLOAT constant to value */
394 /*-----------------------------------------------------------------*/
396 constFloatVal (char *s)
398 value *val = newValue ();
401 if (sscanf (s, "%lf", &sval) != 1)
403 werror (E_INVALID_FLOAT_CONST, s);
404 return constVal ("0");
407 val->type = val->etype = newLink (SPECIFIER);
408 SPEC_NOUN (val->type) = V_FLOAT;
409 SPEC_SCLS (val->type) = S_LITERAL;
410 SPEC_CVAL (val->type).v_float = sval;
415 /*-----------------------------------------------------------------*/
416 /* constVal - converts an INTEGER constant into a cheapest value */
417 /*-----------------------------------------------------------------*/
418 value *constVal (char *s)
421 short hex = 0, octal = 0;
426 val = newValue (); /* alloc space for value */
428 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
429 SPEC_SCLS (val->type) = S_LITERAL;
430 // let's start with an unsigned char
431 SPEC_NOUN (val->type) = V_CHAR;
432 SPEC_USIGN (val->type) = 0;
434 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
436 /* set the octal flag */
437 if (!hex && *s == '0' && *(s + 1))
440 /* create the scan string */
441 scanFmt[scI++] = '%';
443 scanFmt[scI++] = 'l';
446 scanFmt[scI++] = 'o';
448 scanFmt[scI++] = 'x';
450 scanFmt[scI++] = 'f';
452 scanFmt[scI++] = '\0';
456 sscanf (s, scanFmt, &sval);
459 sscanf (s, scanFmt, &dval);
462 /* Setup the flags first */
463 /* set the _long flag if 'lL' is found */
464 if (strchr (s, 'l') || strchr (s, 'L')) {
465 SPEC_NOUN (val->type) = V_INT;
466 SPEC_LONG (val->type) = 1;
469 /* set the unsigned flag if 'uU' is found */
470 if (strchr (s, 'u') || strchr (s, 'U')) {
471 SPEC_USIGN (val->type) = 1;
474 if (dval<0) { // "-28u" will still be signed and negative
475 if (dval<-128) { // check if we have to promote to int
476 SPEC_NOUN (val->type) = V_INT;
478 if (dval<-32768) { // check if we have to promote to long int
479 SPEC_LONG (val->type) = 1;
482 if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int
483 SPEC_NOUN (val->type) = V_INT;
485 else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
486 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
488 SPEC_USIGN (val->type) = 1;
490 SPEC_NOUN (val->type) = V_INT;
493 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
494 SPEC_LONG (val->type) = 1;
496 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
497 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
499 SPEC_USIGN (val->type) = 1;
501 SPEC_LONG (val->type) = 1;
502 if (dval>0x7fffffff) {
503 SPEC_USIGN (val->type) = 1;
509 if (SPEC_LONG (val->type))
511 if (SPEC_USIGN (val->type))
513 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
517 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
522 if (SPEC_USIGN (val->type))
524 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
528 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
535 /*! /fn char hexEscape(char **src)
537 /param src Pointer to 'x' from start of hex character value
540 unsigned char hexEscape(char **src)
543 unsigned long value ;
545 (*src)++ ; /* Skip over the 'x' */
546 s = *src ; /* Save for error detection */
548 value = strtol (*src, src, 16);
551 // no valid hex found
552 werror(E_INVALID_HEX);
555 werror(W_ESC_SEQ_OOR_FOR_CHAR);
561 /*------------------------------------------------------------------*/
562 /* octalEscape - process an octal constant of max three digits */
563 /* return the octal value, throw a warning for illegal octal */
564 /* adjust src to point at the last proccesed char */
565 /*------------------------------------------------------------------*/
567 unsigned char octalEscape (char **str) {
571 for (digits=0; digits<3; digits++) {
572 if (**str>='0' && **str<='7') {
573 value = value*8 + (**str-'0');
580 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
581 werror (W_ESC_SEQ_OOR_FOR_CHAR);
588 /fn int copyStr (char *dest, char *src)
590 Copies a source string to a dest buffer interpreting escape sequences
591 and special characters
593 /param dest Buffer to receive the resultant string
594 /param src Buffer containing the source string with escape sequecnes
595 /return Number of characters in output string
600 copyStr (char *dest, char *src)
603 char *OriginalDest = dest ;
609 else if (*src == '\\')
644 *dest++ = octalEscape(&src);
649 *dest++ = hexEscape(&src) ;
676 return dest - OriginalDest ;
679 /*------------------------------------------------------------------*/
680 /* strVal - converts a string constant to a value */
681 /*------------------------------------------------------------------*/
687 val = newValue (); /* get a new one */
689 /* get a declarator */
690 val->type = newLink (DECLARATOR);
691 DCL_TYPE (val->type) = ARRAY;
692 val->type->next = val->etype = newLink (SPECIFIER);
693 SPEC_NOUN (val->etype) = V_CHAR;
694 SPEC_SCLS (val->etype) = S_LITERAL;
696 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
697 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
703 /*------------------------------------------------------------------*/
704 /* reverseValWithType - reverses value chain with type & etype */
705 /*------------------------------------------------------------------*/
707 reverseValWithType (value * val)
715 /* save the type * etype chains */
719 /* set the current one 2b null */
720 val->type = val->etype = NULL;
721 val = reverseVal (val);
723 /* restore type & etype */
730 /*------------------------------------------------------------------*/
731 /* reverseVal - reverses the values for a value chain */
732 /*------------------------------------------------------------------*/
734 reverseVal (value * val)
736 value *prev, *curr, *next;
751 val->next = (void *) NULL;
755 /*------------------------------------------------------------------*/
756 /* copyValueChain - will copy a chain of values */
757 /*------------------------------------------------------------------*/
759 copyValueChain (value * src)
766 dest = copyValue (src);
767 dest->next = copyValueChain (src->next);
772 /*------------------------------------------------------------------*/
773 /* copyValue - copies contents of a value to a fresh one */
774 /*------------------------------------------------------------------*/
776 copyValue (value * src)
781 dest->sym = copySymbol (src->sym);
782 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
783 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
784 dest->etype = (src->type ? getSpec (dest->type) : NULL);
789 /*------------------------------------------------------------------*/
790 /* charVal - converts a character constant to a value */
791 /*------------------------------------------------------------------*/
799 val->type = val->etype = newLink (SPECIFIER);
800 SPEC_NOUN (val->type) = V_CHAR;
801 SPEC_USIGN(val->type) = 1;
802 SPEC_SCLS (val->type) = S_LITERAL;
804 s++; /* get rid of quotation */
805 /* if \ then special processing */
808 s++; /* go beyond the backslash */
812 SPEC_CVAL (val->type).v_uint = '\n';
815 SPEC_CVAL (val->type).v_uint = '\t';
818 SPEC_CVAL (val->type).v_uint = '\v';
821 SPEC_CVAL (val->type).v_uint = '\b';
824 SPEC_CVAL (val->type).v_uint = '\r';
827 SPEC_CVAL (val->type).v_uint = '\f';
830 SPEC_CVAL (val->type).v_uint = '\a';
833 SPEC_CVAL (val->type).v_uint = '\\';
836 SPEC_CVAL (val->type).v_uint = '\?';
839 SPEC_CVAL (val->type).v_uint = '\'';
842 SPEC_CVAL (val->type).v_uint = '\"';
853 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
857 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
861 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
865 else /* not a backslash */
866 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
871 /*------------------------------------------------------------------*/
872 /* valFromType - creates a value from type given */
873 /*------------------------------------------------------------------*/
875 valFromType (sym_link * type)
877 value *val = newValue ();
878 val->type = copyLinkChain (type);
879 val->etype = getSpec (val->type);
883 /*------------------------------------------------------------------*/
884 /* floatFromVal - value to double float conversion */
885 /*------------------------------------------------------------------*/
887 floatFromVal (value * val)
892 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
894 werror (E_CONST_EXPECTED, val->name);
898 /* if it is not a specifier then we can assume that */
899 /* it will be an unsigned long */
900 if (!IS_SPEC (val->type))
901 return (double) SPEC_CVAL (val->etype).v_ulong;
903 if (SPEC_NOUN (val->etype) == V_FLOAT)
904 return (double) SPEC_CVAL (val->etype).v_float;
906 if (SPEC_LONG (val->etype))
908 if (SPEC_USIGN (val->etype))
909 return (double) SPEC_CVAL (val->etype).v_ulong;
911 return (double) SPEC_CVAL (val->etype).v_long;
914 if (SPEC_NOUN (val->etype) == V_INT) {
915 if (SPEC_USIGN (val->etype))
916 return (double) SPEC_CVAL (val->etype).v_uint;
918 return (double) SPEC_CVAL (val->etype).v_int;
921 if (SPEC_NOUN (val->etype) == V_CHAR) {
922 if (SPEC_USIGN (val->etype))
923 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
925 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
928 if (IS_BITVAR(val->etype)) {
929 return (double) SPEC_CVAL (val->etype).v_uint;
932 if (SPEC_NOUN (val->etype) == V_VOID) {
933 return (double) SPEC_CVAL (val->etype).v_ulong;
937 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
938 "floatFromVal: unknown value");
942 /*------------------------------------------------------------------*/
943 /* valUnaryPM - does the unary +/- operation on a constant */
944 /*------------------------------------------------------------------*/
946 valUnaryPM (value * val)
948 /* depending on type */
949 if (SPEC_NOUN (val->etype) == V_FLOAT)
950 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
953 if (SPEC_LONG (val->etype))
955 if (SPEC_USIGN (val->etype))
956 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
958 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
962 if (SPEC_USIGN (val->etype))
963 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
965 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
968 // -(unsigned 3) now really is signed
969 SPEC_USIGN(val->etype)=0;
970 // -(unsigned char)135 now really is an int
971 if (SPEC_NOUN(val->etype) == V_CHAR) {
972 if (SPEC_CVAL(val->etype).v_int < -128) {
973 SPEC_NOUN(val->etype) = V_INT;
979 /*------------------------------------------------------------------*/
980 /* valueComplement - complements a constant */
981 /*------------------------------------------------------------------*/
983 valComplement (value * val)
985 /* depending on type */
986 if (SPEC_LONG (val->etype))
988 if (SPEC_USIGN (val->etype))
989 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
991 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
995 if (SPEC_USIGN (val->etype))
996 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
998 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1000 // ~(unsigned 3) now really is signed
1001 SPEC_USIGN(val->etype)=0;
1005 /*------------------------------------------------------------------*/
1006 /* valueNot - complements a constant */
1007 /*------------------------------------------------------------------*/
1009 valNot (value * val)
1011 /* depending on type */
1012 if (SPEC_LONG (val->etype))
1014 if (SPEC_USIGN (val->etype))
1015 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1017 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1021 if (SPEC_USIGN (val->etype))
1022 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1024 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1029 /*------------------------------------------------------------------*/
1030 /* valMult - multiply constants */
1031 /*------------------------------------------------------------------*/
1033 valMult (value * lval, value * rval)
1037 /* create a new value */
1039 val->type = val->etype = newLink (SPECIFIER);
1040 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1041 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1042 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1043 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1044 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1046 if (IS_FLOAT (val->type))
1047 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1048 /* signed and unsigned mul are the same, as long as the precision of the
1049 result isn't bigger than the precision of the operands. */
1050 else if (SPEC_LONG (val->type))
1051 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1052 (TYPE_UDWORD) floatFromVal (rval);
1053 else if (SPEC_USIGN (val->type)) /* unsigned */
1055 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1056 (TYPE_UWORD) floatFromVal (rval);
1058 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1059 if (!options.lessPedantic &&
1060 ul != SPEC_CVAL (val->type).v_uint)
1065 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1066 (TYPE_WORD) floatFromVal (rval);
1068 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1069 if (!options.lessPedantic &&
1070 l != SPEC_CVAL (val->type).v_int)
1073 #ifdef REDUCE_LITERALS
1074 return cheapestVal(val);
1080 /*------------------------------------------------------------------*/
1081 /* valDiv - Divide constants */
1082 /*------------------------------------------------------------------*/
1084 valDiv (value * lval, value * rval)
1088 if (floatFromVal (rval) == 0)
1090 werror (E_DIVIDE_BY_ZERO);
1094 /* create a new value */
1096 val->type = val->etype = newLink(SPECIFIER);
1097 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1098 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1099 SPEC_SCLS (val->etype) = S_LITERAL;
1100 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1101 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1103 if (IS_FLOAT (val->type))
1104 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1107 if (SPEC_LONG (val->type))
1109 if (SPEC_USIGN (val->type))
1110 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1111 (TYPE_UDWORD) floatFromVal (rval);
1113 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1114 (TYPE_DWORD) floatFromVal (rval);
1118 if (SPEC_USIGN (val->type)) {
1119 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1120 (TYPE_UWORD) floatFromVal (rval);
1122 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1123 (TYPE_WORD) floatFromVal (rval);
1127 #ifdef REDUCE_LITERALS
1128 return cheapestVal(val);
1134 /*------------------------------------------------------------------*/
1135 /* valMod - Modulus constants */
1136 /*------------------------------------------------------------------*/
1138 valMod (value * lval, value * rval)
1142 /* create a new value */
1144 val->type = val->etype = newLink (SPECIFIER);
1145 SPEC_NOUN (val->type) = V_INT; /* type is int */
1146 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1147 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1148 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1150 if (SPEC_LONG (val->type))
1152 if (SPEC_USIGN (val->type))
1153 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1154 (TYPE_UDWORD) floatFromVal (rval);
1156 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1157 (TYPE_DWORD) floatFromVal (rval);
1161 if (SPEC_USIGN (val->type)) {
1162 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1163 (TYPE_UWORD) floatFromVal (rval);
1165 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1166 (TYPE_WORD) floatFromVal (rval);
1170 #ifdef REDUCE_LITERALS
1171 return cheapestVal(val);
1177 /*------------------------------------------------------------------*/
1178 /* valPlus - Addition constants */
1179 /*------------------------------------------------------------------*/
1181 valPlus (value * lval, value * rval)
1185 /* create a new value */
1187 val->type = val->etype = newLink (SPECIFIER);
1188 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1189 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1190 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1191 SPEC_USIGN (val->type) =
1192 SPEC_USIGN (lval->etype) &&
1193 SPEC_USIGN (rval->etype) &&
1194 (floatFromVal(lval)+floatFromVal(rval))>=0;
1196 SPEC_LONG (val->type) = 1;
1198 if (IS_FLOAT (val->type))
1199 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1202 if (SPEC_LONG (val->type))
1204 if (SPEC_USIGN (val->type))
1205 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1206 (unsigned long) floatFromVal (rval);
1208 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1209 (long) floatFromVal (rval);
1212 #ifdef REDUCE_LITERALS
1213 return cheapestVal(val);
1219 /*------------------------------------------------------------------*/
1220 /* valMinus - Addition constants */
1221 /*------------------------------------------------------------------*/
1223 valMinus (value * lval, value * rval)
1227 /* create a new value */
1229 val->type = val->etype = newLink (SPECIFIER);
1230 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1231 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1232 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1233 SPEC_USIGN (val->type) =
1234 SPEC_USIGN (lval->etype) &&
1235 SPEC_USIGN (rval->etype) &&
1236 (floatFromVal(lval)-floatFromVal(rval))>=0;
1238 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1240 if (IS_FLOAT (val->type))
1241 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1244 if (SPEC_LONG (val->type))
1246 if (SPEC_USIGN (val->type)) {
1247 SPEC_CVAL (val->type).v_ulong =
1248 (unsigned long) floatFromVal (lval) -
1249 (unsigned long) floatFromVal (rval);
1251 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1252 (long) floatFromVal (rval);
1257 if (SPEC_USIGN (val->type)) {
1258 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1259 (unsigned) floatFromVal (rval);
1261 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1262 (int) floatFromVal (rval);
1266 #ifdef REDUCE_LITERALS
1267 return cheapestVal(val);
1273 /*------------------------------------------------------------------*/
1274 /* valShift - Shift left or right */
1275 /*------------------------------------------------------------------*/
1277 valShift (value * lval, value * rval, int lr)
1281 /* create a new value */
1283 val->type = val->etype = newIntLink ();
1284 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1285 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1286 SPEC_LONG (val->type) = 1;
1288 if (SPEC_LONG (val->type))
1290 if (SPEC_USIGN (val->type))
1291 SPEC_CVAL (val->type).v_ulong = lr ?
1292 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1293 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1295 SPEC_CVAL (val->type).v_long = lr ?
1296 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1297 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1300 #ifdef REDUCE_LITERALS
1301 return cheapestVal(val);
1307 /*------------------------------------------------------------------*/
1308 /* valCompare- Compares two literal */
1309 /*------------------------------------------------------------------*/
1311 valCompare (value * lval, value * rval, int ctype)
1315 /* create a new value */
1317 val->type = val->etype = newCharLink ();
1318 val->type->class = SPECIFIER;
1319 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1320 SPEC_USIGN (val->type) = 1;
1321 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1326 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1330 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1334 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1338 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1342 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1346 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1354 /*------------------------------------------------------------------*/
1355 /* valBitwise - Bitwise operation */
1356 /*------------------------------------------------------------------*/
1358 valBitwise (value * lval, value * rval, int op)
1362 /* create a new value */
1364 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1365 rval->type : lval->type);
1366 val->etype = getSpec (val->type);
1371 if (SPEC_LONG (val->type))
1373 if (SPEC_USIGN (val->type))
1374 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1375 (unsigned long) floatFromVal (rval);
1377 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1378 (long) floatFromVal (rval);
1382 if (SPEC_USIGN (val->type))
1383 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1384 (unsigned) floatFromVal (rval);
1386 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1391 if (SPEC_LONG (val->type))
1393 if (SPEC_USIGN (val->type))
1394 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1395 (unsigned long) floatFromVal (rval);
1397 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1398 (long) floatFromVal (rval);
1402 if (SPEC_USIGN (val->type))
1403 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1404 (unsigned) floatFromVal (rval);
1406 SPEC_CVAL (val->type).v_int =
1407 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1413 if (SPEC_LONG (val->type))
1415 if (SPEC_USIGN (val->type))
1416 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1417 (unsigned long) floatFromVal (rval);
1419 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1420 (long) floatFromVal (rval);
1424 if (SPEC_USIGN (val->type))
1425 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1426 (unsigned) floatFromVal (rval);
1428 SPEC_CVAL (val->type).v_int =
1429 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1434 #ifdef REDUCE_LITERALS
1435 return cheapestVal(val);
1441 /*------------------------------------------------------------------*/
1442 /* valAndOr - Generates code for and / or operation */
1443 /*------------------------------------------------------------------*/
1445 valLogicAndOr (value * lval, value * rval, int op)
1449 /* create a new value */
1451 val->type = val->etype = newCharLink ();
1452 val->type->class = SPECIFIER;
1453 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1454 SPEC_USIGN (val->type) = 0;
1459 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1463 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1471 /*------------------------------------------------------------------*/
1472 /* valCastLiteral - casts a literal value to another type */
1473 /*------------------------------------------------------------------*/
1475 valCastLiteral (sym_link * dtype, double fval)
1478 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1484 val->etype = getSpec (val->type = copyLinkChain (dtype));
1485 SPEC_SCLS (val->etype) = S_LITERAL;
1487 /* if it is not a specifier then we can assume that */
1488 /* it will be an unsigned long */
1489 if (!IS_SPEC (val->type)) {
1490 SPEC_CVAL (val->etype).v_ulong = l;
1494 if (SPEC_NOUN (val->etype) == V_FLOAT)
1495 SPEC_CVAL (val->etype).v_float = fval;
1496 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1497 if (SPEC_USIGN (val->etype))
1498 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1500 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1502 if (SPEC_LONG (val->etype)) {
1503 if (SPEC_USIGN (val->etype))
1504 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1506 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1508 if (SPEC_USIGN (val->etype))
1509 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1511 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1517 /*------------------------------------------------------------------*/
1518 /* getNelements - determines # of elements from init list */
1519 /*------------------------------------------------------------------*/
1521 getNelements (sym_link * type, initList * ilist)
1528 if (ilist->type == INIT_DEEP)
1529 ilist = ilist->init.deep;
1531 /* if type is a character array and there is only one
1532 (string) initialiser then get the length of the string */
1533 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1535 ast *iast = ilist->init.node;
1536 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1539 werror (E_CONST_EXPECTED);
1543 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1544 // yep, it's a string
1546 return DCL_ELEM (v->type);
1554 ilist = ilist->next;
1559 /*-----------------------------------------------------------------*/
1560 /* valForArray - returns a value with name of array index */
1561 /*-----------------------------------------------------------------*/
1563 valForArray (ast * arrExpr)
1565 value *val, *lval = NULL;
1567 int size = getSize (arrExpr->left->ftype->next);
1568 /* if the right or left is an array
1570 if (IS_AST_OP (arrExpr->left))
1572 if (arrExpr->left->opval.op == '[')
1573 lval = valForArray (arrExpr->left);
1574 else if (arrExpr->left->opval.op == '.')
1575 lval = valForStructElem (arrExpr->left->left,
1576 arrExpr->left->right);
1577 else if (arrExpr->left->opval.op == PTR_OP &&
1578 IS_ADDRESS_OF_OP (arrExpr->left->left))
1579 lval = valForStructElem (arrExpr->left->left->left,
1580 arrExpr->left->right);
1585 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1588 if (!IS_AST_LIT_VALUE (arrExpr->right))
1594 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1598 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1601 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1602 (int) AST_LIT_VALUE (arrExpr->right) * size);
1604 val->type = newLink (DECLARATOR);
1605 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1606 DCL_TYPE (val->type) = CPOINTER;
1607 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1608 DCL_TYPE (val->type) = FPOINTER;
1609 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1610 DCL_TYPE (val->type) = PPOINTER;
1611 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1612 DCL_TYPE (val->type) = IPOINTER;
1613 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1614 DCL_TYPE (val->type) = EEPPOINTER;
1616 DCL_TYPE (val->type) = POINTER;
1617 val->type->next = arrExpr->left->ftype;
1618 val->etype = getSpec (val->type);
1622 /*-----------------------------------------------------------------*/
1623 /* valForStructElem - returns value with name of struct element */
1624 /*-----------------------------------------------------------------*/
1626 valForStructElem (ast * structT, ast * elemT)
1628 value *val, *lval = NULL;
1632 /* left could be furthur derefed */
1633 if (IS_AST_OP (structT))
1635 if (structT->opval.op == '[')
1636 lval = valForArray (structT);
1637 else if (structT->opval.op == '.')
1638 lval = valForStructElem (structT->left, structT->right);
1639 else if (structT->opval.op == PTR_OP &&
1640 IS_ADDRESS_OF_OP (structT->left))
1641 lval = valForStructElem (structT->left->left,
1647 if (!IS_AST_SYM_VALUE (elemT))
1650 if (!IS_STRUCT (structT->etype))
1653 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1654 AST_SYMBOL (elemT))) == NULL)
1662 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1666 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1669 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1672 val->type = newLink (DECLARATOR);
1673 if (SPEC_SCLS (structT->etype) == S_CODE)
1674 DCL_TYPE (val->type) = CPOINTER;
1675 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1676 DCL_TYPE (val->type) = FPOINTER;
1677 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1678 DCL_TYPE (val->type) = PPOINTER;
1679 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1680 DCL_TYPE (val->type) = IPOINTER;
1681 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1682 DCL_TYPE (val->type) = EEPPOINTER;
1684 DCL_TYPE (val->type) = POINTER;
1685 val->type->next = sym->type;
1686 val->etype = getSpec (val->type);
1690 /*-----------------------------------------------------------------*/
1691 /* valForCastAggr - will return value for a cast of an aggregate */
1692 /* plus minus a constant */
1693 /*-----------------------------------------------------------------*/
1695 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1699 if (!IS_AST_SYM_VALUE (aexpr))
1701 if (!IS_AST_LIT_VALUE (cnst))
1706 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1707 AST_SYMBOL (aexpr)->rname, op,
1708 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1711 val->etype = getSpec (val->type);
1715 /*-----------------------------------------------------------------*/
1716 /* valForCastAggr - will return value for a cast of an aggregate */
1717 /* with no constant */
1718 /*-----------------------------------------------------------------*/
1720 valForCastArr (ast * aexpr, sym_link * type)
1724 if (!IS_AST_SYM_VALUE (aexpr))
1729 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1730 AST_SYMBOL (aexpr)->rname);
1733 val->etype = getSpec (val->type);