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 -------------------------------------------------------------------------*/
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define LONG_LONG __int64
35 #define LONG_LONG long long
40 /*-----------------------------------------------------------------*/
41 /* newValue - allocates and returns a new value */
42 /*-----------------------------------------------------------------*/
48 val = Safe_alloc (sizeof (value));
53 /*-----------------------------------------------------------------*/
54 /* newiList - new initializer list */
55 /*-----------------------------------------------------------------*/
57 newiList (int type, void *ilist)
62 nilist = Safe_alloc (sizeof (initList));
65 nilist->lineno = yylineno;
70 nilist->init.node = (struct ast *) ilist;
74 nilist->init.deep = (struct initList *) ilist;
81 /*------------------------------------------------------------------*/
82 /* revinit - reverses the initial values for a value chain */
83 /*------------------------------------------------------------------*/
85 revinit (initList * val)
87 initList *prev, *curr, *next;
102 val->next = (void *) NULL;
107 convertIListToConstList(initList *src, literalList **lList)
110 literalList *head, *last, *newL;
114 if (!src || src->type != INIT_DEEP)
119 iLoop = src->init.deep;
123 if (iLoop->type != INIT_NODE)
128 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
135 // We've now established that the initializer list contains only literal values.
137 iLoop = src->init.deep;
140 double val = AST_LIT_VALUE(iLoop->init.node);
142 if (last && last->literalValue == val)
148 newL = Safe_alloc(sizeof(literalList));
149 newL->literalValue = val;
176 copyLiteralList(literalList *src)
178 literalList *head, *prev, *newL;
184 newL = Safe_alloc(sizeof(literalList));
186 newL->literalValue = src->literalValue;
187 newL->count = src->count;
207 /*------------------------------------------------------------------*/
208 /* copyIlist - copy initializer list */
209 /*------------------------------------------------------------------*/
211 copyIlist (initList * src)
213 initList *dest = NULL;
221 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
224 dest = newiList (INIT_NODE, copyAst (src->init.node));
229 dest->next = copyIlist (src->next);
234 /*------------------------------------------------------------------*/
235 /* list2int - converts the first element of the list to value */
236 /*------------------------------------------------------------------*/
238 list2int (initList * val)
242 if (i->type == INIT_DEEP)
243 return list2int (val->init.deep);
245 return floatFromVal (constExprValue (val->init.node, TRUE));
248 /*------------------------------------------------------------------*/
249 /* list2val - converts the first element of the list to value */
250 /*------------------------------------------------------------------*/
252 list2val (initList * val)
257 if (val->type == INIT_DEEP)
258 return list2val (val->init.deep);
260 return constExprValue (val->init.node, TRUE);
263 /*------------------------------------------------------------------*/
264 /* list2expr - returns the first expression in the initializer list */
265 /*------------------------------------------------------------------*/
267 list2expr (initList * ilist)
269 if (ilist->type == INIT_DEEP)
270 return list2expr (ilist->init.deep);
271 return ilist->init.node;
274 /*------------------------------------------------------------------*/
275 /* resolveIvalSym - resolve symbols in initial values */
276 /*------------------------------------------------------------------*/
278 resolveIvalSym (initList * ilist)
283 if (ilist->type == INIT_NODE)
284 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
286 if (ilist->type == INIT_DEEP)
287 resolveIvalSym (ilist->init.deep);
289 resolveIvalSym (ilist->next);
292 /*-----------------------------------------------------------------*/
293 /* symbolVal - creates a value for a symbol */
294 /*-----------------------------------------------------------------*/
296 symbolVal (symbol * sym)
308 val->type = sym->type;
309 val->etype = getSpec (val->type);
313 sprintf (val->name, "%s", sym->rname);
315 sprintf (val->name, "_%s", sym->name);
321 /*--------------------------------------------------------------------*/
322 /* cheapestVal - convert a val to the cheapest as possible value */
323 /*--------------------------------------------------------------------*/
324 value *cheapestVal (value *val) {
326 unsigned long uval=0;
328 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
331 if (SPEC_LONG(val->type)) {
332 if (SPEC_USIGN(val->type)) {
333 uval=SPEC_CVAL(val->type).v_ulong;
335 sval=SPEC_CVAL(val->type).v_long;
338 if (SPEC_USIGN(val->type)) {
339 uval=SPEC_CVAL(val->type).v_uint;
341 sval=SPEC_CVAL(val->type).v_int;
345 if (SPEC_USIGN(val->type)) {
347 SPEC_LONG(val->type)=0;
348 SPEC_CVAL(val->type).v_uint = uval;
351 SPEC_NOUN(val->type)=V_CHAR;
353 } else { // not unsigned
356 SPEC_LONG(val->type)=0;
357 SPEC_CVAL(val->type).v_int = sval & 0xffff;
360 SPEC_NOUN(val->type)=V_CHAR;
361 SPEC_CVAL(val->type).v_int &= 0xff;
364 SPEC_USIGN(val->type)=1;
366 SPEC_LONG(val->type)=0;
367 SPEC_CVAL(val->type).v_int = sval;
370 SPEC_NOUN(val->type)=V_CHAR;
377 /*-----------------------------------------------------------------*/
378 /* valueFromLit - creates a value from a literal */
379 /*-----------------------------------------------------------------*/
381 valueFromLit (double lit)
385 if ((((long) lit) - lit) == 0)
387 sprintf (buffer, "%ld", (long) lit);
388 return constVal (buffer);
391 sprintf (buffer, "%f", lit);
392 return constFloatVal (buffer);
395 /*-----------------------------------------------------------------*/
396 /* constFloatVal - converts a FLOAT constant to value */
397 /*-----------------------------------------------------------------*/
399 constFloatVal (char *s)
401 value *val = newValue ();
404 if (sscanf (s, "%lf", &sval) != 1)
406 werror (E_INVALID_FLOAT_CONST, s);
407 return constVal ("0");
410 val->type = val->etype = newLink ();
411 val->type->class = SPECIFIER;
412 SPEC_NOUN (val->type) = V_FLOAT;
413 SPEC_SCLS (val->type) = S_LITERAL;
414 SPEC_CVAL (val->type).v_float = sval;
419 /*-----------------------------------------------------------------*/
420 /* constVal - converts an INTEGER constant into a cheapest value */
421 /*-----------------------------------------------------------------*/
422 value *constVal (char *s)
425 short hex = 0, octal = 0;
430 val = newValue (); /* alloc space for value */
432 val->type = val->etype = newLink (); /* create the spcifier */
433 val->type->class = SPECIFIER;
434 SPEC_SCLS (val->type) = S_LITERAL;
435 // let's start with an unsigned char
436 SPEC_NOUN (val->type) = V_CHAR;
437 SPEC_USIGN (val->type) = 1;
439 /* set the _long flag if 'lL' is found */
440 if (strchr (s, 'l') || strchr (s, 'L'))
441 SPEC_LONG (val->type) = 1;
443 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
445 /* set the octal flag */
446 if (!hex && *s == '0' && *(s + 1))
449 /* create the scan string */
450 scanFmt[scI++] = '%';
452 scanFmt[scI++] = 'l';
453 scanFmt[scI++] = 'l';
456 scanFmt[scI++] = 'o';
458 scanFmt[scI++] = 'x';
460 scanFmt[scI++] = 'd';
462 scanFmt[scI++] = '\0';
464 sscanf (s, scanFmt, &sval);
466 if (sval<0) { // "-28u" will still be signed and negative
467 SPEC_USIGN (val->type) = 0;
468 if (sval<-32768) { // check if we have to promote to long
469 SPEC_NOUN (val->type) = V_INT;
470 SPEC_LONG (val->type) = 1;
471 SPEC_CVAL (val->type).v_long=sval;
473 SPEC_CVAL (val->type).v_int=sval;
474 if (sval<-128) { // check if we have to promote to int
475 SPEC_NOUN (val->type) = V_INT;
479 if (sval>0xffff) { // check if we have to promote to long
480 SPEC_NOUN (val->type) = V_INT;
481 SPEC_LONG (val->type) = 1;
482 SPEC_CVAL (val->type).v_ulong=sval;
484 SPEC_CVAL (val->type).v_uint=sval;
485 if (sval>0xff) { // check if we have to promote to int
486 SPEC_NOUN (val->type) = V_INT;
494 /*! /fn char hexEscape(char **src)
496 /param src Pointer to 'x' from start of hex character value
499 unsigned char hexEscape(char **src)
502 unsigned long value ;
504 (*src)++ ; /* Skip over the 'x' */
505 s = *src ; /* Save for error detection */
507 value = strtol (*src, src, 16);
510 // no valid hex found
511 werror(E_INVALID_HEX);
514 werror(W_ESC_SEQ_OOR_FOR_CHAR);
520 /*------------------------------------------------------------------*/
521 /* octalEscape - process an octal constant of max three digits */
522 /* return the octal value, throw a warning for illegal octal */
523 /* adjust src to point at the last proccesed char */
524 /*------------------------------------------------------------------*/
526 unsigned char octalEscape (char **str) {
530 for (digits=0; digits<3; digits++) {
531 if (**str>='0' && **str<='7') {
532 value = value*8 + (**str-'0');
539 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
540 werror (W_ESC_SEQ_OOR_FOR_CHAR);
547 /fn int copyStr (char *dest, char *src)
549 Copies a source string to a dest buffer interpreting escape sequences
550 and special characters
552 /param dest Buffer to receive the resultant string
553 /param src Buffer containing the source string with escape sequecnes
554 /return Number of characters in output string
559 copyStr (char *dest, char *src)
562 char *OriginalDest = dest ;
568 else if (*src == '\\')
603 *dest++ = octalEscape(&src);
608 *dest++ = hexEscape(&src) ;
635 return dest - OriginalDest ;
638 /*------------------------------------------------------------------*/
639 /* strVal - converts a string constant to a value */
640 /*------------------------------------------------------------------*/
646 val = newValue (); /* get a new one */
648 /* get a declarator */
649 val->type = newLink ();
650 DCL_TYPE (val->type) = ARRAY;
651 val->type->next = val->etype = newLink ();
652 val->etype->class = SPECIFIER;
653 SPEC_NOUN (val->etype) = V_CHAR;
654 SPEC_SCLS (val->etype) = S_LITERAL;
656 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
657 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
663 /*------------------------------------------------------------------*/
664 /* reverseValWithType - reverses value chain with type & etype */
665 /*------------------------------------------------------------------*/
667 reverseValWithType (value * val)
675 /* save the type * etype chains */
679 /* set the current one 2b null */
680 val->type = val->etype = NULL;
681 val = reverseVal (val);
683 /* restore type & etype */
690 /*------------------------------------------------------------------*/
691 /* reverseVal - reverses the values for a value chain */
692 /*------------------------------------------------------------------*/
694 reverseVal (value * val)
696 value *prev, *curr, *next;
711 val->next = (void *) NULL;
715 /*------------------------------------------------------------------*/
716 /* copyValueChain - will copy a chain of values */
717 /*------------------------------------------------------------------*/
719 copyValueChain (value * src)
726 dest = copyValue (src);
727 dest->next = copyValueChain (src->next);
732 /*------------------------------------------------------------------*/
733 /* copyValue - copies contents of a value to a fresh one */
734 /*------------------------------------------------------------------*/
736 copyValue (value * src)
741 dest->sym = copySymbol (src->sym);
742 strcpy (dest->name, src->name);
743 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
744 dest->etype = (src->type ? getSpec (dest->type) : NULL);
749 /*------------------------------------------------------------------*/
750 /* charVal - converts a character constant to a value */
751 /*------------------------------------------------------------------*/
760 val->type = val->etype = newLink ();
761 val->type->class = SPECIFIER;
762 SPEC_NOUN (val->type) = V_CHAR;
763 SPEC_USIGN(val->type) = 1;
764 SPEC_SCLS (val->type) = S_LITERAL;
766 s++; /* get rid of quotation */
767 /* if \ then special processing */
770 s++; /* go beyond the backslash */
774 SPEC_CVAL (val->type).v_int = '\n';
777 SPEC_CVAL (val->type).v_int = '\t';
780 SPEC_CVAL (val->type).v_int = '\v';
783 SPEC_CVAL (val->type).v_int = '\b';
786 SPEC_CVAL (val->type).v_int = '\r';
789 SPEC_CVAL (val->type).v_int = '\f';
792 SPEC_CVAL (val->type).v_int = '\a';
795 SPEC_CVAL (val->type).v_int = '\\';
798 SPEC_CVAL (val->type).v_int = '\?';
801 SPEC_CVAL (val->type).v_int = '\'';
804 SPEC_CVAL (val->type).v_int = '\"';
815 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
819 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
823 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
827 else /* not a backslash */
828 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
833 /*------------------------------------------------------------------*/
834 /* valFromType - creates a value from type given */
835 /*------------------------------------------------------------------*/
837 valFromType (sym_link * type)
839 value *val = newValue ();
840 val->type = copyLinkChain (type);
841 val->etype = getSpec (val->type);
845 /*------------------------------------------------------------------*/
846 /* floatFromVal - value to unsinged integer conversion */
847 /*------------------------------------------------------------------*/
849 floatFromVal (value * val)
854 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
856 werror (E_CONST_EXPECTED, val->name);
860 /* if it is not a specifier then we can assume that */
861 /* it will be an unsigned long */
862 if (!IS_SPEC (val->type))
863 return (double) SPEC_CVAL (val->etype).v_ulong;
865 if (SPEC_NOUN (val->etype) == V_FLOAT)
866 return (double) SPEC_CVAL (val->etype).v_float;
868 if (SPEC_LONG (val->etype))
870 if (SPEC_USIGN (val->etype))
871 return (double) SPEC_CVAL (val->etype).v_ulong;
873 return (double) SPEC_CVAL (val->etype).v_long;
876 if (SPEC_NOUN(val->etype)==V_INT) {
877 if (SPEC_USIGN (val->etype))
878 return (double) SPEC_CVAL (val->etype).v_uint;
880 return (double) SPEC_CVAL (val->etype).v_int;
881 } else { // SPEC_NOUN==V_CHAR
882 if (SPEC_USIGN (val->etype))
883 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
885 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
890 /*------------------------------------------------------------------*/
891 /* valUnaryPM - does the unary +/- operation on a constant */
892 /*------------------------------------------------------------------*/
894 valUnaryPM (value * val)
896 /* depending on type */
897 if (SPEC_NOUN (val->etype) == V_FLOAT)
898 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
901 if (SPEC_LONG (val->etype))
903 if (SPEC_USIGN (val->etype))
904 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
906 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
910 if (SPEC_USIGN (val->etype))
911 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
913 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
914 if (SPEC_NOUN (val->etype)==V_CHAR) {
915 SPEC_CVAL (val->etype).v_uint &= 0xff;
919 // -(unsigned 3) now really is signed
920 SPEC_USIGN(val->etype)=0;
924 /*------------------------------------------------------------------*/
925 /* valueComplement - complements a constant */
926 /*------------------------------------------------------------------*/
928 valComplement (value * val)
930 /* depending on type */
931 if (SPEC_LONG (val->etype))
933 if (SPEC_USIGN (val->etype))
934 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
936 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
940 if (SPEC_USIGN (val->etype))
941 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
943 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
944 if (SPEC_NOUN (val->etype)==V_CHAR) {
945 SPEC_CVAL (val->etype).v_uint &= 0xff;
951 /*------------------------------------------------------------------*/
952 /* valueNot - complements a constant */
953 /*------------------------------------------------------------------*/
957 /* depending on type */
958 if (SPEC_LONG (val->etype))
960 if (SPEC_USIGN (val->etype))
961 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
963 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
967 if (SPEC_USIGN (val->etype))
968 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
970 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
971 if (SPEC_NOUN (val->etype)==V_CHAR) {
972 SPEC_CVAL (val->etype).v_uint &= 0xff;
978 /*------------------------------------------------------------------*/
979 /* valMult - multiply constants */
980 /*------------------------------------------------------------------*/
982 valMult (value * lval, value * rval)
986 /* create a new value */
988 val->type = val->etype = newLink ();
989 val->type->class = SPECIFIER;
990 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
991 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
992 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
993 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
994 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
996 if (IS_FLOAT (val->type))
997 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1000 if (SPEC_LONG (val->type))
1002 if (SPEC_USIGN (val->type))
1003 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1004 (unsigned long) floatFromVal (rval);
1006 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1007 (long) floatFromVal (rval);
1011 if (SPEC_USIGN (val->type))
1012 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1013 (unsigned) floatFromVal (rval);
1015 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1016 (int) floatFromVal (rval);
1019 return cheapestVal(val);
1022 /*------------------------------------------------------------------*/
1023 /* valDiv - Divide constants */
1024 /*------------------------------------------------------------------*/
1026 valDiv (value * lval, value * rval)
1030 if (floatFromVal (rval) == 0)
1032 werror (E_DIVIDE_BY_ZERO);
1036 /* create a new value */
1038 val->type = val->etype = newLink();
1039 val->type->class = SPECIFIER;
1040 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1041 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1042 SPEC_SCLS (val->etype) = S_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);
1050 if (SPEC_LONG (val->type))
1052 if (SPEC_USIGN (val->type))
1053 SPEC_CVAL (val->type).v_ulong =
1054 (unsigned long) floatFromVal (lval) /
1055 (unsigned long) floatFromVal (rval);
1057 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1058 (long) floatFromVal (rval);
1062 if (SPEC_USIGN (val->type)) {
1063 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1064 (unsigned) floatFromVal (rval);
1066 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1067 (int) floatFromVal (rval);
1071 return cheapestVal(val);
1074 /*------------------------------------------------------------------*/
1075 /* valMod - Modulus constants */
1076 /*------------------------------------------------------------------*/
1078 valMod (value * lval, value * rval)
1082 /* create a new value */
1084 val->type = val->etype = newLink ();
1085 val->type->class = SPECIFIER;
1086 SPEC_NOUN (val->type) = V_INT; /* type is int */
1087 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1088 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1089 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1091 if (SPEC_LONG (val->type))
1093 if (SPEC_USIGN (val->type))
1094 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1095 (unsigned long) floatFromVal (rval);
1097 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1098 (unsigned long) floatFromVal (rval);
1102 if (SPEC_USIGN (val->type)) {
1103 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1104 (unsigned) floatFromVal (rval);
1106 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1107 (unsigned) floatFromVal (rval);
1111 return cheapestVal(val);
1114 /*------------------------------------------------------------------*/
1115 /* valPlus - Addition constants */
1116 /*------------------------------------------------------------------*/
1118 valPlus (value * lval, value * rval)
1122 /* create a new value */
1124 val->type = val->etype = newLink ();
1125 val->type->class = SPECIFIER;
1126 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1127 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1128 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1129 SPEC_USIGN (val->type) =
1130 SPEC_USIGN (lval->etype) &&
1131 SPEC_USIGN (rval->etype) &&
1132 (floatFromVal(lval)+floatFromVal(rval))>=0;
1134 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1136 if (IS_FLOAT (val->type))
1137 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1140 if (SPEC_LONG (val->type))
1142 if (SPEC_USIGN (val->type))
1143 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1144 (unsigned long) floatFromVal (rval);
1146 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1147 (long) floatFromVal (rval);
1151 if (SPEC_USIGN (val->type)) {
1152 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1153 (unsigned) floatFromVal (rval);
1155 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1156 (int) floatFromVal (rval);
1160 return cheapestVal(val);
1163 /*------------------------------------------------------------------*/
1164 /* valMinus - Addition constants */
1165 /*------------------------------------------------------------------*/
1167 valMinus (value * lval, value * rval)
1171 /* create a new value */
1173 val->type = val->etype = newLink ();
1174 val->type->class = SPECIFIER;
1175 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1176 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1177 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1178 SPEC_USIGN (val->type) =
1179 SPEC_USIGN (lval->etype) &&
1180 SPEC_USIGN (rval->etype) &&
1181 (floatFromVal(lval)-floatFromVal(rval))>=0;
1183 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1185 if (IS_FLOAT (val->type))
1186 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1189 if (SPEC_LONG (val->type))
1191 if (SPEC_USIGN (val->type)) {
1192 SPEC_CVAL (val->type).v_ulong =
1193 (unsigned long) floatFromVal (lval) -
1194 (unsigned long) floatFromVal (rval);
1196 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1197 (long) floatFromVal (rval);
1202 if (SPEC_USIGN (val->type)) {
1203 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1204 (unsigned) floatFromVal (rval);
1206 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1207 (int) floatFromVal (rval);
1211 return cheapestVal(val);
1214 /*------------------------------------------------------------------*/
1215 /* valShift - Shift left or right */
1216 /*------------------------------------------------------------------*/
1218 valShift (value * lval, value * rval, int lr)
1222 /* create a new value */
1224 val->type = val->etype = newIntLink ();
1225 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1226 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1227 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1229 if (SPEC_LONG (val->type))
1231 if (SPEC_USIGN (val->type))
1232 SPEC_CVAL (val->type).v_ulong = lr ?
1233 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1234 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1236 SPEC_CVAL (val->type).v_long = lr ?
1237 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1238 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1242 if (SPEC_USIGN (val->type)) {
1243 SPEC_CVAL (val->type).v_uint = lr ?
1244 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1245 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1247 SPEC_CVAL (val->type).v_int = lr ?
1248 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1249 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1253 return cheapestVal(val);
1256 /*------------------------------------------------------------------*/
1257 /* valCompare- Compares two literal */
1258 /*------------------------------------------------------------------*/
1260 valCompare (value * lval, value * rval, int ctype)
1264 /* create a new value */
1266 val->type = val->etype = newCharLink ();
1267 val->type->class = SPECIFIER;
1268 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1269 SPEC_USIGN (val->type) = 1;
1270 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1275 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1279 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1283 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1287 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1291 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1295 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1303 /*------------------------------------------------------------------*/
1304 /* valBitwise - Bitwise operation */
1305 /*------------------------------------------------------------------*/
1307 valBitwise (value * lval, value * rval, int op)
1311 /* create a new value */
1313 val->type = copyLinkChain (lval->type);
1314 val->etype = getSpec (val->type);
1319 if (SPEC_LONG (val->type))
1321 if (SPEC_USIGN (val->type))
1322 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1323 (unsigned long) floatFromVal (rval);
1325 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1326 (long) floatFromVal (rval);
1330 if (SPEC_USIGN (val->type))
1331 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1332 (unsigned) floatFromVal (rval);
1334 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1339 if (SPEC_LONG (val->type))
1341 if (SPEC_USIGN (val->type))
1342 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1343 (unsigned long) floatFromVal (rval);
1345 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1346 (long) floatFromVal (rval);
1350 if (SPEC_USIGN (val->type))
1351 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1352 (unsigned) floatFromVal (rval);
1354 SPEC_CVAL (val->type).v_int =
1355 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1361 if (SPEC_LONG (val->type))
1363 if (SPEC_USIGN (val->type))
1364 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1365 (unsigned long) floatFromVal (rval);
1367 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1368 (long) floatFromVal (rval);
1372 if (SPEC_USIGN (val->type))
1373 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1374 (unsigned) floatFromVal (rval);
1376 SPEC_CVAL (val->type).v_int =
1377 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1382 return cheapestVal(val);
1385 /*------------------------------------------------------------------*/
1386 /* valAndOr - Generates code for and / or operation */
1387 /*------------------------------------------------------------------*/
1389 valLogicAndOr (value * lval, value * rval, int op)
1393 /* create a new value */
1395 val->type = val->etype = newCharLink ();
1396 val->type->class = SPECIFIER;
1397 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1398 SPEC_USIGN (val->type) = 0;
1403 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1407 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1415 /*------------------------------------------------------------------*/
1416 /* valCastLiteral - casts a literal value to another type */
1417 /*------------------------------------------------------------------*/
1419 valCastLiteral (sym_link * dtype, double fval)
1427 val->etype = getSpec (val->type = copyLinkChain (dtype));
1428 SPEC_SCLS (val->etype) = S_LITERAL;
1429 /* if it is not a specifier then we can assume that */
1430 /* it will be an unsigned long */
1431 if (!IS_SPEC (val->type))
1433 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1437 if (SPEC_NOUN (val->etype) == V_FLOAT)
1438 SPEC_CVAL (val->etype).v_float = fval;
1441 if (SPEC_LONG (val->etype))
1443 if (SPEC_USIGN (val->etype))
1444 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1446 SPEC_CVAL (val->etype).v_long = (long) fval;
1450 if (SPEC_USIGN (val->etype))
1451 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1453 SPEC_CVAL (val->etype).v_int = (short)fval;
1454 if (SPEC_NOUN (val->etype)==V_CHAR) {
1455 SPEC_CVAL (val->etype).v_uint &= 0xff;
1462 /*------------------------------------------------------------------*/
1463 /* getNelements - determines # of elements from init list */
1464 /*------------------------------------------------------------------*/
1466 getNelements (sym_link * type, initList * ilist)
1468 sym_link *etype = getSpec (type);
1474 if (ilist->type == INIT_DEEP)
1475 ilist = ilist->init.deep;
1477 /* if type is a character array and there is only one
1478 (string) initialiser then get the length of the string */
1479 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1481 ast *iast = ilist->init.node;
1482 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1485 werror (W_INIT_WRONG);
1489 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1490 // yep, it's a string
1492 return DCL_ELEM (v->type);
1500 ilist = ilist->next;
1506 /*-----------------------------------------------------------------*/
1507 /* valForArray - returns a value with name of array index */
1508 /*-----------------------------------------------------------------*/
1510 valForArray (ast * arrExpr)
1512 value *val, *lval = NULL;
1514 int size = getSize (arrExpr->left->ftype->next);
1515 /* if the right or left is an array
1517 if (IS_AST_OP (arrExpr->left))
1519 if (arrExpr->left->opval.op == '[')
1520 lval = valForArray (arrExpr->left);
1521 else if (arrExpr->left->opval.op == '.')
1522 lval = valForStructElem (arrExpr->left->left,
1523 arrExpr->left->right);
1524 else if (arrExpr->left->opval.op == PTR_OP &&
1525 IS_ADDRESS_OF_OP (arrExpr->left->left))
1526 lval = valForStructElem (arrExpr->left->left->left,
1527 arrExpr->left->right);
1532 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1535 if (!IS_AST_LIT_VALUE (arrExpr->right))
1540 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1542 sprintf (buffer, "%s", lval->name);
1544 sprintf (val->name, "(%s + %d)", buffer,
1545 (int) AST_LIT_VALUE (arrExpr->right) * size);
1547 val->type = newLink ();
1548 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1550 DCL_TYPE (val->type) = CPOINTER;
1551 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1553 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1554 DCL_TYPE (val->type) = FPOINTER;
1555 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1556 DCL_TYPE (val->type) = PPOINTER;
1557 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1558 DCL_TYPE (val->type) = IPOINTER;
1559 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1560 DCL_TYPE (val->type) = EEPPOINTER;
1562 DCL_TYPE (val->type) = POINTER;
1563 val->type->next = arrExpr->left->ftype;
1564 val->etype = getSpec (val->type);
1568 /*-----------------------------------------------------------------*/
1569 /* valForStructElem - returns value with name of struct element */
1570 /*-----------------------------------------------------------------*/
1572 valForStructElem (ast * structT, ast * elemT)
1574 value *val, *lval = NULL;
1578 /* left could be furthur derefed */
1579 if (IS_AST_OP (structT))
1581 if (structT->opval.op == '[')
1582 lval = valForArray (structT);
1583 else if (structT->opval.op == '.')
1584 lval = valForStructElem (structT->left, structT->right);
1585 else if (structT->opval.op == PTR_OP &&
1586 IS_ADDRESS_OF_OP (structT->left))
1587 lval = valForStructElem (structT->left->left,
1593 if (!IS_AST_SYM_VALUE (elemT))
1596 if (!IS_STRUCT (structT->etype))
1599 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1600 AST_SYMBOL (elemT))) == NULL)
1607 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1609 sprintf (buffer, "%s", lval->name);
1611 sprintf (val->name, "(%s + %d)", buffer,
1614 val->type = newLink ();
1615 if (SPEC_SCLS (structT->etype) == S_CODE)
1617 DCL_TYPE (val->type) = CPOINTER;
1618 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1620 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1621 DCL_TYPE (val->type) = FPOINTER;
1622 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1623 DCL_TYPE (val->type) = PPOINTER;
1624 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1625 DCL_TYPE (val->type) = IPOINTER;
1626 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1627 DCL_TYPE (val->type) = EEPPOINTER;
1629 DCL_TYPE (val->type) = POINTER;
1630 val->type->next = sym->type;
1631 val->etype = getSpec (val->type);
1635 /*-----------------------------------------------------------------*/
1636 /* valForCastAggr - will return value for a cast of an aggregate */
1637 /* plus minus a constant */
1638 /*-----------------------------------------------------------------*/
1640 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1644 if (!IS_AST_SYM_VALUE (aexpr))
1646 if (!IS_AST_LIT_VALUE (cnst))
1651 sprintf (val->name, "(%s %c %d)",
1652 AST_SYMBOL (aexpr)->rname, op,
1653 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1656 val->etype = getSpec (val->type);
1660 /*-----------------------------------------------------------------*/
1661 /* valForCastAggr - will return value for a cast of an aggregate */
1662 /* with no constant */
1663 /*-----------------------------------------------------------------*/
1665 valForCastArr (ast * aexpr, sym_link * type)
1669 if (!IS_AST_SYM_VALUE (aexpr))
1674 sprintf (val->name, "(%s)",
1675 AST_SYMBOL (aexpr)->rname);
1678 val->etype = getSpec (val->type);