1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_alloc (sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->lineno = yylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_alloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_alloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
307 sprintf (val->name, "%s", sym->rname);
309 sprintf (val->name, "_%s", sym->name);
315 /*--------------------------------------------------------------------*/
316 /* cheapestVal - convert a val to the cheapest as possible value */
317 /*--------------------------------------------------------------------*/
318 value *cheapestVal (value *val) {
320 unsigned long uval=0;
322 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
325 if (SPEC_LONG(val->type)) {
326 if (SPEC_USIGN(val->type)) {
327 uval=SPEC_CVAL(val->type).v_ulong;
329 sval=SPEC_CVAL(val->type).v_long;
332 if (SPEC_USIGN(val->type)) {
333 uval=SPEC_CVAL(val->type).v_uint;
335 sval=SPEC_CVAL(val->type).v_int;
339 if (SPEC_USIGN(val->type)) {
341 SPEC_LONG(val->type)=0;
342 SPEC_CVAL(val->type).v_uint = uval;
345 SPEC_NOUN(val->type)=V_CHAR;
347 } else { // not unsigned
350 SPEC_LONG(val->type)=0;
351 SPEC_CVAL(val->type).v_int = sval & 0xffff;
354 SPEC_NOUN(val->type)=V_CHAR;
355 SPEC_CVAL(val->type).v_int &= 0xff;
358 SPEC_USIGN(val->type)=1;
360 SPEC_LONG(val->type)=0;
361 SPEC_CVAL(val->type).v_int = sval;
364 SPEC_NOUN(val->type)=V_CHAR;
371 /*-----------------------------------------------------------------*/
372 /* valueFromLit - creates a value from a literal */
373 /*-----------------------------------------------------------------*/
375 valueFromLit (double lit)
379 if ((((long) lit) - lit) == 0)
381 sprintf (buffer, "%ld", (long) lit);
382 return constVal (buffer);
385 sprintf (buffer, "%f", lit);
386 return constFloatVal (buffer);
389 /*-----------------------------------------------------------------*/
390 /* constFloatVal - converts a FLOAT constant to value */
391 /*-----------------------------------------------------------------*/
393 constFloatVal (char *s)
395 value *val = newValue ();
398 if (sscanf (s, "%lf", &sval) != 1)
400 werror (E_INVALID_FLOAT_CONST, s);
401 return constVal ("0");
404 val->type = val->etype = newLink ();
405 val->type->class = SPECIFIER;
406 SPEC_NOUN (val->type) = V_FLOAT;
407 SPEC_SCLS (val->type) = S_LITERAL;
408 SPEC_CVAL (val->type).v_float = sval;
413 /*-----------------------------------------------------------------*/
414 /* constVal - converts an INTEGER constant into a cheapest value */
415 /*-----------------------------------------------------------------*/
416 value *constVal (char *s)
419 short hex = 0, octal = 0;
424 val = newValue (); /* alloc space for value */
426 val->type = val->etype = newLink (); /* create the spcifier */
427 val->type->class = SPECIFIER;
428 SPEC_SCLS (val->type) = S_LITERAL;
429 // let's start with an unsigned char
430 SPEC_NOUN (val->type) = V_CHAR;
431 SPEC_USIGN (val->type) = 1;
433 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
435 /* set the octal flag */
436 if (!hex && *s == '0' && *(s + 1))
439 /* create the scan string */
440 scanFmt[scI++] = '%';
442 scanFmt[scI++] = 'l';
445 scanFmt[scI++] = 'o';
447 scanFmt[scI++] = 'x';
449 scanFmt[scI++] = 'f';
451 scanFmt[scI++] = '\0';
455 sscanf (s, scanFmt, &sval);
458 sscanf (s, scanFmt, &dval);
461 /* Setup the flags first */
462 /* set the _long flag if 'lL' is found */
463 if (strchr (s, 'l') || strchr (s, 'L')) {
464 SPEC_NOUN (val->type) = V_INT;
465 SPEC_LONG (val->type) = 1;
468 if (dval<0) { // "-28u" will still be signed and negative
469 SPEC_USIGN (val->type) = 0;
470 if (dval<-128) { // check if we have to promote to int
471 SPEC_NOUN (val->type) = V_INT;
473 if (dval<-32768) { // check if we have to promote to long int
474 SPEC_LONG (val->type) = 1;
477 if (dval>0xff) { // check if we have to promote to int
478 SPEC_NOUN (val->type) = V_INT;
480 if (dval>0xffff) { // check if we have to promote to long int
481 SPEC_LONG (val->type) = 1;
485 if (SPEC_LONG (val->type))
487 if (SPEC_USIGN (val->type))
489 SPEC_CVAL (val->type).v_ulong = dval;
493 SPEC_CVAL (val->type).v_long = dval;
498 if (SPEC_USIGN (val->type))
500 SPEC_CVAL (val->type).v_uint = dval;
504 SPEC_CVAL (val->type).v_int = dval;
511 /*! /fn char hexEscape(char **src)
513 /param src Pointer to 'x' from start of hex character value
516 unsigned char hexEscape(char **src)
519 unsigned long value ;
521 (*src)++ ; /* Skip over the 'x' */
522 s = *src ; /* Save for error detection */
524 value = strtol (*src, src, 16);
527 // no valid hex found
528 werror(E_INVALID_HEX);
531 werror(W_ESC_SEQ_OOR_FOR_CHAR);
537 /*------------------------------------------------------------------*/
538 /* octalEscape - process an octal constant of max three digits */
539 /* return the octal value, throw a warning for illegal octal */
540 /* adjust src to point at the last proccesed char */
541 /*------------------------------------------------------------------*/
543 unsigned char octalEscape (char **str) {
547 for (digits=0; digits<3; digits++) {
548 if (**str>='0' && **str<='7') {
549 value = value*8 + (**str-'0');
556 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
557 werror (W_ESC_SEQ_OOR_FOR_CHAR);
564 /fn int copyStr (char *dest, char *src)
566 Copies a source string to a dest buffer interpreting escape sequences
567 and special characters
569 /param dest Buffer to receive the resultant string
570 /param src Buffer containing the source string with escape sequecnes
571 /return Number of characters in output string
576 copyStr (char *dest, char *src)
579 char *OriginalDest = dest ;
585 else if (*src == '\\')
620 *dest++ = octalEscape(&src);
625 *dest++ = hexEscape(&src) ;
652 return dest - OriginalDest ;
655 /*------------------------------------------------------------------*/
656 /* strVal - converts a string constant to a value */
657 /*------------------------------------------------------------------*/
663 val = newValue (); /* get a new one */
665 /* get a declarator */
666 val->type = newLink ();
667 DCL_TYPE (val->type) = ARRAY;
668 val->type->next = val->etype = newLink ();
669 val->etype->class = SPECIFIER;
670 SPEC_NOUN (val->etype) = V_CHAR;
671 SPEC_SCLS (val->etype) = S_LITERAL;
673 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
674 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
680 /*------------------------------------------------------------------*/
681 /* reverseValWithType - reverses value chain with type & etype */
682 /*------------------------------------------------------------------*/
684 reverseValWithType (value * val)
692 /* save the type * etype chains */
696 /* set the current one 2b null */
697 val->type = val->etype = NULL;
698 val = reverseVal (val);
700 /* restore type & etype */
707 /*------------------------------------------------------------------*/
708 /* reverseVal - reverses the values for a value chain */
709 /*------------------------------------------------------------------*/
711 reverseVal (value * val)
713 value *prev, *curr, *next;
728 val->next = (void *) NULL;
732 /*------------------------------------------------------------------*/
733 /* copyValueChain - will copy a chain of values */
734 /*------------------------------------------------------------------*/
736 copyValueChain (value * src)
743 dest = copyValue (src);
744 dest->next = copyValueChain (src->next);
749 /*------------------------------------------------------------------*/
750 /* copyValue - copies contents of a value to a fresh one */
751 /*------------------------------------------------------------------*/
753 copyValue (value * src)
758 dest->sym = copySymbol (src->sym);
759 strcpy (dest->name, src->name);
760 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
761 dest->etype = (src->type ? getSpec (dest->type) : NULL);
766 /*------------------------------------------------------------------*/
767 /* charVal - converts a character constant to a value */
768 /*------------------------------------------------------------------*/
777 val->type = val->etype = newLink ();
778 val->type->class = SPECIFIER;
779 SPEC_NOUN (val->type) = V_CHAR;
780 SPEC_USIGN(val->type) = 1;
781 SPEC_SCLS (val->type) = S_LITERAL;
783 s++; /* get rid of quotation */
784 /* if \ then special processing */
787 s++; /* go beyond the backslash */
791 SPEC_CVAL (val->type).v_int = '\n';
794 SPEC_CVAL (val->type).v_int = '\t';
797 SPEC_CVAL (val->type).v_int = '\v';
800 SPEC_CVAL (val->type).v_int = '\b';
803 SPEC_CVAL (val->type).v_int = '\r';
806 SPEC_CVAL (val->type).v_int = '\f';
809 SPEC_CVAL (val->type).v_int = '\a';
812 SPEC_CVAL (val->type).v_int = '\\';
815 SPEC_CVAL (val->type).v_int = '\?';
818 SPEC_CVAL (val->type).v_int = '\'';
821 SPEC_CVAL (val->type).v_int = '\"';
832 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
836 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
840 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
844 else /* not a backslash */
845 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
850 /*------------------------------------------------------------------*/
851 /* valFromType - creates a value from type given */
852 /*------------------------------------------------------------------*/
854 valFromType (sym_link * type)
856 value *val = newValue ();
857 val->type = copyLinkChain (type);
858 val->etype = getSpec (val->type);
862 /*------------------------------------------------------------------*/
863 /* floatFromVal - value to unsinged integer conversion */
864 /*------------------------------------------------------------------*/
866 floatFromVal (value * val)
871 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
873 werror (E_CONST_EXPECTED, val->name);
877 /* if it is not a specifier then we can assume that */
878 /* it will be an unsigned long */
879 if (!IS_SPEC (val->type))
880 return (double) SPEC_CVAL (val->etype).v_ulong;
882 if (SPEC_NOUN (val->etype) == V_FLOAT)
883 return (double) SPEC_CVAL (val->etype).v_float;
885 if (SPEC_LONG (val->etype))
887 if (SPEC_USIGN (val->etype))
888 return (double) SPEC_CVAL (val->etype).v_ulong;
890 return (double) SPEC_CVAL (val->etype).v_long;
893 if (SPEC_NOUN(val->etype)==V_INT) {
894 if (SPEC_USIGN (val->etype))
895 return (double) SPEC_CVAL (val->etype).v_uint;
897 return (double) SPEC_CVAL (val->etype).v_int;
898 } else { // SPEC_NOUN==V_CHAR
899 if (SPEC_USIGN (val->etype))
900 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
902 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
907 /*------------------------------------------------------------------*/
908 /* valUnaryPM - does the unary +/- operation on a constant */
909 /*------------------------------------------------------------------*/
911 valUnaryPM (value * val)
913 /* depending on type */
914 if (SPEC_NOUN (val->etype) == V_FLOAT)
915 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
918 if (SPEC_LONG (val->etype))
920 if (SPEC_USIGN (val->etype))
921 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
923 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
927 if (SPEC_USIGN (val->etype))
928 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
930 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
931 if (SPEC_NOUN (val->etype)==V_CHAR) {
932 SPEC_CVAL (val->etype).v_uint &= 0xff;
936 // -(unsigned 3) now really is signed
937 SPEC_USIGN(val->etype)=0;
941 /*------------------------------------------------------------------*/
942 /* valueComplement - complements a constant */
943 /*------------------------------------------------------------------*/
945 valComplement (value * val)
947 /* depending on type */
948 if (SPEC_LONG (val->etype))
950 if (SPEC_USIGN (val->etype))
951 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
953 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
957 if (SPEC_USIGN (val->etype))
958 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
960 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
961 if (SPEC_NOUN (val->etype)==V_CHAR) {
962 SPEC_CVAL (val->etype).v_uint &= 0xff;
968 /*------------------------------------------------------------------*/
969 /* valueNot - complements a constant */
970 /*------------------------------------------------------------------*/
974 /* depending on type */
975 if (SPEC_LONG (val->etype))
977 if (SPEC_USIGN (val->etype))
978 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
980 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
984 if (SPEC_USIGN (val->etype))
985 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
987 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
988 if (SPEC_NOUN (val->etype)==V_CHAR) {
989 SPEC_CVAL (val->etype).v_uint &= 0xff;
995 /*------------------------------------------------------------------*/
996 /* valMult - multiply constants */
997 /*------------------------------------------------------------------*/
999 valMult (value * lval, value * rval)
1003 /* create a new value */
1005 val->type = val->etype = newLink ();
1006 val->type->class = SPECIFIER;
1007 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1008 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1009 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1010 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1011 SPEC_LONG (val->type) = 1;
1013 if (IS_FLOAT (val->type))
1014 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1017 if (SPEC_LONG (val->type))
1019 if (SPEC_USIGN (val->type))
1020 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1021 (unsigned long) floatFromVal (rval);
1023 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1024 (long) floatFromVal (rval);
1027 return cheapestVal(val);
1030 /*------------------------------------------------------------------*/
1031 /* valDiv - Divide constants */
1032 /*------------------------------------------------------------------*/
1034 valDiv (value * lval, value * rval)
1038 if (floatFromVal (rval) == 0)
1040 werror (E_DIVIDE_BY_ZERO);
1044 /* create a new value */
1046 val->type = val->etype = newLink();
1047 val->type->class = SPECIFIER;
1048 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1049 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1050 SPEC_SCLS (val->etype) = S_LITERAL;
1051 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1052 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1054 if (IS_FLOAT (val->type))
1055 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1058 if (SPEC_LONG (val->type))
1060 if (SPEC_USIGN (val->type))
1061 SPEC_CVAL (val->type).v_ulong =
1062 (unsigned long) floatFromVal (lval) /
1063 (unsigned long) floatFromVal (rval);
1065 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1066 (long) floatFromVal (rval);
1070 if (SPEC_USIGN (val->type)) {
1071 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1072 (unsigned) floatFromVal (rval);
1074 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1075 (int) floatFromVal (rval);
1079 return cheapestVal(val);
1082 /*------------------------------------------------------------------*/
1083 /* valMod - Modulus constants */
1084 /*------------------------------------------------------------------*/
1086 valMod (value * lval, value * rval)
1090 /* create a new value */
1092 val->type = val->etype = newLink ();
1093 val->type->class = SPECIFIER;
1094 SPEC_NOUN (val->type) = V_INT; /* type is int */
1095 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1096 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1097 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1099 if (SPEC_LONG (val->type))
1101 if (SPEC_USIGN (val->type))
1102 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1103 (unsigned long) floatFromVal (rval);
1105 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1106 (unsigned long) floatFromVal (rval);
1110 if (SPEC_USIGN (val->type)) {
1111 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1112 (unsigned) floatFromVal (rval);
1114 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1115 (unsigned) floatFromVal (rval);
1119 return cheapestVal(val);
1122 /*------------------------------------------------------------------*/
1123 /* valPlus - Addition constants */
1124 /*------------------------------------------------------------------*/
1126 valPlus (value * lval, value * rval)
1130 /* create a new value */
1132 val->type = val->etype = newLink ();
1133 val->type->class = SPECIFIER;
1134 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1135 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1136 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1137 SPEC_USIGN (val->type) =
1138 SPEC_USIGN (lval->etype) &&
1139 SPEC_USIGN (rval->etype) &&
1140 (floatFromVal(lval)+floatFromVal(rval))>=0;
1142 SPEC_LONG (val->type) = 1;
1144 if (IS_FLOAT (val->type))
1145 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1148 if (SPEC_LONG (val->type))
1150 if (SPEC_USIGN (val->type))
1151 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1152 (unsigned long) floatFromVal (rval);
1154 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1155 (long) floatFromVal (rval);
1158 return cheapestVal(val);
1161 /*------------------------------------------------------------------*/
1162 /* valMinus - Addition constants */
1163 /*------------------------------------------------------------------*/
1165 valMinus (value * lval, value * rval)
1169 /* create a new value */
1171 val->type = val->etype = newLink ();
1172 val->type->class = SPECIFIER;
1173 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1174 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1175 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1176 SPEC_USIGN (val->type) =
1177 SPEC_USIGN (lval->etype) &&
1178 SPEC_USIGN (rval->etype) &&
1179 (floatFromVal(lval)-floatFromVal(rval))>=0;
1181 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1183 if (IS_FLOAT (val->type))
1184 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1187 if (SPEC_LONG (val->type))
1189 if (SPEC_USIGN (val->type)) {
1190 SPEC_CVAL (val->type).v_ulong =
1191 (unsigned long) floatFromVal (lval) -
1192 (unsigned long) floatFromVal (rval);
1194 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1195 (long) floatFromVal (rval);
1200 if (SPEC_USIGN (val->type)) {
1201 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1202 (unsigned) floatFromVal (rval);
1204 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1205 (int) floatFromVal (rval);
1209 return cheapestVal(val);
1212 /*------------------------------------------------------------------*/
1213 /* valShift - Shift left or right */
1214 /*------------------------------------------------------------------*/
1216 valShift (value * lval, value * rval, int lr)
1220 /* create a new value */
1222 val->type = val->etype = newIntLink ();
1223 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1224 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1225 SPEC_LONG (val->type) = 1;
1227 if (SPEC_LONG (val->type))
1229 if (SPEC_USIGN (val->type))
1230 SPEC_CVAL (val->type).v_ulong = lr ?
1231 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1232 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1234 SPEC_CVAL (val->type).v_long = lr ?
1235 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1236 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1239 return cheapestVal(val);
1242 /*------------------------------------------------------------------*/
1243 /* valCompare- Compares two literal */
1244 /*------------------------------------------------------------------*/
1246 valCompare (value * lval, value * rval, int ctype)
1250 /* create a new value */
1252 val->type = val->etype = newCharLink ();
1253 val->type->class = SPECIFIER;
1254 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1255 SPEC_USIGN (val->type) = 1;
1256 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1261 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1265 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1269 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1273 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1277 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1281 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1289 /*------------------------------------------------------------------*/
1290 /* valBitwise - Bitwise operation */
1291 /*------------------------------------------------------------------*/
1293 valBitwise (value * lval, value * rval, int op)
1297 /* create a new value */
1299 val->type = copyLinkChain (lval->type);
1300 val->etype = getSpec (val->type);
1305 if (SPEC_LONG (val->type))
1307 if (SPEC_USIGN (val->type))
1308 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1309 (unsigned long) floatFromVal (rval);
1311 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1312 (long) floatFromVal (rval);
1316 if (SPEC_USIGN (val->type))
1317 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1318 (unsigned) floatFromVal (rval);
1320 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1325 if (SPEC_LONG (val->type))
1327 if (SPEC_USIGN (val->type))
1328 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1329 (unsigned long) floatFromVal (rval);
1331 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1332 (long) floatFromVal (rval);
1336 if (SPEC_USIGN (val->type))
1337 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1338 (unsigned) floatFromVal (rval);
1340 SPEC_CVAL (val->type).v_int =
1341 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1347 if (SPEC_LONG (val->type))
1349 if (SPEC_USIGN (val->type))
1350 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1351 (unsigned long) floatFromVal (rval);
1353 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1354 (long) floatFromVal (rval);
1358 if (SPEC_USIGN (val->type))
1359 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1360 (unsigned) floatFromVal (rval);
1362 SPEC_CVAL (val->type).v_int =
1363 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1368 return cheapestVal(val);
1371 /*------------------------------------------------------------------*/
1372 /* valAndOr - Generates code for and / or operation */
1373 /*------------------------------------------------------------------*/
1375 valLogicAndOr (value * lval, value * rval, int op)
1379 /* create a new value */
1381 val->type = val->etype = newCharLink ();
1382 val->type->class = SPECIFIER;
1383 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1384 SPEC_USIGN (val->type) = 0;
1389 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1393 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1401 /*------------------------------------------------------------------*/
1402 /* valCastLiteral - casts a literal value to another type */
1403 /*------------------------------------------------------------------*/
1405 valCastLiteral (sym_link * dtype, double fval)
1413 val->etype = getSpec (val->type = copyLinkChain (dtype));
1414 SPEC_SCLS (val->etype) = S_LITERAL;
1415 /* if it is not a specifier then we can assume that */
1416 /* it will be an unsigned long */
1417 if (!IS_SPEC (val->type))
1419 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1423 if (SPEC_NOUN (val->etype) == V_FLOAT)
1424 SPEC_CVAL (val->etype).v_float = fval;
1427 if (SPEC_LONG (val->etype))
1429 if (SPEC_USIGN (val->etype))
1430 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1432 SPEC_CVAL (val->etype).v_long = (long) fval;
1436 if (SPEC_USIGN (val->etype))
1437 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1439 SPEC_CVAL (val->etype).v_int = (short)fval;
1440 if (SPEC_NOUN (val->etype)==V_CHAR) {
1441 SPEC_CVAL (val->etype).v_uint &= 0xff;
1448 /*------------------------------------------------------------------*/
1449 /* getNelements - determines # of elements from init list */
1450 /*------------------------------------------------------------------*/
1452 getNelements (sym_link * type, initList * ilist)
1454 sym_link *etype = getSpec (type);
1460 if (ilist->type == INIT_DEEP)
1461 ilist = ilist->init.deep;
1463 /* if type is a character array and there is only one
1464 (string) initialiser then get the length of the string */
1465 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1467 ast *iast = ilist->init.node;
1468 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1471 werror (W_INIT_WRONG);
1475 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1476 // yep, it's a string
1478 return DCL_ELEM (v->type);
1486 ilist = ilist->next;
1492 /*-----------------------------------------------------------------*/
1493 /* valForArray - returns a value with name of array index */
1494 /*-----------------------------------------------------------------*/
1496 valForArray (ast * arrExpr)
1498 value *val, *lval = NULL;
1500 int size = getSize (arrExpr->left->ftype->next);
1501 /* if the right or left is an array
1503 if (IS_AST_OP (arrExpr->left))
1505 if (arrExpr->left->opval.op == '[')
1506 lval = valForArray (arrExpr->left);
1507 else if (arrExpr->left->opval.op == '.')
1508 lval = valForStructElem (arrExpr->left->left,
1509 arrExpr->left->right);
1510 else if (arrExpr->left->opval.op == PTR_OP &&
1511 IS_ADDRESS_OF_OP (arrExpr->left->left))
1512 lval = valForStructElem (arrExpr->left->left->left,
1513 arrExpr->left->right);
1518 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1521 if (!IS_AST_LIT_VALUE (arrExpr->right))
1526 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1528 sprintf (buffer, "%s", lval->name);
1530 sprintf (val->name, "(%s + %d)", buffer,
1531 (int) AST_LIT_VALUE (arrExpr->right) * size);
1533 val->type = newLink ();
1534 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1536 DCL_TYPE (val->type) = CPOINTER;
1537 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1539 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1540 DCL_TYPE (val->type) = FPOINTER;
1541 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1542 DCL_TYPE (val->type) = PPOINTER;
1543 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1544 DCL_TYPE (val->type) = IPOINTER;
1545 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1546 DCL_TYPE (val->type) = EEPPOINTER;
1548 DCL_TYPE (val->type) = POINTER;
1549 val->type->next = arrExpr->left->ftype;
1550 val->etype = getSpec (val->type);
1554 /*-----------------------------------------------------------------*/
1555 /* valForStructElem - returns value with name of struct element */
1556 /*-----------------------------------------------------------------*/
1558 valForStructElem (ast * structT, ast * elemT)
1560 value *val, *lval = NULL;
1564 /* left could be furthur derefed */
1565 if (IS_AST_OP (structT))
1567 if (structT->opval.op == '[')
1568 lval = valForArray (structT);
1569 else if (structT->opval.op == '.')
1570 lval = valForStructElem (structT->left, structT->right);
1571 else if (structT->opval.op == PTR_OP &&
1572 IS_ADDRESS_OF_OP (structT->left))
1573 lval = valForStructElem (structT->left->left,
1579 if (!IS_AST_SYM_VALUE (elemT))
1582 if (!IS_STRUCT (structT->etype))
1585 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1586 AST_SYMBOL (elemT))) == NULL)
1593 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1595 sprintf (buffer, "%s", lval->name);
1597 sprintf (val->name, "(%s + %d)", buffer,
1600 val->type = newLink ();
1601 if (SPEC_SCLS (structT->etype) == S_CODE)
1603 DCL_TYPE (val->type) = CPOINTER;
1604 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1606 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1607 DCL_TYPE (val->type) = FPOINTER;
1608 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1609 DCL_TYPE (val->type) = PPOINTER;
1610 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1611 DCL_TYPE (val->type) = IPOINTER;
1612 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1613 DCL_TYPE (val->type) = EEPPOINTER;
1615 DCL_TYPE (val->type) = POINTER;
1616 val->type->next = sym->type;
1617 val->etype = getSpec (val->type);
1621 /*-----------------------------------------------------------------*/
1622 /* valForCastAggr - will return value for a cast of an aggregate */
1623 /* plus minus a constant */
1624 /*-----------------------------------------------------------------*/
1626 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1630 if (!IS_AST_SYM_VALUE (aexpr))
1632 if (!IS_AST_LIT_VALUE (cnst))
1637 sprintf (val->name, "(%s %c %d)",
1638 AST_SYMBOL (aexpr)->rname, op,
1639 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1642 val->etype = getSpec (val->type);
1646 /*-----------------------------------------------------------------*/
1647 /* valForCastAggr - will return value for a cast of an aggregate */
1648 /* with no constant */
1649 /*-----------------------------------------------------------------*/
1651 valForCastArr (ast * aexpr, sym_link * type)
1655 if (!IS_AST_SYM_VALUE (aexpr))
1660 sprintf (val->name, "(%s)",
1661 AST_SYMBOL (aexpr)->rname);
1664 val->etype = getSpec (val->type);