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;
344 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;
353 SPEC_NOUN(val->type)=V_CHAR;
354 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;
363 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 double float 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_USIGN (val->etype))
894 return (double) SPEC_CVAL (val->etype).v_uint;
896 return (double) SPEC_CVAL (val->etype).v_int;
900 /*------------------------------------------------------------------*/
901 /* valUnaryPM - does the unary +/- operation on a constant */
902 /*------------------------------------------------------------------*/
904 valUnaryPM (value * val)
906 /* depending on type */
907 if (SPEC_NOUN (val->etype) == V_FLOAT)
908 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
911 if (SPEC_LONG (val->etype))
913 if (SPEC_USIGN (val->etype))
914 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
916 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
920 if (SPEC_USIGN (val->etype))
921 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
923 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
926 // -(unsigned 3) now really is signed
927 SPEC_USIGN(val->etype)=0;
931 /*------------------------------------------------------------------*/
932 /* valueComplement - complements a constant */
933 /*------------------------------------------------------------------*/
935 valComplement (value * val)
937 /* depending on type */
938 if (SPEC_LONG (val->etype))
940 if (SPEC_USIGN (val->etype))
941 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
943 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
947 if (SPEC_USIGN (val->etype))
948 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
950 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
951 if (SPEC_NOUN (val->etype)==V_CHAR) {
952 SPEC_CVAL (val->etype).v_uint &= 0xff;
958 /*------------------------------------------------------------------*/
959 /* valueNot - complements a constant */
960 /*------------------------------------------------------------------*/
964 /* depending on type */
965 if (SPEC_LONG (val->etype))
967 if (SPEC_USIGN (val->etype))
968 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
970 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
974 if (SPEC_USIGN (val->etype))
975 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
977 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
978 if (SPEC_NOUN (val->etype)==V_CHAR) {
979 SPEC_CVAL (val->etype).v_uint &= 0xff;
985 /*------------------------------------------------------------------*/
986 /* valMult - multiply constants */
987 /*------------------------------------------------------------------*/
989 valMult (value * lval, value * rval)
993 /* create a new value */
995 val->type = val->etype = newLink ();
996 val->type->class = SPECIFIER;
997 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
998 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
999 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1000 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1001 SPEC_LONG (val->type) = 1;
1003 if (IS_FLOAT (val->type))
1004 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1007 if (SPEC_LONG (val->type))
1009 if (SPEC_USIGN (val->type))
1010 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1011 (unsigned long) floatFromVal (rval);
1013 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1014 (long) floatFromVal (rval);
1017 return cheapestVal(val);
1020 /*------------------------------------------------------------------*/
1021 /* valDiv - Divide constants */
1022 /*------------------------------------------------------------------*/
1024 valDiv (value * lval, value * rval)
1028 if (floatFromVal (rval) == 0)
1030 werror (E_DIVIDE_BY_ZERO);
1034 /* create a new value */
1036 val->type = val->etype = newLink();
1037 val->type->class = SPECIFIER;
1038 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1039 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1040 SPEC_SCLS (val->etype) = S_LITERAL;
1041 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1042 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1044 if (IS_FLOAT (val->type))
1045 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1048 if (SPEC_LONG (val->type))
1050 if (SPEC_USIGN (val->type))
1051 SPEC_CVAL (val->type).v_ulong =
1052 (unsigned long) floatFromVal (lval) /
1053 (unsigned long) floatFromVal (rval);
1055 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1056 (long) floatFromVal (rval);
1060 if (SPEC_USIGN (val->type)) {
1061 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1062 (unsigned) floatFromVal (rval);
1064 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1065 (int) floatFromVal (rval);
1069 return cheapestVal(val);
1072 /*------------------------------------------------------------------*/
1073 /* valMod - Modulus constants */
1074 /*------------------------------------------------------------------*/
1076 valMod (value * lval, value * rval)
1080 /* create a new value */
1082 val->type = val->etype = newLink ();
1083 val->type->class = SPECIFIER;
1084 SPEC_NOUN (val->type) = V_INT; /* type is int */
1085 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1086 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1087 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1089 if (SPEC_LONG (val->type))
1091 if (SPEC_USIGN (val->type))
1092 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1093 (unsigned long) floatFromVal (rval);
1095 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1096 (unsigned long) floatFromVal (rval);
1100 if (SPEC_USIGN (val->type)) {
1101 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1102 (unsigned) floatFromVal (rval);
1104 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1105 (unsigned) floatFromVal (rval);
1109 return cheapestVal(val);
1112 /*------------------------------------------------------------------*/
1113 /* valPlus - Addition constants */
1114 /*------------------------------------------------------------------*/
1116 valPlus (value * lval, value * rval)
1120 /* create a new value */
1122 val->type = val->etype = newLink ();
1123 val->type->class = SPECIFIER;
1124 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1125 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1126 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1127 SPEC_USIGN (val->type) =
1128 SPEC_USIGN (lval->etype) &&
1129 SPEC_USIGN (rval->etype) &&
1130 (floatFromVal(lval)+floatFromVal(rval))>=0;
1132 SPEC_LONG (val->type) = 1;
1134 if (IS_FLOAT (val->type))
1135 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1138 if (SPEC_LONG (val->type))
1140 if (SPEC_USIGN (val->type))
1141 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1142 (unsigned long) floatFromVal (rval);
1144 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1145 (long) floatFromVal (rval);
1148 return cheapestVal(val);
1151 /*------------------------------------------------------------------*/
1152 /* valMinus - Addition constants */
1153 /*------------------------------------------------------------------*/
1155 valMinus (value * lval, value * rval)
1159 /* create a new value */
1161 val->type = val->etype = newLink ();
1162 val->type->class = SPECIFIER;
1163 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1164 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1165 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1166 SPEC_USIGN (val->type) =
1167 SPEC_USIGN (lval->etype) &&
1168 SPEC_USIGN (rval->etype) &&
1169 (floatFromVal(lval)-floatFromVal(rval))>=0;
1171 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1173 if (IS_FLOAT (val->type))
1174 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1177 if (SPEC_LONG (val->type))
1179 if (SPEC_USIGN (val->type)) {
1180 SPEC_CVAL (val->type).v_ulong =
1181 (unsigned long) floatFromVal (lval) -
1182 (unsigned long) floatFromVal (rval);
1184 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1185 (long) floatFromVal (rval);
1190 if (SPEC_USIGN (val->type)) {
1191 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1192 (unsigned) floatFromVal (rval);
1194 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1195 (int) floatFromVal (rval);
1199 return cheapestVal(val);
1202 /*------------------------------------------------------------------*/
1203 /* valShift - Shift left or right */
1204 /*------------------------------------------------------------------*/
1206 valShift (value * lval, value * rval, int lr)
1210 /* create a new value */
1212 val->type = val->etype = newIntLink ();
1213 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1214 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1215 SPEC_LONG (val->type) = 1;
1217 if (SPEC_LONG (val->type))
1219 if (SPEC_USIGN (val->type))
1220 SPEC_CVAL (val->type).v_ulong = lr ?
1221 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1222 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1224 SPEC_CVAL (val->type).v_long = lr ?
1225 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1226 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1229 return cheapestVal(val);
1232 /*------------------------------------------------------------------*/
1233 /* valCompare- Compares two literal */
1234 /*------------------------------------------------------------------*/
1236 valCompare (value * lval, value * rval, int ctype)
1240 /* create a new value */
1242 val->type = val->etype = newCharLink ();
1243 val->type->class = SPECIFIER;
1244 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1245 SPEC_USIGN (val->type) = 1;
1246 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1251 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1255 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1259 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1263 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1267 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1271 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1279 /*------------------------------------------------------------------*/
1280 /* valBitwise - Bitwise operation */
1281 /*------------------------------------------------------------------*/
1283 valBitwise (value * lval, value * rval, int op)
1287 /* create a new value */
1289 val->type = copyLinkChain (lval->type);
1290 val->etype = getSpec (val->type);
1295 if (SPEC_LONG (val->type))
1297 if (SPEC_USIGN (val->type))
1298 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1299 (unsigned long) floatFromVal (rval);
1301 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1302 (long) floatFromVal (rval);
1306 if (SPEC_USIGN (val->type))
1307 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1308 (unsigned) floatFromVal (rval);
1310 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1315 if (SPEC_LONG (val->type))
1317 if (SPEC_USIGN (val->type))
1318 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1319 (unsigned long) floatFromVal (rval);
1321 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1322 (long) floatFromVal (rval);
1326 if (SPEC_USIGN (val->type))
1327 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1328 (unsigned) floatFromVal (rval);
1330 SPEC_CVAL (val->type).v_int =
1331 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1337 if (SPEC_LONG (val->type))
1339 if (SPEC_USIGN (val->type))
1340 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1341 (unsigned long) floatFromVal (rval);
1343 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1344 (long) floatFromVal (rval);
1348 if (SPEC_USIGN (val->type))
1349 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1350 (unsigned) floatFromVal (rval);
1352 SPEC_CVAL (val->type).v_int =
1353 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1358 return cheapestVal(val);
1361 /*------------------------------------------------------------------*/
1362 /* valAndOr - Generates code for and / or operation */
1363 /*------------------------------------------------------------------*/
1365 valLogicAndOr (value * lval, value * rval, int op)
1369 /* create a new value */
1371 val->type = val->etype = newCharLink ();
1372 val->type->class = SPECIFIER;
1373 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1374 SPEC_USIGN (val->type) = 0;
1379 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1383 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1391 /*------------------------------------------------------------------*/
1392 /* valCastLiteral - casts a literal value to another type */
1393 /*------------------------------------------------------------------*/
1395 valCastLiteral (sym_link * dtype, double fval)
1403 val->etype = getSpec (val->type = copyLinkChain (dtype));
1404 SPEC_SCLS (val->etype) = S_LITERAL;
1405 /* if it is not a specifier then we can assume that */
1406 /* it will be an unsigned long */
1407 if (!IS_SPEC (val->type)) {
1408 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1412 if (SPEC_NOUN (val->etype) == V_FLOAT)
1413 SPEC_CVAL (val->etype).v_float = fval;
1415 unsigned long l = fval;
1416 if (SPEC_LONG (val->etype)) {
1417 if (SPEC_USIGN (val->etype))
1418 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1420 SPEC_CVAL (val->etype).v_long = (long) l;
1422 if (SPEC_USIGN (val->etype))
1423 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1425 SPEC_CVAL (val->etype).v_int = (short)l;
1426 if (SPEC_NOUN (val->etype)==V_CHAR) {
1427 SPEC_CVAL (val->etype).v_uint &= 0xff;
1434 /*------------------------------------------------------------------*/
1435 /* getNelements - determines # of elements from init list */
1436 /*------------------------------------------------------------------*/
1438 getNelements (sym_link * type, initList * ilist)
1440 sym_link *etype = getSpec (type);
1446 if (ilist->type == INIT_DEEP)
1447 ilist = ilist->init.deep;
1449 /* if type is a character array and there is only one
1450 (string) initialiser then get the length of the string */
1451 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1453 ast *iast = ilist->init.node;
1454 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1457 werror (W_INIT_WRONG);
1461 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1462 // yep, it's a string
1464 return DCL_ELEM (v->type);
1472 ilist = ilist->next;
1478 /*-----------------------------------------------------------------*/
1479 /* valForArray - returns a value with name of array index */
1480 /*-----------------------------------------------------------------*/
1482 valForArray (ast * arrExpr)
1484 value *val, *lval = NULL;
1486 int size = getSize (arrExpr->left->ftype->next);
1487 /* if the right or left is an array
1489 if (IS_AST_OP (arrExpr->left))
1491 if (arrExpr->left->opval.op == '[')
1492 lval = valForArray (arrExpr->left);
1493 else if (arrExpr->left->opval.op == '.')
1494 lval = valForStructElem (arrExpr->left->left,
1495 arrExpr->left->right);
1496 else if (arrExpr->left->opval.op == PTR_OP &&
1497 IS_ADDRESS_OF_OP (arrExpr->left->left))
1498 lval = valForStructElem (arrExpr->left->left->left,
1499 arrExpr->left->right);
1504 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1507 if (!IS_AST_LIT_VALUE (arrExpr->right))
1512 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1514 sprintf (buffer, "%s", lval->name);
1516 sprintf (val->name, "(%s + %d)", buffer,
1517 (int) AST_LIT_VALUE (arrExpr->right) * size);
1519 val->type = newLink ();
1520 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1522 DCL_TYPE (val->type) = CPOINTER;
1523 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1525 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1526 DCL_TYPE (val->type) = FPOINTER;
1527 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1528 DCL_TYPE (val->type) = PPOINTER;
1529 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1530 DCL_TYPE (val->type) = IPOINTER;
1531 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1532 DCL_TYPE (val->type) = EEPPOINTER;
1534 DCL_TYPE (val->type) = POINTER;
1535 val->type->next = arrExpr->left->ftype;
1536 val->etype = getSpec (val->type);
1540 /*-----------------------------------------------------------------*/
1541 /* valForStructElem - returns value with name of struct element */
1542 /*-----------------------------------------------------------------*/
1544 valForStructElem (ast * structT, ast * elemT)
1546 value *val, *lval = NULL;
1550 /* left could be furthur derefed */
1551 if (IS_AST_OP (structT))
1553 if (structT->opval.op == '[')
1554 lval = valForArray (structT);
1555 else if (structT->opval.op == '.')
1556 lval = valForStructElem (structT->left, structT->right);
1557 else if (structT->opval.op == PTR_OP &&
1558 IS_ADDRESS_OF_OP (structT->left))
1559 lval = valForStructElem (structT->left->left,
1565 if (!IS_AST_SYM_VALUE (elemT))
1568 if (!IS_STRUCT (structT->etype))
1571 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1572 AST_SYMBOL (elemT))) == NULL)
1579 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1581 sprintf (buffer, "%s", lval->name);
1583 sprintf (val->name, "(%s + %d)", buffer,
1586 val->type = newLink ();
1587 if (SPEC_SCLS (structT->etype) == S_CODE)
1589 DCL_TYPE (val->type) = CPOINTER;
1590 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1592 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1593 DCL_TYPE (val->type) = FPOINTER;
1594 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1595 DCL_TYPE (val->type) = PPOINTER;
1596 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1597 DCL_TYPE (val->type) = IPOINTER;
1598 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1599 DCL_TYPE (val->type) = EEPPOINTER;
1601 DCL_TYPE (val->type) = POINTER;
1602 val->type->next = sym->type;
1603 val->etype = getSpec (val->type);
1607 /*-----------------------------------------------------------------*/
1608 /* valForCastAggr - will return value for a cast of an aggregate */
1609 /* plus minus a constant */
1610 /*-----------------------------------------------------------------*/
1612 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1616 if (!IS_AST_SYM_VALUE (aexpr))
1618 if (!IS_AST_LIT_VALUE (cnst))
1623 sprintf (val->name, "(%s %c %d)",
1624 AST_SYMBOL (aexpr)->rname, op,
1625 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1628 val->etype = getSpec (val->type);
1632 /*-----------------------------------------------------------------*/
1633 /* valForCastAggr - will return value for a cast of an aggregate */
1634 /* with no constant */
1635 /*-----------------------------------------------------------------*/
1637 valForCastArr (ast * aexpr, sym_link * type)
1641 if (!IS_AST_SYM_VALUE (aexpr))
1646 sprintf (val->name, "(%s)",
1647 AST_SYMBOL (aexpr)->rname);
1650 val->etype = getSpec (val->type);