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 = mylineno;
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);
308 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
312 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
318 /*--------------------------------------------------------------------*/
319 /* cheapestVal - convert a val to the cheapest as possible value */
320 /*--------------------------------------------------------------------*/
321 value *cheapestVal (value *val) {
325 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
328 if (SPEC_LONG(val->type)) {
329 if (SPEC_USIGN(val->type)) {
330 uval=SPEC_CVAL(val->type).v_ulong;
332 sval=SPEC_CVAL(val->type).v_long;
335 if (SPEC_USIGN(val->type)) {
336 uval=SPEC_CVAL(val->type).v_uint;
338 sval=SPEC_CVAL(val->type).v_int;
342 if (SPEC_USIGN(val->type)) {
344 SPEC_LONG(val->type)=0;
345 SPEC_CVAL(val->type).v_uint = uval;
347 SPEC_NOUN(val->type)=V_CHAR;
350 } else { // not unsigned
353 SPEC_LONG(val->type)=0;
354 SPEC_CVAL(val->type).v_int = sval;
356 SPEC_NOUN(val->type)=V_CHAR;
360 SPEC_USIGN(val->type)=1;
362 SPEC_LONG(val->type)=0;
363 SPEC_CVAL(val->type).v_int = sval;
365 SPEC_NOUN(val->type)=V_CHAR;
373 /*-----------------------------------------------------------------*/
374 /* valueFromLit - creates a value from a literal */
375 /*-----------------------------------------------------------------*/
377 valueFromLit (double lit)
381 if ((((TYPE_DWORD) lit) - lit) == 0)
383 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
384 return constVal (buffer);
387 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
388 return constFloatVal (buffer);
391 /*-----------------------------------------------------------------*/
392 /* constFloatVal - converts a FLOAT constant to value */
393 /*-----------------------------------------------------------------*/
395 constFloatVal (char *s)
397 value *val = newValue ();
400 if (sscanf (s, "%lf", &sval) != 1)
402 werror (E_INVALID_FLOAT_CONST, s);
403 return constVal ("0");
406 val->type = val->etype = newLink (SPECIFIER);
407 SPEC_NOUN (val->type) = V_FLOAT;
408 SPEC_SCLS (val->type) = S_LITERAL;
409 SPEC_CVAL (val->type).v_float = sval;
414 /*-----------------------------------------------------------------*/
415 /* constVal - converts an INTEGER constant into a cheapest value */
416 /*-----------------------------------------------------------------*/
417 value *constVal (char *s)
420 short hex = 0, octal = 0;
425 val = newValue (); /* alloc space for value */
427 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
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) = 0;
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);
457 SPEC_USIGN (val->type) = 1;
459 sscanf (s, scanFmt, &dval);
462 /* Setup the flags first */
463 /* set the _long flag if 'lL' is found */
464 if (strchr (s, 'l') || strchr (s, 'L')) {
465 SPEC_NOUN (val->type) = V_INT;
466 SPEC_LONG (val->type) = 1;
469 /* set the unsigned flag if 'uU' is found */
470 if (strchr (s, 'u') || strchr (s, 'U')) {
471 SPEC_USIGN (val->type) = 1;
474 if (dval<0) { // "-28u" will still be signed and negative
475 if (dval<-128) { // check if we have to promote to int
476 SPEC_NOUN (val->type) = V_INT;
478 if (dval<-32768) { // check if we have to promote to long int
479 SPEC_LONG (val->type) = 1;
482 if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int
483 SPEC_NOUN (val->type) = V_INT;
485 else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
486 SPEC_NOUN (val->type) = V_INT;
488 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
489 SPEC_LONG (val->type) = 1;
491 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
492 SPEC_LONG (val->type) = 1;
496 if (SPEC_LONG (val->type))
498 if (SPEC_USIGN (val->type))
500 SPEC_CVAL (val->type).v_ulong = dval;
504 SPEC_CVAL (val->type).v_long = dval;
509 if (SPEC_USIGN (val->type))
511 SPEC_CVAL (val->type).v_uint = dval;
515 SPEC_CVAL (val->type).v_int = dval;
522 /*! /fn char hexEscape(char **src)
524 /param src Pointer to 'x' from start of hex character value
527 unsigned char hexEscape(char **src)
530 unsigned long value ;
532 (*src)++ ; /* Skip over the 'x' */
533 s = *src ; /* Save for error detection */
535 value = strtol (*src, src, 16);
538 // no valid hex found
539 werror(E_INVALID_HEX);
542 werror(W_ESC_SEQ_OOR_FOR_CHAR);
548 /*------------------------------------------------------------------*/
549 /* octalEscape - process an octal constant of max three digits */
550 /* return the octal value, throw a warning for illegal octal */
551 /* adjust src to point at the last proccesed char */
552 /*------------------------------------------------------------------*/
554 unsigned char octalEscape (char **str) {
558 for (digits=0; digits<3; digits++) {
559 if (**str>='0' && **str<='7') {
560 value = value*8 + (**str-'0');
567 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
568 werror (W_ESC_SEQ_OOR_FOR_CHAR);
575 /fn int copyStr (char *dest, char *src)
577 Copies a source string to a dest buffer interpreting escape sequences
578 and special characters
580 /param dest Buffer to receive the resultant string
581 /param src Buffer containing the source string with escape sequecnes
582 /return Number of characters in output string
587 copyStr (char *dest, char *src)
590 char *OriginalDest = dest ;
596 else if (*src == '\\')
631 *dest++ = octalEscape(&src);
636 *dest++ = hexEscape(&src) ;
663 return dest - OriginalDest ;
666 /*------------------------------------------------------------------*/
667 /* strVal - converts a string constant to a value */
668 /*------------------------------------------------------------------*/
674 val = newValue (); /* get a new one */
676 /* get a declarator */
677 val->type = newLink (DECLARATOR);
678 DCL_TYPE (val->type) = ARRAY;
679 val->type->next = val->etype = newLink (SPECIFIER);
680 SPEC_NOUN (val->etype) = V_CHAR;
681 SPEC_SCLS (val->etype) = S_LITERAL;
683 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
684 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
690 /*------------------------------------------------------------------*/
691 /* reverseValWithType - reverses value chain with type & etype */
692 /*------------------------------------------------------------------*/
694 reverseValWithType (value * val)
702 /* save the type * etype chains */
706 /* set the current one 2b null */
707 val->type = val->etype = NULL;
708 val = reverseVal (val);
710 /* restore type & etype */
717 /*------------------------------------------------------------------*/
718 /* reverseVal - reverses the values for a value chain */
719 /*------------------------------------------------------------------*/
721 reverseVal (value * val)
723 value *prev, *curr, *next;
738 val->next = (void *) NULL;
742 /*------------------------------------------------------------------*/
743 /* copyValueChain - will copy a chain of values */
744 /*------------------------------------------------------------------*/
746 copyValueChain (value * src)
753 dest = copyValue (src);
754 dest->next = copyValueChain (src->next);
759 /*------------------------------------------------------------------*/
760 /* copyValue - copies contents of a value to a fresh one */
761 /*------------------------------------------------------------------*/
763 copyValue (value * src)
768 dest->sym = copySymbol (src->sym);
769 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
770 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
771 dest->etype = (src->type ? getSpec (dest->type) : NULL);
776 /*------------------------------------------------------------------*/
777 /* charVal - converts a character constant to a value */
778 /*------------------------------------------------------------------*/
786 val->type = val->etype = newLink (SPECIFIER);
787 SPEC_NOUN (val->type) = V_CHAR;
788 SPEC_USIGN(val->type) = 1;
789 SPEC_SCLS (val->type) = S_LITERAL;
791 s++; /* get rid of quotation */
792 /* if \ then special processing */
795 s++; /* go beyond the backslash */
799 SPEC_CVAL (val->type).v_uint = '\n';
802 SPEC_CVAL (val->type).v_uint = '\t';
805 SPEC_CVAL (val->type).v_uint = '\v';
808 SPEC_CVAL (val->type).v_uint = '\b';
811 SPEC_CVAL (val->type).v_uint = '\r';
814 SPEC_CVAL (val->type).v_uint = '\f';
817 SPEC_CVAL (val->type).v_uint = '\a';
820 SPEC_CVAL (val->type).v_uint = '\\';
823 SPEC_CVAL (val->type).v_uint = '\?';
826 SPEC_CVAL (val->type).v_uint = '\'';
829 SPEC_CVAL (val->type).v_uint = '\"';
840 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
844 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
848 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
852 else /* not a backslash */
853 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
858 /*------------------------------------------------------------------*/
859 /* valFromType - creates a value from type given */
860 /*------------------------------------------------------------------*/
862 valFromType (sym_link * type)
864 value *val = newValue ();
865 val->type = copyLinkChain (type);
866 val->etype = getSpec (val->type);
870 /*------------------------------------------------------------------*/
871 /* floatFromVal - value to double float conversion */
872 /*------------------------------------------------------------------*/
874 floatFromVal (value * val)
879 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
881 werror (E_CONST_EXPECTED, val->name);
885 /* if it is not a specifier then we can assume that */
886 /* it will be an unsigned long */
887 if (!IS_SPEC (val->type))
888 return (double) SPEC_CVAL (val->etype).v_ulong;
890 if (SPEC_NOUN (val->etype) == V_FLOAT)
891 return (double) SPEC_CVAL (val->etype).v_float;
893 if (SPEC_LONG (val->etype))
895 if (SPEC_USIGN (val->etype))
896 return (double) SPEC_CVAL (val->etype).v_ulong;
898 return (double) SPEC_CVAL (val->etype).v_long;
901 if (SPEC_NOUN (val->etype) == V_INT) {
902 if (SPEC_USIGN (val->etype))
903 return (double) SPEC_CVAL (val->etype).v_uint;
905 return (double) SPEC_CVAL (val->etype).v_int;
908 if (SPEC_NOUN (val->etype) == V_CHAR) {
909 if (SPEC_USIGN (val->etype))
910 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
912 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
915 if (IS_BITVAR(val->etype)) {
916 return (double) SPEC_CVAL (val->etype).v_uint;
919 if (SPEC_NOUN (val->etype) == V_VOID) {
920 return (double) SPEC_CVAL (val->etype).v_ulong;
924 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
925 "floatFromVal: unknown value");
930 /*------------------------------------------------------------------*/
931 /* valUnaryPM - does the unary +/- operation on a constant */
932 /*------------------------------------------------------------------*/
934 valUnaryPM (value * val)
936 /* depending on type */
937 if (SPEC_NOUN (val->etype) == V_FLOAT)
938 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
941 if (SPEC_LONG (val->etype))
943 if (SPEC_USIGN (val->etype))
944 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
946 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
950 if (SPEC_USIGN (val->etype))
951 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
953 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
956 // -(unsigned 3) now really is signed
957 SPEC_USIGN(val->etype)=0;
958 // -(unsigned char)135 now really is an int
959 if (SPEC_NOUN(val->etype) == V_CHAR) {
960 if (SPEC_CVAL(val->etype).v_int < -128) {
961 SPEC_NOUN(val->etype) = V_INT;
967 /*------------------------------------------------------------------*/
968 /* valueComplement - complements a constant */
969 /*------------------------------------------------------------------*/
971 valComplement (value * val)
973 /* depending on type */
974 if (SPEC_LONG (val->etype))
976 if (SPEC_USIGN (val->etype))
977 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
979 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
983 if (SPEC_USIGN (val->etype))
984 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
986 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
988 // ~(unsigned 3) now really is signed
989 SPEC_USIGN(val->etype)=0;
993 /*------------------------------------------------------------------*/
994 /* valueNot - complements a constant */
995 /*------------------------------------------------------------------*/
999 /* depending on type */
1000 if (SPEC_LONG (val->etype))
1002 if (SPEC_USIGN (val->etype))
1003 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1005 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1009 if (SPEC_USIGN (val->etype))
1010 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1012 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1017 /*------------------------------------------------------------------*/
1018 /* valMult - multiply constants */
1019 /*------------------------------------------------------------------*/
1021 valMult (value * lval, value * rval)
1025 /* create a new value */
1027 val->type = val->etype = newLink (SPECIFIER);
1028 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1029 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1030 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1031 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1032 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1034 if (IS_FLOAT (val->type))
1035 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1038 /* signed and unsigned mul are the same, as long as the precision of the
1039 result isn't bigger than the precision of the operands. */
1040 if (SPEC_LONG (val->type))
1041 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1042 (TYPE_UDWORD) floatFromVal (rval);
1045 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1046 (TYPE_UWORD) floatFromVal (rval);
1048 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1049 if (!options.lessPedantic)
1051 if (SPEC_USIGN (val->type))
1053 if (ul != SPEC_CVAL (val->type).v_uint)
1056 else /* signed result */
1058 if ((TYPE_DWORD) ul != SPEC_CVAL (val->type).v_int)
1064 return cheapestVal(val);
1067 /*------------------------------------------------------------------*/
1068 /* valDiv - Divide constants */
1069 /*------------------------------------------------------------------*/
1071 valDiv (value * lval, value * rval)
1075 if (floatFromVal (rval) == 0)
1077 werror (E_DIVIDE_BY_ZERO);
1081 /* create a new value */
1083 val->type = val->etype = newLink(SPECIFIER);
1084 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1085 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1086 SPEC_SCLS (val->etype) = S_LITERAL;
1087 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1088 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1090 if (IS_FLOAT (val->type))
1091 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1094 if (SPEC_LONG (val->type))
1096 if (SPEC_USIGN (val->type))
1097 SPEC_CVAL (val->type).v_ulong =
1098 (unsigned long) floatFromVal (lval) /
1099 (unsigned long) floatFromVal (rval);
1101 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1102 (long) floatFromVal (rval);
1106 if (SPEC_USIGN (val->type)) {
1107 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1108 (unsigned) floatFromVal (rval);
1110 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1111 (int) floatFromVal (rval);
1115 return cheapestVal(val);
1118 /*------------------------------------------------------------------*/
1119 /* valMod - Modulus constants */
1120 /*------------------------------------------------------------------*/
1122 valMod (value * lval, value * rval)
1126 /* create a new value */
1128 val->type = val->etype = newLink (SPECIFIER);
1129 SPEC_NOUN (val->type) = V_INT; /* type is int */
1130 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1131 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1132 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1134 if (SPEC_LONG (val->type))
1136 if (SPEC_USIGN (val->type))
1137 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1138 (unsigned long) floatFromVal (rval);
1140 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1141 (unsigned long) floatFromVal (rval);
1145 if (SPEC_USIGN (val->type)) {
1146 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1147 (unsigned) floatFromVal (rval);
1149 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1150 (unsigned) floatFromVal (rval);
1154 return cheapestVal(val);
1157 /*------------------------------------------------------------------*/
1158 /* valPlus - Addition constants */
1159 /*------------------------------------------------------------------*/
1161 valPlus (value * lval, value * rval)
1165 /* create a new value */
1167 val->type = val->etype = newLink (SPECIFIER);
1168 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1169 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1170 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1171 SPEC_USIGN (val->type) =
1172 SPEC_USIGN (lval->etype) &&
1173 SPEC_USIGN (rval->etype) &&
1174 (floatFromVal(lval)+floatFromVal(rval))>=0;
1176 SPEC_LONG (val->type) = 1;
1178 if (IS_FLOAT (val->type))
1179 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1182 if (SPEC_LONG (val->type))
1184 if (SPEC_USIGN (val->type))
1185 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1186 (unsigned long) floatFromVal (rval);
1188 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1189 (long) floatFromVal (rval);
1192 return cheapestVal(val);
1195 /*------------------------------------------------------------------*/
1196 /* valMinus - Addition constants */
1197 /*------------------------------------------------------------------*/
1199 valMinus (value * lval, value * rval)
1203 /* create a new value */
1205 val->type = val->etype = newLink (SPECIFIER);
1206 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1207 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1208 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1209 SPEC_USIGN (val->type) =
1210 SPEC_USIGN (lval->etype) &&
1211 SPEC_USIGN (rval->etype) &&
1212 (floatFromVal(lval)-floatFromVal(rval))>=0;
1214 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1216 if (IS_FLOAT (val->type))
1217 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1220 if (SPEC_LONG (val->type))
1222 if (SPEC_USIGN (val->type)) {
1223 SPEC_CVAL (val->type).v_ulong =
1224 (unsigned long) floatFromVal (lval) -
1225 (unsigned long) floatFromVal (rval);
1227 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1228 (long) floatFromVal (rval);
1233 if (SPEC_USIGN (val->type)) {
1234 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1235 (unsigned) floatFromVal (rval);
1237 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1238 (int) floatFromVal (rval);
1242 return cheapestVal(val);
1245 /*------------------------------------------------------------------*/
1246 /* valShift - Shift left or right */
1247 /*------------------------------------------------------------------*/
1249 valShift (value * lval, value * rval, int lr)
1253 /* create a new value */
1255 val->type = val->etype = newIntLink ();
1256 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1257 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1258 SPEC_LONG (val->type) = 1;
1260 if (SPEC_LONG (val->type))
1262 if (SPEC_USIGN (val->type))
1263 SPEC_CVAL (val->type).v_ulong = lr ?
1264 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1265 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1267 SPEC_CVAL (val->type).v_long = lr ?
1268 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1269 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1272 return cheapestVal(val);
1275 /*------------------------------------------------------------------*/
1276 /* valCompare- Compares two literal */
1277 /*------------------------------------------------------------------*/
1279 valCompare (value * lval, value * rval, int ctype)
1283 /* create a new value */
1285 val->type = val->etype = newCharLink ();
1286 val->type->class = SPECIFIER;
1287 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1288 SPEC_USIGN (val->type) = 1;
1289 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1294 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1298 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1302 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1306 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1310 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1322 /*------------------------------------------------------------------*/
1323 /* valBitwise - Bitwise operation */
1324 /*------------------------------------------------------------------*/
1326 valBitwise (value * lval, value * rval, int op)
1330 /* create a new value */
1332 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1333 rval->type : 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)) {
1452 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1456 if (SPEC_NOUN (val->etype) == V_FLOAT)
1457 SPEC_CVAL (val->etype).v_float = fval;
1459 unsigned long l = fval;
1460 if (SPEC_LONG (val->etype)) {
1461 if (SPEC_USIGN (val->etype))
1462 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1464 SPEC_CVAL (val->etype).v_long = (long) l;
1466 if (SPEC_USIGN (val->etype))
1467 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1469 SPEC_CVAL (val->etype).v_int = (short)l;
1475 /*------------------------------------------------------------------*/
1476 /* getNelements - determines # of elements from init list */
1477 /*------------------------------------------------------------------*/
1479 getNelements (sym_link * type, initList * ilist)
1486 if (ilist->type == INIT_DEEP)
1487 ilist = ilist->init.deep;
1489 /* if type is a character array and there is only one
1490 (string) initialiser then get the length of the string */
1491 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1493 ast *iast = ilist->init.node;
1494 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1497 werror (E_CONST_EXPECTED);
1501 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1502 // yep, it's a string
1504 return DCL_ELEM (v->type);
1512 ilist = ilist->next;
1517 /*-----------------------------------------------------------------*/
1518 /* valForArray - returns a value with name of array index */
1519 /*-----------------------------------------------------------------*/
1521 valForArray (ast * arrExpr)
1523 value *val, *lval = NULL;
1525 int size = getSize (arrExpr->left->ftype->next);
1526 /* if the right or left is an array
1528 if (IS_AST_OP (arrExpr->left))
1530 if (arrExpr->left->opval.op == '[')
1531 lval = valForArray (arrExpr->left);
1532 else if (arrExpr->left->opval.op == '.')
1533 lval = valForStructElem (arrExpr->left->left,
1534 arrExpr->left->right);
1535 else if (arrExpr->left->opval.op == PTR_OP &&
1536 IS_ADDRESS_OF_OP (arrExpr->left->left))
1537 lval = valForStructElem (arrExpr->left->left->left,
1538 arrExpr->left->right);
1543 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1546 if (!IS_AST_LIT_VALUE (arrExpr->right))
1552 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1556 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1559 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1560 (int) AST_LIT_VALUE (arrExpr->right) * size);
1562 val->type = newLink (DECLARATOR);
1563 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1565 DCL_TYPE (val->type) = CPOINTER;
1566 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1568 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1569 DCL_TYPE (val->type) = FPOINTER;
1570 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1571 DCL_TYPE (val->type) = PPOINTER;
1572 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1573 DCL_TYPE (val->type) = IPOINTER;
1574 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1575 DCL_TYPE (val->type) = EEPPOINTER;
1577 DCL_TYPE (val->type) = POINTER;
1578 val->type->next = arrExpr->left->ftype;
1579 val->etype = getSpec (val->type);
1583 /*-----------------------------------------------------------------*/
1584 /* valForStructElem - returns value with name of struct element */
1585 /*-----------------------------------------------------------------*/
1587 valForStructElem (ast * structT, ast * elemT)
1589 value *val, *lval = NULL;
1593 /* left could be furthur derefed */
1594 if (IS_AST_OP (structT))
1596 if (structT->opval.op == '[')
1597 lval = valForArray (structT);
1598 else if (structT->opval.op == '.')
1599 lval = valForStructElem (structT->left, structT->right);
1600 else if (structT->opval.op == PTR_OP &&
1601 IS_ADDRESS_OF_OP (structT->left))
1602 lval = valForStructElem (structT->left->left,
1608 if (!IS_AST_SYM_VALUE (elemT))
1611 if (!IS_STRUCT (structT->etype))
1614 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1615 AST_SYMBOL (elemT))) == NULL)
1623 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1627 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1630 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1633 val->type = newLink (DECLARATOR);
1634 if (SPEC_SCLS (structT->etype) == S_CODE)
1636 DCL_TYPE (val->type) = CPOINTER;
1637 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1639 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1640 DCL_TYPE (val->type) = FPOINTER;
1641 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1642 DCL_TYPE (val->type) = PPOINTER;
1643 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1644 DCL_TYPE (val->type) = IPOINTER;
1645 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1646 DCL_TYPE (val->type) = EEPPOINTER;
1648 DCL_TYPE (val->type) = POINTER;
1649 val->type->next = sym->type;
1650 val->etype = getSpec (val->type);
1654 /*-----------------------------------------------------------------*/
1655 /* valForCastAggr - will return value for a cast of an aggregate */
1656 /* plus minus a constant */
1657 /*-----------------------------------------------------------------*/
1659 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1663 if (!IS_AST_SYM_VALUE (aexpr))
1665 if (!IS_AST_LIT_VALUE (cnst))
1670 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1671 AST_SYMBOL (aexpr)->rname, op,
1672 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1675 val->etype = getSpec (val->type);
1679 /*-----------------------------------------------------------------*/
1680 /* valForCastAggr - will return value for a cast of an aggregate */
1681 /* with no constant */
1682 /*-----------------------------------------------------------------*/
1684 valForCastArr (ast * aexpr, sym_link * type)
1688 if (!IS_AST_SYM_VALUE (aexpr))
1693 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1694 AST_SYMBOL (aexpr)->rname);
1697 val->etype = getSpec (val->type);