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 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
441 /* set the octal flag */
442 if (!hex && *s == '0' && *(s + 1))
445 /* create the scan string */
446 scanFmt[scI++] = '%';
448 scanFmt[scI++] = 'l';
449 scanFmt[scI++] = 'l';
452 scanFmt[scI++] = 'o';
454 scanFmt[scI++] = 'x';
456 scanFmt[scI++] = 'd';
458 scanFmt[scI++] = '\0';
460 sscanf (s, scanFmt, &sval);
462 /* Setup the flags first */
463 /* set the _long flag if 'lL' is found */
464 if (strchr (s, 'l') || strchr (s, 'L'))
465 SPEC_LONG (val->type) = 1;
467 if (sval<0) { // "-28u" will still be signed and negative
468 SPEC_USIGN (val->type) = 0;
469 if (sval<-32768) { // check if we have to promote to long
470 SPEC_NOUN (val->type) = V_INT;
471 SPEC_LONG (val->type) = 1;
473 if (sval<-128) { // check if we have to promote to int
474 SPEC_NOUN (val->type) = V_INT;
478 if (sval>0xffff) { // check if we have to promote to long
479 SPEC_NOUN (val->type) = V_INT;
480 SPEC_LONG (val->type) = 1;
482 if (sval>0xff) { // check if we have to promote to int
483 SPEC_NOUN (val->type) = V_INT;
488 if (SPEC_LONG (val->type))
490 if (SPEC_USIGN (val->type))
492 SPEC_CVAL (val->type).v_ulong = sval;
496 SPEC_CVAL (val->type).v_long = sval;
501 if (SPEC_USIGN (val->type))
503 SPEC_CVAL (val->type).v_uint = sval;
507 SPEC_CVAL (val->type).v_int = sval;
514 /*! /fn char hexEscape(char **src)
516 /param src Pointer to 'x' from start of hex character value
519 unsigned char hexEscape(char **src)
522 unsigned long value ;
524 (*src)++ ; /* Skip over the 'x' */
525 s = *src ; /* Save for error detection */
527 value = strtol (*src, src, 16);
530 // no valid hex found
531 werror(E_INVALID_HEX);
534 werror(W_ESC_SEQ_OOR_FOR_CHAR);
540 /*------------------------------------------------------------------*/
541 /* octalEscape - process an octal constant of max three digits */
542 /* return the octal value, throw a warning for illegal octal */
543 /* adjust src to point at the last proccesed char */
544 /*------------------------------------------------------------------*/
546 unsigned char octalEscape (char **str) {
550 for (digits=0; digits<3; digits++) {
551 if (**str>='0' && **str<='7') {
552 value = value*8 + (**str-'0');
559 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
560 werror (W_ESC_SEQ_OOR_FOR_CHAR);
567 /fn int copyStr (char *dest, char *src)
569 Copies a source string to a dest buffer interpreting escape sequences
570 and special characters
572 /param dest Buffer to receive the resultant string
573 /param src Buffer containing the source string with escape sequecnes
574 /return Number of characters in output string
579 copyStr (char *dest, char *src)
582 char *OriginalDest = dest ;
588 else if (*src == '\\')
623 *dest++ = octalEscape(&src);
628 *dest++ = hexEscape(&src) ;
655 return dest - OriginalDest ;
658 /*------------------------------------------------------------------*/
659 /* strVal - converts a string constant to a value */
660 /*------------------------------------------------------------------*/
666 val = newValue (); /* get a new one */
668 /* get a declarator */
669 val->type = newLink ();
670 DCL_TYPE (val->type) = ARRAY;
671 val->type->next = val->etype = newLink ();
672 val->etype->class = SPECIFIER;
673 SPEC_NOUN (val->etype) = V_CHAR;
674 SPEC_SCLS (val->etype) = S_LITERAL;
676 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
677 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
683 /*------------------------------------------------------------------*/
684 /* reverseValWithType - reverses value chain with type & etype */
685 /*------------------------------------------------------------------*/
687 reverseValWithType (value * val)
695 /* save the type * etype chains */
699 /* set the current one 2b null */
700 val->type = val->etype = NULL;
701 val = reverseVal (val);
703 /* restore type & etype */
710 /*------------------------------------------------------------------*/
711 /* reverseVal - reverses the values for a value chain */
712 /*------------------------------------------------------------------*/
714 reverseVal (value * val)
716 value *prev, *curr, *next;
731 val->next = (void *) NULL;
735 /*------------------------------------------------------------------*/
736 /* copyValueChain - will copy a chain of values */
737 /*------------------------------------------------------------------*/
739 copyValueChain (value * src)
746 dest = copyValue (src);
747 dest->next = copyValueChain (src->next);
752 /*------------------------------------------------------------------*/
753 /* copyValue - copies contents of a value to a fresh one */
754 /*------------------------------------------------------------------*/
756 copyValue (value * src)
761 dest->sym = copySymbol (src->sym);
762 strcpy (dest->name, src->name);
763 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
764 dest->etype = (src->type ? getSpec (dest->type) : NULL);
769 /*------------------------------------------------------------------*/
770 /* charVal - converts a character constant to a value */
771 /*------------------------------------------------------------------*/
780 val->type = val->etype = newLink ();
781 val->type->class = SPECIFIER;
782 SPEC_NOUN (val->type) = V_CHAR;
783 SPEC_USIGN(val->type) = 1;
784 SPEC_SCLS (val->type) = S_LITERAL;
786 s++; /* get rid of quotation */
787 /* if \ then special processing */
790 s++; /* go beyond the backslash */
794 SPEC_CVAL (val->type).v_int = '\n';
797 SPEC_CVAL (val->type).v_int = '\t';
800 SPEC_CVAL (val->type).v_int = '\v';
803 SPEC_CVAL (val->type).v_int = '\b';
806 SPEC_CVAL (val->type).v_int = '\r';
809 SPEC_CVAL (val->type).v_int = '\f';
812 SPEC_CVAL (val->type).v_int = '\a';
815 SPEC_CVAL (val->type).v_int = '\\';
818 SPEC_CVAL (val->type).v_int = '\?';
821 SPEC_CVAL (val->type).v_int = '\'';
824 SPEC_CVAL (val->type).v_int = '\"';
835 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
839 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
843 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
847 else /* not a backslash */
848 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
853 /*------------------------------------------------------------------*/
854 /* valFromType - creates a value from type given */
855 /*------------------------------------------------------------------*/
857 valFromType (sym_link * type)
859 value *val = newValue ();
860 val->type = copyLinkChain (type);
861 val->etype = getSpec (val->type);
865 /*------------------------------------------------------------------*/
866 /* floatFromVal - value to unsinged integer conversion */
867 /*------------------------------------------------------------------*/
869 floatFromVal (value * val)
874 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
876 werror (E_CONST_EXPECTED, val->name);
880 /* if it is not a specifier then we can assume that */
881 /* it will be an unsigned long */
882 if (!IS_SPEC (val->type))
883 return (double) SPEC_CVAL (val->etype).v_ulong;
885 if (SPEC_NOUN (val->etype) == V_FLOAT)
886 return (double) SPEC_CVAL (val->etype).v_float;
888 if (SPEC_LONG (val->etype))
890 if (SPEC_USIGN (val->etype))
891 return (double) SPEC_CVAL (val->etype).v_ulong;
893 return (double) SPEC_CVAL (val->etype).v_long;
896 if (SPEC_NOUN(val->etype)==V_INT) {
897 if (SPEC_USIGN (val->etype))
898 return (double) SPEC_CVAL (val->etype).v_uint;
900 return (double) SPEC_CVAL (val->etype).v_int;
901 } else { // SPEC_NOUN==V_CHAR
902 if (SPEC_USIGN (val->etype))
903 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
905 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
910 /*------------------------------------------------------------------*/
911 /* valUnaryPM - does the unary +/- operation on a constant */
912 /*------------------------------------------------------------------*/
914 valUnaryPM (value * val)
916 /* depending on type */
917 if (SPEC_NOUN (val->etype) == V_FLOAT)
918 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
921 if (SPEC_LONG (val->etype))
923 if (SPEC_USIGN (val->etype))
924 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
926 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
930 if (SPEC_USIGN (val->etype))
931 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
933 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
934 if (SPEC_NOUN (val->etype)==V_CHAR) {
935 SPEC_CVAL (val->etype).v_uint &= 0xff;
939 // -(unsigned 3) now really is signed
940 SPEC_USIGN(val->etype)=0;
944 /*------------------------------------------------------------------*/
945 /* valueComplement - complements a constant */
946 /*------------------------------------------------------------------*/
948 valComplement (value * val)
950 /* depending on type */
951 if (SPEC_LONG (val->etype))
953 if (SPEC_USIGN (val->etype))
954 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
956 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
960 if (SPEC_USIGN (val->etype))
961 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
963 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
964 if (SPEC_NOUN (val->etype)==V_CHAR) {
965 SPEC_CVAL (val->etype).v_uint &= 0xff;
971 /*------------------------------------------------------------------*/
972 /* valueNot - complements a constant */
973 /*------------------------------------------------------------------*/
977 /* depending on type */
978 if (SPEC_LONG (val->etype))
980 if (SPEC_USIGN (val->etype))
981 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
983 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
987 if (SPEC_USIGN (val->etype))
988 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
990 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
991 if (SPEC_NOUN (val->etype)==V_CHAR) {
992 SPEC_CVAL (val->etype).v_uint &= 0xff;
998 /*------------------------------------------------------------------*/
999 /* valMult - multiply constants */
1000 /*------------------------------------------------------------------*/
1002 valMult (value * lval, value * rval)
1006 /* create a new value */
1008 val->type = val->etype = newLink ();
1009 val->type->class = SPECIFIER;
1010 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1011 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1012 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1013 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1014 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1016 if (IS_FLOAT (val->type))
1017 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1020 if (SPEC_LONG (val->type))
1022 if (SPEC_USIGN (val->type))
1023 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1024 (unsigned long) floatFromVal (rval);
1026 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1027 (long) floatFromVal (rval);
1031 if (SPEC_USIGN (val->type))
1032 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1033 (unsigned) floatFromVal (rval);
1035 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1036 (int) floatFromVal (rval);
1039 return cheapestVal(val);
1042 /*------------------------------------------------------------------*/
1043 /* valDiv - Divide constants */
1044 /*------------------------------------------------------------------*/
1046 valDiv (value * lval, value * rval)
1050 if (floatFromVal (rval) == 0)
1052 werror (E_DIVIDE_BY_ZERO);
1056 /* create a new value */
1058 val->type = val->etype = newLink();
1059 val->type->class = SPECIFIER;
1060 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1061 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1062 SPEC_SCLS (val->etype) = S_LITERAL;
1063 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1064 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1066 if (IS_FLOAT (val->type))
1067 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1070 if (SPEC_LONG (val->type))
1072 if (SPEC_USIGN (val->type))
1073 SPEC_CVAL (val->type).v_ulong =
1074 (unsigned long) floatFromVal (lval) /
1075 (unsigned long) floatFromVal (rval);
1077 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1078 (long) floatFromVal (rval);
1082 if (SPEC_USIGN (val->type)) {
1083 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1084 (unsigned) floatFromVal (rval);
1086 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1087 (int) floatFromVal (rval);
1091 return cheapestVal(val);
1094 /*------------------------------------------------------------------*/
1095 /* valMod - Modulus constants */
1096 /*------------------------------------------------------------------*/
1098 valMod (value * lval, value * rval)
1102 /* create a new value */
1104 val->type = val->etype = newLink ();
1105 val->type->class = SPECIFIER;
1106 SPEC_NOUN (val->type) = V_INT; /* type is int */
1107 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1108 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1109 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1111 if (SPEC_LONG (val->type))
1113 if (SPEC_USIGN (val->type))
1114 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1115 (unsigned long) floatFromVal (rval);
1117 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1118 (unsigned long) floatFromVal (rval);
1122 if (SPEC_USIGN (val->type)) {
1123 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1124 (unsigned) floatFromVal (rval);
1126 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1127 (unsigned) floatFromVal (rval);
1131 return cheapestVal(val);
1134 /*------------------------------------------------------------------*/
1135 /* valPlus - Addition constants */
1136 /*------------------------------------------------------------------*/
1138 valPlus (value * lval, value * rval)
1142 /* create a new value */
1144 val->type = val->etype = newLink ();
1145 val->type->class = SPECIFIER;
1146 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1147 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1148 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1149 SPEC_USIGN (val->type) =
1150 SPEC_USIGN (lval->etype) &&
1151 SPEC_USIGN (rval->etype) &&
1152 (floatFromVal(lval)+floatFromVal(rval))>=0;
1154 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1156 if (IS_FLOAT (val->type))
1157 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1160 if (SPEC_LONG (val->type))
1162 if (SPEC_USIGN (val->type))
1163 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1164 (unsigned long) floatFromVal (rval);
1166 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1167 (long) floatFromVal (rval);
1171 if (SPEC_USIGN (val->type)) {
1172 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1173 (unsigned) floatFromVal (rval);
1175 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1176 (int) floatFromVal (rval);
1180 return cheapestVal(val);
1183 /*------------------------------------------------------------------*/
1184 /* valMinus - Addition constants */
1185 /*------------------------------------------------------------------*/
1187 valMinus (value * lval, value * rval)
1191 /* create a new value */
1193 val->type = val->etype = newLink ();
1194 val->type->class = SPECIFIER;
1195 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1196 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1197 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1198 SPEC_USIGN (val->type) =
1199 SPEC_USIGN (lval->etype) &&
1200 SPEC_USIGN (rval->etype) &&
1201 (floatFromVal(lval)-floatFromVal(rval))>=0;
1203 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1205 if (IS_FLOAT (val->type))
1206 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1209 if (SPEC_LONG (val->type))
1211 if (SPEC_USIGN (val->type)) {
1212 SPEC_CVAL (val->type).v_ulong =
1213 (unsigned long) floatFromVal (lval) -
1214 (unsigned long) floatFromVal (rval);
1216 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1217 (long) floatFromVal (rval);
1222 if (SPEC_USIGN (val->type)) {
1223 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1224 (unsigned) floatFromVal (rval);
1226 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1227 (int) floatFromVal (rval);
1231 return cheapestVal(val);
1234 /*------------------------------------------------------------------*/
1235 /* valShift - Shift left or right */
1236 /*------------------------------------------------------------------*/
1238 valShift (value * lval, value * rval, int lr)
1242 /* create a new value */
1244 val->type = val->etype = newIntLink ();
1245 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1246 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1247 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1249 if (SPEC_LONG (val->type))
1251 if (SPEC_USIGN (val->type))
1252 SPEC_CVAL (val->type).v_ulong = lr ?
1253 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1254 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1256 SPEC_CVAL (val->type).v_long = lr ?
1257 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1258 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1262 if (SPEC_USIGN (val->type)) {
1263 SPEC_CVAL (val->type).v_uint = lr ?
1264 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1265 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1267 SPEC_CVAL (val->type).v_int = lr ?
1268 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1269 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1273 return cheapestVal(val);
1276 /*------------------------------------------------------------------*/
1277 /* valCompare- Compares two literal */
1278 /*------------------------------------------------------------------*/
1280 valCompare (value * lval, value * rval, int ctype)
1284 /* create a new value */
1286 val->type = val->etype = newCharLink ();
1287 val->type->class = SPECIFIER;
1288 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1289 SPEC_USIGN (val->type) = 1;
1290 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1295 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1299 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1303 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1307 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1311 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1315 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1323 /*------------------------------------------------------------------*/
1324 /* valBitwise - Bitwise operation */
1325 /*------------------------------------------------------------------*/
1327 valBitwise (value * lval, value * rval, int op)
1331 /* create a new value */
1333 val->type = copyLinkChain (lval->type);
1334 val->etype = getSpec (val->type);
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 = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1359 if (SPEC_LONG (val->type))
1361 if (SPEC_USIGN (val->type))
1362 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1363 (unsigned long) floatFromVal (rval);
1365 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1366 (long) floatFromVal (rval);
1370 if (SPEC_USIGN (val->type))
1371 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1372 (unsigned) floatFromVal (rval);
1374 SPEC_CVAL (val->type).v_int =
1375 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1381 if (SPEC_LONG (val->type))
1383 if (SPEC_USIGN (val->type))
1384 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1385 (unsigned long) floatFromVal (rval);
1387 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1388 (long) floatFromVal (rval);
1392 if (SPEC_USIGN (val->type))
1393 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1394 (unsigned) floatFromVal (rval);
1396 SPEC_CVAL (val->type).v_int =
1397 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1402 return cheapestVal(val);
1405 /*------------------------------------------------------------------*/
1406 /* valAndOr - Generates code for and / or operation */
1407 /*------------------------------------------------------------------*/
1409 valLogicAndOr (value * lval, value * rval, int op)
1413 /* create a new value */
1415 val->type = val->etype = newCharLink ();
1416 val->type->class = SPECIFIER;
1417 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1418 SPEC_USIGN (val->type) = 0;
1423 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1427 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1435 /*------------------------------------------------------------------*/
1436 /* valCastLiteral - casts a literal value to another type */
1437 /*------------------------------------------------------------------*/
1439 valCastLiteral (sym_link * dtype, double fval)
1447 val->etype = getSpec (val->type = copyLinkChain (dtype));
1448 SPEC_SCLS (val->etype) = S_LITERAL;
1449 /* if it is not a specifier then we can assume that */
1450 /* it will be an unsigned long */
1451 if (!IS_SPEC (val->type))
1453 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1457 if (SPEC_NOUN (val->etype) == V_FLOAT)
1458 SPEC_CVAL (val->etype).v_float = fval;
1461 if (SPEC_LONG (val->etype))
1463 if (SPEC_USIGN (val->etype))
1464 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1466 SPEC_CVAL (val->etype).v_long = (long) fval;
1470 if (SPEC_USIGN (val->etype))
1471 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1473 SPEC_CVAL (val->etype).v_int = (short)fval;
1474 if (SPEC_NOUN (val->etype)==V_CHAR) {
1475 SPEC_CVAL (val->etype).v_uint &= 0xff;
1482 /*------------------------------------------------------------------*/
1483 /* getNelements - determines # of elements from init list */
1484 /*------------------------------------------------------------------*/
1486 getNelements (sym_link * type, initList * ilist)
1488 sym_link *etype = getSpec (type);
1494 if (ilist->type == INIT_DEEP)
1495 ilist = ilist->init.deep;
1497 /* if type is a character array and there is only one
1498 (string) initialiser then get the length of the string */
1499 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1501 ast *iast = ilist->init.node;
1502 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1505 werror (W_INIT_WRONG);
1509 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1510 // yep, it's a string
1512 return DCL_ELEM (v->type);
1520 ilist = ilist->next;
1526 /*-----------------------------------------------------------------*/
1527 /* valForArray - returns a value with name of array index */
1528 /*-----------------------------------------------------------------*/
1530 valForArray (ast * arrExpr)
1532 value *val, *lval = NULL;
1534 int size = getSize (arrExpr->left->ftype->next);
1535 /* if the right or left is an array
1537 if (IS_AST_OP (arrExpr->left))
1539 if (arrExpr->left->opval.op == '[')
1540 lval = valForArray (arrExpr->left);
1541 else if (arrExpr->left->opval.op == '.')
1542 lval = valForStructElem (arrExpr->left->left,
1543 arrExpr->left->right);
1544 else if (arrExpr->left->opval.op == PTR_OP &&
1545 IS_ADDRESS_OF_OP (arrExpr->left->left))
1546 lval = valForStructElem (arrExpr->left->left->left,
1547 arrExpr->left->right);
1552 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1555 if (!IS_AST_LIT_VALUE (arrExpr->right))
1560 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1562 sprintf (buffer, "%s", lval->name);
1564 sprintf (val->name, "(%s + %d)", buffer,
1565 (int) AST_LIT_VALUE (arrExpr->right) * size);
1567 val->type = newLink ();
1568 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1570 DCL_TYPE (val->type) = CPOINTER;
1571 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1573 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1574 DCL_TYPE (val->type) = FPOINTER;
1575 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1576 DCL_TYPE (val->type) = PPOINTER;
1577 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1578 DCL_TYPE (val->type) = IPOINTER;
1579 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1580 DCL_TYPE (val->type) = EEPPOINTER;
1582 DCL_TYPE (val->type) = POINTER;
1583 val->type->next = arrExpr->left->ftype;
1584 val->etype = getSpec (val->type);
1588 /*-----------------------------------------------------------------*/
1589 /* valForStructElem - returns value with name of struct element */
1590 /*-----------------------------------------------------------------*/
1592 valForStructElem (ast * structT, ast * elemT)
1594 value *val, *lval = NULL;
1598 /* left could be furthur derefed */
1599 if (IS_AST_OP (structT))
1601 if (structT->opval.op == '[')
1602 lval = valForArray (structT);
1603 else if (structT->opval.op == '.')
1604 lval = valForStructElem (structT->left, structT->right);
1605 else if (structT->opval.op == PTR_OP &&
1606 IS_ADDRESS_OF_OP (structT->left))
1607 lval = valForStructElem (structT->left->left,
1613 if (!IS_AST_SYM_VALUE (elemT))
1616 if (!IS_STRUCT (structT->etype))
1619 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1620 AST_SYMBOL (elemT))) == NULL)
1627 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1629 sprintf (buffer, "%s", lval->name);
1631 sprintf (val->name, "(%s + %d)", buffer,
1634 val->type = newLink ();
1635 if (SPEC_SCLS (structT->etype) == S_CODE)
1637 DCL_TYPE (val->type) = CPOINTER;
1638 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1640 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1641 DCL_TYPE (val->type) = FPOINTER;
1642 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1643 DCL_TYPE (val->type) = PPOINTER;
1644 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1645 DCL_TYPE (val->type) = IPOINTER;
1646 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1647 DCL_TYPE (val->type) = EEPPOINTER;
1649 DCL_TYPE (val->type) = POINTER;
1650 val->type->next = sym->type;
1651 val->etype = getSpec (val->type);
1655 /*-----------------------------------------------------------------*/
1656 /* valForCastAggr - will return value for a cast of an aggregate */
1657 /* plus minus a constant */
1658 /*-----------------------------------------------------------------*/
1660 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1664 if (!IS_AST_SYM_VALUE (aexpr))
1666 if (!IS_AST_LIT_VALUE (cnst))
1671 sprintf (val->name, "(%s %c %d)",
1672 AST_SYMBOL (aexpr)->rname, op,
1673 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1676 val->etype = getSpec (val->type);
1680 /*-----------------------------------------------------------------*/
1681 /* valForCastAggr - will return value for a cast of an aggregate */
1682 /* with no constant */
1683 /*-----------------------------------------------------------------*/
1685 valForCastArr (ast * aexpr, sym_link * type)
1689 if (!IS_AST_SYM_VALUE (aexpr))
1694 sprintf (val->name, "(%s)",
1695 AST_SYMBOL (aexpr)->rname);
1698 val->etype = getSpec (val->type);