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_NOUN(val->type)=V_CHAR;
348 SPEC_LONG(val->type)=0;
351 SPEC_LONG(val->type)=0;
357 SPEC_NOUN(val->type)=V_CHAR;
358 SPEC_CVAL(val->type).v_int &= 0xff;
359 SPEC_LONG(val->type)=0;
362 SPEC_LONG(val->type)=0;
367 SPEC_NOUN(val->type)=V_CHAR;
368 SPEC_LONG(val->type)=0;
371 SPEC_LONG(val->type)=0;
379 /*-----------------------------------------------------------------*/
380 /* valueFromLit - creates a value from a literal */
381 /*-----------------------------------------------------------------*/
383 valueFromLit (double lit)
387 if ((((long) lit) - lit) == 0)
389 sprintf (buffer, "%ld", (long) lit);
390 return constVal (buffer);
393 sprintf (buffer, "%f", lit);
394 return constFloatVal (buffer);
397 /*-----------------------------------------------------------------*/
398 /* constFloatVal - converts a FLOAT constant to value */
399 /*-----------------------------------------------------------------*/
401 constFloatVal (char *s)
403 value *val = newValue ();
406 if (sscanf (s, "%lf", &sval) != 1)
408 werror (E_INVALID_FLOAT_CONST, s);
409 return constVal ("0");
412 val->type = val->etype = newLink ();
413 val->type->class = SPECIFIER;
414 SPEC_NOUN (val->type) = V_FLOAT;
415 SPEC_SCLS (val->type) = S_LITERAL;
416 SPEC_CVAL (val->type).v_float = sval;
421 /*-----------------------------------------------------------------*/
422 /* constVal - converts an INTEGER constant into a cheapest value */
423 /*-----------------------------------------------------------------*/
424 value *constVal (char *s)
427 short hex = 0, octal = 0;
432 val = newValue (); /* alloc space for value */
434 val->type = val->etype = newLink (); /* create the spcifier */
435 val->type->class = SPECIFIER;
436 SPEC_SCLS (val->type) = S_LITERAL;
437 // let's start with an unsigned char
438 SPEC_NOUN (val->type) = V_CHAR;
439 SPEC_USIGN (val->type) = 1;
441 /* set the _long flag if 'lL' is found */
442 if (strchr (s, 'l') || strchr (s, 'L'))
443 SPEC_LONG (val->type) = 1;
445 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
447 /* set the octal flag */
448 if (!hex && *s == '0' && *(s + 1))
451 /* create the scan string */
452 scanFmt[scI++] = '%';
454 scanFmt[scI++] = 'l';
455 scanFmt[scI++] = 'l';
458 scanFmt[scI++] = 'o';
460 scanFmt[scI++] = 'x';
462 scanFmt[scI++] = 'd';
464 scanFmt[scI++] = '\0';
466 sscanf (s, scanFmt, &sval);
468 if (sval<0) { // "-28u" will still be signed and negative
469 SPEC_USIGN (val->type) = 0;
470 if (sval<-32768) { // check if we have to promote to long
471 SPEC_NOUN (val->type) = V_INT;
472 SPEC_LONG (val->type) = 1;
473 SPEC_CVAL (val->type).v_long=sval;
475 SPEC_CVAL (val->type).v_int=sval;
476 if (sval<-128) { // check if we have to promote to int
477 SPEC_NOUN (val->type) = V_INT;
481 if (sval>0xffff) { // check if we have to promote to long
482 SPEC_NOUN (val->type) = V_INT;
483 SPEC_LONG (val->type) = 1;
484 SPEC_CVAL (val->type).v_ulong=sval;
486 SPEC_CVAL (val->type).v_uint=sval;
487 if (sval>0xff) { // check if we have to promote to int
488 SPEC_NOUN (val->type) = V_INT;
496 /*! /fn char hexEscape(char **src)
498 /param src Pointer to 'x' from start of hex character value
501 unsigned char hexEscape(char **src)
504 unsigned long value ;
506 (*src)++ ; /* Skip over the 'x' */
507 s = *src ; /* Save for error detection */
509 value = strtol (*src, src, 16);
512 // no valid hex found
513 werror(E_INVALID_HEX);
516 werror(W_ESC_SEQ_OOR_FOR_CHAR);
522 /*------------------------------------------------------------------*/
523 /* octalEscape - process an octal constant of max three digits */
524 /* return the octal value, throw a warning for illegal octal */
525 /* adjust src to point at the last proccesed char */
526 /*------------------------------------------------------------------*/
528 unsigned char octalEscape (char **str) {
532 for (digits=0; digits<3; digits++) {
533 if (**str>='0' && **str<='7') {
534 value = value*8 + (**str-'0');
541 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
542 werror (W_ESC_SEQ_OOR_FOR_CHAR);
549 /fn int copyStr (char *dest, char *src)
551 Copies a source string to a dest buffer interpreting escape sequences
552 and special characters
554 /param dest Buffer to receive the resultant string
555 /param src Buffer containing the source string with escape sequecnes
556 /return Number of characters in output string
561 copyStr (char *dest, char *src)
564 char *OriginalDest = dest ;
570 else if (*src == '\\')
605 *dest++ = octalEscape(&src);
610 *dest++ = hexEscape(&src) ;
637 return dest - OriginalDest ;
640 /*------------------------------------------------------------------*/
641 /* strVal - converts a string constant to a value */
642 /*------------------------------------------------------------------*/
648 val = newValue (); /* get a new one */
650 /* get a declarator */
651 val->type = newLink ();
652 DCL_TYPE (val->type) = ARRAY;
653 val->type->next = val->etype = newLink ();
654 val->etype->class = SPECIFIER;
655 SPEC_NOUN (val->etype) = V_CHAR;
656 SPEC_SCLS (val->etype) = S_LITERAL;
658 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
659 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
665 /*------------------------------------------------------------------*/
666 /* reverseValWithType - reverses value chain with type & etype */
667 /*------------------------------------------------------------------*/
669 reverseValWithType (value * val)
677 /* save the type * etype chains */
681 /* set the current one 2b null */
682 val->type = val->etype = NULL;
683 val = reverseVal (val);
685 /* restore type & etype */
692 /*------------------------------------------------------------------*/
693 /* reverseVal - reverses the values for a value chain */
694 /*------------------------------------------------------------------*/
696 reverseVal (value * val)
698 value *prev, *curr, *next;
713 val->next = (void *) NULL;
717 /*------------------------------------------------------------------*/
718 /* copyValueChain - will copy a chain of values */
719 /*------------------------------------------------------------------*/
721 copyValueChain (value * src)
728 dest = copyValue (src);
729 dest->next = copyValueChain (src->next);
734 /*------------------------------------------------------------------*/
735 /* copyValue - copies contents of a value to a fresh one */
736 /*------------------------------------------------------------------*/
738 copyValue (value * src)
743 dest->sym = copySymbol (src->sym);
744 strcpy (dest->name, src->name);
745 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
746 dest->etype = (src->type ? getSpec (dest->type) : NULL);
751 /*------------------------------------------------------------------*/
752 /* charVal - converts a character constant to a value */
753 /*------------------------------------------------------------------*/
762 val->type = val->etype = newLink ();
763 val->type->class = SPECIFIER;
764 SPEC_NOUN (val->type) = V_CHAR;
765 SPEC_USIGN(val->type) = 1;
766 SPEC_SCLS (val->type) = S_LITERAL;
768 s++; /* get rid of quotation */
769 /* if \ then special processing */
772 s++; /* go beyond the backslash */
776 SPEC_CVAL (val->type).v_int = '\n';
779 SPEC_CVAL (val->type).v_int = '\t';
782 SPEC_CVAL (val->type).v_int = '\v';
785 SPEC_CVAL (val->type).v_int = '\b';
788 SPEC_CVAL (val->type).v_int = '\r';
791 SPEC_CVAL (val->type).v_int = '\f';
794 SPEC_CVAL (val->type).v_int = '\a';
797 SPEC_CVAL (val->type).v_int = '\\';
800 SPEC_CVAL (val->type).v_int = '\?';
803 SPEC_CVAL (val->type).v_int = '\'';
806 SPEC_CVAL (val->type).v_int = '\"';
817 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
821 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
825 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
829 else /* not a backslash */
830 SPEC_CVAL (val->type).v_int = (unsigned char)*s;
835 /*------------------------------------------------------------------*/
836 /* valFromType - creates a value from type given */
837 /*------------------------------------------------------------------*/
839 valFromType (sym_link * type)
841 value *val = newValue ();
842 val->type = copyLinkChain (type);
843 val->etype = getSpec (val->type);
847 /*------------------------------------------------------------------*/
848 /* floatFromVal - value to unsinged integer conversion */
849 /*------------------------------------------------------------------*/
851 floatFromVal (value * val)
856 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
858 werror (E_CONST_EXPECTED, val->name);
862 /* if it is not a specifier then we can assume that */
863 /* it will be an unsigned long */
864 if (!IS_SPEC (val->type))
865 return (double) SPEC_CVAL (val->etype).v_ulong;
867 if (SPEC_NOUN (val->etype) == V_FLOAT)
868 return (double) SPEC_CVAL (val->etype).v_float;
870 if (SPEC_LONG (val->etype))
872 if (SPEC_USIGN (val->etype))
873 return (double) SPEC_CVAL (val->etype).v_ulong;
875 return (double) SPEC_CVAL (val->etype).v_long;
878 if (SPEC_NOUN(val->etype)==V_INT) {
879 if (SPEC_USIGN (val->etype))
880 return (double) SPEC_CVAL (val->etype).v_uint;
882 return (double) SPEC_CVAL (val->etype).v_int;
883 } else { // SPEC_NOUN==V_CHAR
884 if (SPEC_USIGN (val->etype))
885 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
887 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
892 /*------------------------------------------------------------------*/
893 /* valUnaryPM - does the unary +/- operation on a constant */
894 /*------------------------------------------------------------------*/
896 valUnaryPM (value * val)
898 /* depending on type */
899 if (SPEC_NOUN (val->etype) == V_FLOAT)
900 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
903 if (SPEC_LONG (val->etype))
905 if (SPEC_USIGN (val->etype))
906 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
908 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
912 if (SPEC_USIGN (val->etype))
913 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
915 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
916 if (SPEC_NOUN (val->etype)==V_CHAR) {
917 SPEC_CVAL (val->etype).v_uint &= 0xff;
921 // -(unsigned 3) now really is signed
922 SPEC_USIGN(val->etype)=0;
926 /*------------------------------------------------------------------*/
927 /* valueComplement - complements a constant */
928 /*------------------------------------------------------------------*/
930 valComplement (value * val)
932 /* depending on type */
933 if (SPEC_LONG (val->etype))
935 if (SPEC_USIGN (val->etype))
936 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
938 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
942 if (SPEC_USIGN (val->etype))
943 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
945 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
946 if (SPEC_NOUN (val->etype)==V_CHAR) {
947 SPEC_CVAL (val->etype).v_uint &= 0xff;
953 /*------------------------------------------------------------------*/
954 /* valueNot - complements a constant */
955 /*------------------------------------------------------------------*/
959 /* depending on type */
960 if (SPEC_LONG (val->etype))
962 if (SPEC_USIGN (val->etype))
963 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
965 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
969 if (SPEC_USIGN (val->etype))
970 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
972 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
973 if (SPEC_NOUN (val->etype)==V_CHAR) {
974 SPEC_CVAL (val->etype).v_uint &= 0xff;
980 /*------------------------------------------------------------------*/
981 /* valMult - multiply constants */
982 /*------------------------------------------------------------------*/
984 valMult (value * lval, value * rval)
988 /* create a new value */
990 val->type = val->etype = newLink ();
991 val->type->class = SPECIFIER;
992 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
993 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
994 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
995 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
996 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
998 if (IS_FLOAT (val->type))
999 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1002 if (SPEC_LONG (val->type))
1004 if (SPEC_USIGN (val->type))
1005 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1006 (unsigned long) floatFromVal (rval);
1008 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1009 (long) floatFromVal (rval);
1013 if (SPEC_USIGN (val->type))
1014 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1015 (unsigned) floatFromVal (rval);
1017 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1018 (int) floatFromVal (rval);
1021 return cheapestVal(val);
1024 /*------------------------------------------------------------------*/
1025 /* valDiv - Divide constants */
1026 /*------------------------------------------------------------------*/
1028 valDiv (value * lval, value * rval)
1032 if (floatFromVal (rval) == 0)
1034 werror (E_DIVIDE_BY_ZERO);
1038 /* create a new value */
1040 val->type = val->etype = newLink();
1041 val->type->class = SPECIFIER;
1042 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1043 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1044 SPEC_SCLS (val->etype) = S_LITERAL;
1045 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1046 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1048 if (IS_FLOAT (val->type))
1049 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1052 if (SPEC_LONG (val->type))
1054 if (SPEC_USIGN (val->type))
1055 SPEC_CVAL (val->type).v_ulong =
1056 (unsigned long) floatFromVal (lval) /
1057 (unsigned long) floatFromVal (rval);
1059 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1060 (long) floatFromVal (rval);
1064 if (SPEC_USIGN (val->type)) {
1065 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1066 (unsigned) floatFromVal (rval);
1068 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1069 (int) floatFromVal (rval);
1073 return cheapestVal(val);
1076 /*------------------------------------------------------------------*/
1077 /* valMod - Modulus constants */
1078 /*------------------------------------------------------------------*/
1080 valMod (value * lval, value * rval)
1084 /* create a new value */
1086 val->type = val->etype = newLink ();
1087 val->type->class = SPECIFIER;
1088 SPEC_NOUN (val->type) = V_INT; /* type is int */
1089 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1090 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1091 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1093 if (SPEC_LONG (val->type))
1095 if (SPEC_USIGN (val->type))
1096 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1097 (unsigned long) floatFromVal (rval);
1099 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1100 (unsigned long) floatFromVal (rval);
1104 if (SPEC_USIGN (val->type)) {
1105 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1106 (unsigned) floatFromVal (rval);
1108 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1109 (unsigned) floatFromVal (rval);
1113 return cheapestVal(val);
1116 /*------------------------------------------------------------------*/
1117 /* valPlus - Addition constants */
1118 /*------------------------------------------------------------------*/
1120 valPlus (value * lval, value * rval)
1124 /* create a new value */
1126 val->type = val->etype = newLink ();
1127 val->type->class = SPECIFIER;
1128 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1129 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1130 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1131 SPEC_USIGN (val->type) =
1132 SPEC_USIGN (lval->etype) &&
1133 SPEC_USIGN (rval->etype) &&
1134 (floatFromVal(lval)+floatFromVal(rval))>=0;
1136 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1138 if (IS_FLOAT (val->type))
1139 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1142 if (SPEC_LONG (val->type))
1144 if (SPEC_USIGN (val->type))
1145 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1146 (unsigned long) floatFromVal (rval);
1148 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1149 (long) floatFromVal (rval);
1153 if (SPEC_USIGN (val->type)) {
1154 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1155 (unsigned) floatFromVal (rval);
1157 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1158 (int) floatFromVal (rval);
1162 return cheapestVal(val);
1165 /*------------------------------------------------------------------*/
1166 /* valMinus - Addition constants */
1167 /*------------------------------------------------------------------*/
1169 valMinus (value * lval, value * rval)
1173 /* create a new value */
1175 val->type = val->etype = newLink ();
1176 val->type->class = SPECIFIER;
1177 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1178 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1179 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1180 SPEC_USIGN (val->type) =
1181 SPEC_USIGN (lval->etype) &&
1182 SPEC_USIGN (rval->etype) &&
1183 (floatFromVal(lval)-floatFromVal(rval))>=0;
1185 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1187 if (IS_FLOAT (val->type))
1188 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1191 if (SPEC_LONG (val->type))
1193 if (SPEC_USIGN (val->type)) {
1194 SPEC_CVAL (val->type).v_ulong =
1195 (unsigned long) floatFromVal (lval) -
1196 (unsigned long) floatFromVal (rval);
1198 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1199 (long) floatFromVal (rval);
1204 if (SPEC_USIGN (val->type)) {
1205 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1206 (unsigned) floatFromVal (rval);
1208 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1209 (int) floatFromVal (rval);
1213 return cheapestVal(val);
1216 /*------------------------------------------------------------------*/
1217 /* valShift - Shift left or right */
1218 /*------------------------------------------------------------------*/
1220 valShift (value * lval, value * rval, int lr)
1224 /* create a new value */
1226 val->type = val->etype = newIntLink ();
1227 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1228 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1229 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1231 if (SPEC_LONG (val->type))
1233 if (SPEC_USIGN (val->type))
1234 SPEC_CVAL (val->type).v_ulong = lr ?
1235 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1236 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1238 SPEC_CVAL (val->type).v_long = lr ?
1239 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1240 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1244 if (SPEC_USIGN (val->type)) {
1245 SPEC_CVAL (val->type).v_uint = lr ?
1246 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1247 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1249 SPEC_CVAL (val->type).v_int = lr ?
1250 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1251 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1255 return cheapestVal(val);
1258 /*------------------------------------------------------------------*/
1259 /* valCompare- Compares two literal */
1260 /*------------------------------------------------------------------*/
1262 valCompare (value * lval, value * rval, int ctype)
1266 /* create a new value */
1268 val->type = val->etype = newCharLink ();
1269 val->type->class = SPECIFIER;
1270 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1271 SPEC_USIGN (val->type) = 1;
1272 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1277 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1281 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1285 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1289 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1293 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1297 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1305 /*------------------------------------------------------------------*/
1306 /* valBitwise - Bitwise operation */
1307 /*------------------------------------------------------------------*/
1309 valBitwise (value * lval, value * rval, int op)
1313 /* create a new value */
1315 val->type = copyLinkChain (lval->type);
1316 val->etype = getSpec (val->type);
1321 if (SPEC_LONG (val->type))
1323 if (SPEC_USIGN (val->type))
1324 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1325 (unsigned long) floatFromVal (rval);
1327 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1328 (long) floatFromVal (rval);
1332 if (SPEC_USIGN (val->type))
1333 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1334 (unsigned) floatFromVal (rval);
1336 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1341 if (SPEC_LONG (val->type))
1343 if (SPEC_USIGN (val->type))
1344 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1345 (unsigned long) floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1348 (long) floatFromVal (rval);
1352 if (SPEC_USIGN (val->type))
1353 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1354 (unsigned) floatFromVal (rval);
1356 SPEC_CVAL (val->type).v_int =
1357 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1363 if (SPEC_LONG (val->type))
1365 if (SPEC_USIGN (val->type))
1366 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1367 (unsigned long) floatFromVal (rval);
1369 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1370 (long) floatFromVal (rval);
1374 if (SPEC_USIGN (val->type))
1375 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1376 (unsigned) floatFromVal (rval);
1378 SPEC_CVAL (val->type).v_int =
1379 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1384 return cheapestVal(val);
1387 /*------------------------------------------------------------------*/
1388 /* valAndOr - Generates code for and / or operation */
1389 /*------------------------------------------------------------------*/
1391 valLogicAndOr (value * lval, value * rval, int op)
1395 /* create a new value */
1397 val->type = val->etype = newCharLink ();
1398 val->type->class = SPECIFIER;
1399 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1400 SPEC_USIGN (val->type) = 0;
1405 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1409 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1417 /*------------------------------------------------------------------*/
1418 /* valCastLiteral - casts a literal value to another type */
1419 /*------------------------------------------------------------------*/
1421 valCastLiteral (sym_link * dtype, double fval)
1429 val->etype = getSpec (val->type = copyLinkChain (dtype));
1430 SPEC_SCLS (val->etype) = S_LITERAL;
1431 /* if it is not a specifier then we can assume that */
1432 /* it will be an unsigned long */
1433 if (!IS_SPEC (val->type))
1435 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1439 if (SPEC_NOUN (val->etype) == V_FLOAT)
1440 SPEC_CVAL (val->etype).v_float = fval;
1443 if (SPEC_LONG (val->etype))
1445 if (SPEC_USIGN (val->etype))
1446 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1448 SPEC_CVAL (val->etype).v_long = (long) fval;
1452 if (SPEC_USIGN (val->etype))
1453 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1455 SPEC_CVAL (val->etype).v_int = (short)fval;
1456 if (SPEC_NOUN (val->etype)==V_CHAR) {
1457 SPEC_CVAL (val->etype).v_uint &= 0xff;
1464 /*------------------------------------------------------------------*/
1465 /* getNelements - determines # of elements from init list */
1466 /*------------------------------------------------------------------*/
1468 getNelements (sym_link * type, initList * ilist)
1470 sym_link *etype = getSpec (type);
1476 if (ilist->type == INIT_DEEP)
1477 ilist = ilist->init.deep;
1479 /* if type is a character array and there is only one
1480 (string) initialiser then get the length of the string */
1481 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1483 ast *iast = ilist->init.node;
1484 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1487 werror (W_INIT_WRONG);
1491 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1492 // yep, it's a string
1494 return DCL_ELEM (v->type);
1502 ilist = ilist->next;
1508 /*-----------------------------------------------------------------*/
1509 /* valForArray - returns a value with name of array index */
1510 /*-----------------------------------------------------------------*/
1512 valForArray (ast * arrExpr)
1514 value *val, *lval = NULL;
1516 int size = getSize (arrExpr->left->ftype->next);
1517 /* if the right or left is an array
1519 if (IS_AST_OP (arrExpr->left))
1521 if (arrExpr->left->opval.op == '[')
1522 lval = valForArray (arrExpr->left);
1523 else if (arrExpr->left->opval.op == '.')
1524 lval = valForStructElem (arrExpr->left->left,
1525 arrExpr->left->right);
1526 else if (arrExpr->left->opval.op == PTR_OP &&
1527 IS_ADDRESS_OF_OP (arrExpr->left->left))
1528 lval = valForStructElem (arrExpr->left->left->left,
1529 arrExpr->left->right);
1534 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1537 if (!IS_AST_LIT_VALUE (arrExpr->right))
1542 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1544 sprintf (buffer, "%s", lval->name);
1546 sprintf (val->name, "(%s + %d)", buffer,
1547 (int) AST_LIT_VALUE (arrExpr->right) * size);
1549 val->type = newLink ();
1550 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1552 DCL_TYPE (val->type) = CPOINTER;
1553 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1555 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1556 DCL_TYPE (val->type) = FPOINTER;
1557 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1558 DCL_TYPE (val->type) = PPOINTER;
1559 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1560 DCL_TYPE (val->type) = IPOINTER;
1561 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1562 DCL_TYPE (val->type) = EEPPOINTER;
1564 DCL_TYPE (val->type) = POINTER;
1565 val->type->next = arrExpr->left->ftype;
1566 val->etype = getSpec (val->type);
1570 /*-----------------------------------------------------------------*/
1571 /* valForStructElem - returns value with name of struct element */
1572 /*-----------------------------------------------------------------*/
1574 valForStructElem (ast * structT, ast * elemT)
1576 value *val, *lval = NULL;
1580 /* left could be furthur derefed */
1581 if (IS_AST_OP (structT))
1583 if (structT->opval.op == '[')
1584 lval = valForArray (structT);
1585 else if (structT->opval.op == '.')
1586 lval = valForStructElem (structT->left, structT->right);
1587 else if (structT->opval.op == PTR_OP &&
1588 IS_ADDRESS_OF_OP (structT->left))
1589 lval = valForStructElem (structT->left->left,
1595 if (!IS_AST_SYM_VALUE (elemT))
1598 if (!IS_STRUCT (structT->etype))
1601 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1602 AST_SYMBOL (elemT))) == NULL)
1609 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1611 sprintf (buffer, "%s", lval->name);
1613 sprintf (val->name, "(%s + %d)", buffer,
1616 val->type = newLink ();
1617 if (SPEC_SCLS (structT->etype) == S_CODE)
1619 DCL_TYPE (val->type) = CPOINTER;
1620 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1622 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1623 DCL_TYPE (val->type) = FPOINTER;
1624 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1625 DCL_TYPE (val->type) = PPOINTER;
1626 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1627 DCL_TYPE (val->type) = IPOINTER;
1628 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1629 DCL_TYPE (val->type) = EEPPOINTER;
1631 DCL_TYPE (val->type) = POINTER;
1632 val->type->next = sym->type;
1633 val->etype = getSpec (val->type);
1637 /*-----------------------------------------------------------------*/
1638 /* valForCastAggr - will return value for a cast of an aggregate */
1639 /* plus minus a constant */
1640 /*-----------------------------------------------------------------*/
1642 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1646 if (!IS_AST_SYM_VALUE (aexpr))
1648 if (!IS_AST_LIT_VALUE (cnst))
1653 sprintf (val->name, "(%s %c %d)",
1654 AST_SYMBOL (aexpr)->rname, op,
1655 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1658 val->etype = getSpec (val->type);
1662 /*-----------------------------------------------------------------*/
1663 /* valForCastAggr - will return value for a cast of an aggregate */
1664 /* with no constant */
1665 /*-----------------------------------------------------------------*/
1667 valForCastArr (ast * aexpr, sym_link * type)
1671 if (!IS_AST_SYM_VALUE (aexpr))
1676 sprintf (val->name, "(%s)",
1677 AST_SYMBOL (aexpr)->rname);
1680 val->etype = getSpec (val->type);