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);
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) {
323 unsigned long uval=0;
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 ((((long) lit) - lit) == 0)
383 SNPRINTF (buffer, sizeof(buffer), "%ld", (long) 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 ();
407 val->type->class = SPECIFIER;
408 SPEC_NOUN (val->type) = V_FLOAT;
409 SPEC_SCLS (val->type) = S_LITERAL;
410 SPEC_CVAL (val->type).v_float = sval;
415 /*-----------------------------------------------------------------*/
416 /* constVal - converts an INTEGER constant into a cheapest value */
417 /*-----------------------------------------------------------------*/
418 value *constVal (char *s)
421 short hex = 0, octal = 0;
426 val = newValue (); /* alloc space for value */
428 val->type = val->etype = newLink (); /* create the spcifier */
429 val->type->class = SPECIFIER;
430 SPEC_SCLS (val->type) = S_LITERAL;
431 // let's start with an unsigned char
432 SPEC_NOUN (val->type) = V_CHAR;
433 SPEC_USIGN (val->type) = 1;
435 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
437 /* set the octal flag */
438 if (!hex && *s == '0' && *(s + 1))
441 /* create the scan string */
442 scanFmt[scI++] = '%';
444 scanFmt[scI++] = 'l';
447 scanFmt[scI++] = 'o';
449 scanFmt[scI++] = 'x';
451 scanFmt[scI++] = 'f';
453 scanFmt[scI++] = '\0';
457 sscanf (s, scanFmt, &sval);
460 sscanf (s, scanFmt, &dval);
463 /* Setup the flags first */
464 /* set the _long flag if 'lL' is found */
465 if (strchr (s, 'l') || strchr (s, 'L')) {
466 SPEC_NOUN (val->type) = V_INT;
467 SPEC_LONG (val->type) = 1;
470 if (dval<0) { // "-28u" will still be signed and negative
471 SPEC_USIGN (val->type) = 0;
472 if (dval<-128) { // check if we have to promote to int
473 SPEC_NOUN (val->type) = V_INT;
475 if (dval<-32768) { // check if we have to promote to long int
476 SPEC_LONG (val->type) = 1;
479 if (dval>0xff) { // check if we have to promote to int
480 SPEC_NOUN (val->type) = V_INT;
482 if (dval>0xffff) { // check if we have to promote to long int
483 SPEC_LONG (val->type) = 1;
487 if (SPEC_LONG (val->type))
489 if (SPEC_USIGN (val->type))
491 SPEC_CVAL (val->type).v_ulong = dval;
495 SPEC_CVAL (val->type).v_long = dval;
500 if (SPEC_USIGN (val->type))
502 SPEC_CVAL (val->type).v_uint = dval;
506 SPEC_CVAL (val->type).v_int = dval;
513 /*! /fn char hexEscape(char **src)
515 /param src Pointer to 'x' from start of hex character value
518 unsigned char hexEscape(char **src)
521 unsigned long value ;
523 (*src)++ ; /* Skip over the 'x' */
524 s = *src ; /* Save for error detection */
526 value = strtol (*src, src, 16);
529 // no valid hex found
530 werror(E_INVALID_HEX);
533 werror(W_ESC_SEQ_OOR_FOR_CHAR);
539 /*------------------------------------------------------------------*/
540 /* octalEscape - process an octal constant of max three digits */
541 /* return the octal value, throw a warning for illegal octal */
542 /* adjust src to point at the last proccesed char */
543 /*------------------------------------------------------------------*/
545 unsigned char octalEscape (char **str) {
549 for (digits=0; digits<3; digits++) {
550 if (**str>='0' && **str<='7') {
551 value = value*8 + (**str-'0');
558 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
559 werror (W_ESC_SEQ_OOR_FOR_CHAR);
566 /fn int copyStr (char *dest, char *src)
568 Copies a source string to a dest buffer interpreting escape sequences
569 and special characters
571 /param dest Buffer to receive the resultant string
572 /param src Buffer containing the source string with escape sequecnes
573 /return Number of characters in output string
578 copyStr (char *dest, char *src)
581 char *OriginalDest = dest ;
587 else if (*src == '\\')
622 *dest++ = octalEscape(&src);
627 *dest++ = hexEscape(&src) ;
654 return dest - OriginalDest ;
657 /*------------------------------------------------------------------*/
658 /* strVal - converts a string constant to a value */
659 /*------------------------------------------------------------------*/
665 val = newValue (); /* get a new one */
667 /* get a declarator */
668 val->type = newLink ();
669 DCL_TYPE (val->type) = ARRAY;
670 val->type->next = val->etype = newLink ();
671 val->etype->class = SPECIFIER;
672 SPEC_NOUN (val->etype) = V_CHAR;
673 SPEC_SCLS (val->etype) = S_LITERAL;
675 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
676 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
682 /*------------------------------------------------------------------*/
683 /* reverseValWithType - reverses value chain with type & etype */
684 /*------------------------------------------------------------------*/
686 reverseValWithType (value * val)
694 /* save the type * etype chains */
698 /* set the current one 2b null */
699 val->type = val->etype = NULL;
700 val = reverseVal (val);
702 /* restore type & etype */
709 /*------------------------------------------------------------------*/
710 /* reverseVal - reverses the values for a value chain */
711 /*------------------------------------------------------------------*/
713 reverseVal (value * val)
715 value *prev, *curr, *next;
730 val->next = (void *) NULL;
734 /*------------------------------------------------------------------*/
735 /* copyValueChain - will copy a chain of values */
736 /*------------------------------------------------------------------*/
738 copyValueChain (value * src)
745 dest = copyValue (src);
746 dest->next = copyValueChain (src->next);
751 /*------------------------------------------------------------------*/
752 /* copyValue - copies contents of a value to a fresh one */
753 /*------------------------------------------------------------------*/
755 copyValue (value * src)
760 dest->sym = copySymbol (src->sym);
761 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
762 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
763 dest->etype = (src->type ? getSpec (dest->type) : NULL);
768 /*------------------------------------------------------------------*/
769 /* charVal - converts a character constant to a value */
770 /*------------------------------------------------------------------*/
779 val->type = val->etype = newLink ();
780 val->type->class = SPECIFIER;
781 SPEC_NOUN (val->type) = V_CHAR;
782 SPEC_USIGN(val->type) = 1;
783 SPEC_SCLS (val->type) = S_LITERAL;
785 s++; /* get rid of quotation */
786 /* if \ then special processing */
789 s++; /* go beyond the backslash */
793 SPEC_CVAL (val->type).v_int = '\n';
796 SPEC_CVAL (val->type).v_int = '\t';
799 SPEC_CVAL (val->type).v_int = '\v';
802 SPEC_CVAL (val->type).v_int = '\b';
805 SPEC_CVAL (val->type).v_int = '\r';
808 SPEC_CVAL (val->type).v_int = '\f';
811 SPEC_CVAL (val->type).v_int = '\a';
814 SPEC_CVAL (val->type).v_int = '\\';
817 SPEC_CVAL (val->type).v_int = '\?';
820 SPEC_CVAL (val->type).v_int = '\'';
823 SPEC_CVAL (val->type).v_int = '\"';
834 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
838 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
842 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
846 else /* not a backslash */
847 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
852 /*------------------------------------------------------------------*/
853 /* valFromType - creates a value from type given */
854 /*------------------------------------------------------------------*/
856 valFromType (sym_link * type)
858 value *val = newValue ();
859 val->type = copyLinkChain (type);
860 val->etype = getSpec (val->type);
864 /*------------------------------------------------------------------*/
865 /* floatFromVal - value to double float conversion */
866 /*------------------------------------------------------------------*/
868 floatFromVal (value * val)
873 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
875 werror (E_CONST_EXPECTED, val->name);
879 /* if it is not a specifier then we can assume that */
880 /* it will be an unsigned long */
881 if (!IS_SPEC (val->type))
882 return (double) SPEC_CVAL (val->etype).v_ulong;
884 if (SPEC_NOUN (val->etype) == V_FLOAT)
885 return (double) SPEC_CVAL (val->etype).v_float;
887 if (SPEC_LONG (val->etype))
889 if (SPEC_USIGN (val->etype))
890 return (double) SPEC_CVAL (val->etype).v_ulong;
892 return (double) SPEC_CVAL (val->etype).v_long;
895 if (SPEC_NOUN (val->etype) == V_INT) {
896 if (SPEC_USIGN (val->etype))
897 return (double) SPEC_CVAL (val->etype).v_uint;
899 return (double) SPEC_CVAL (val->etype).v_int;
902 if (SPEC_NOUN (val->etype) == V_CHAR) {
903 if (SPEC_USIGN (val->etype))
904 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
906 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
909 if (IS_BITVAR(val->etype)) {
910 return (double) SPEC_CVAL (val->etype).v_ulong;
913 if (SPEC_NOUN (val->etype) == V_VOID) {
914 return (double) SPEC_CVAL (val->etype).v_ulong;
918 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
919 "floatFromVal: unknown value");
924 /*------------------------------------------------------------------*/
925 /* valUnaryPM - does the unary +/- operation on a constant */
926 /*------------------------------------------------------------------*/
928 valUnaryPM (value * val)
930 /* depending on type */
931 if (SPEC_NOUN (val->etype) == V_FLOAT)
932 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
935 if (SPEC_LONG (val->etype))
937 if (SPEC_USIGN (val->etype))
938 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
940 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
944 if (SPEC_USIGN (val->etype))
945 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
947 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
950 // -(unsigned 3) now really is signed
951 SPEC_USIGN(val->etype)=0;
952 // -(unsigned char)135 now really is an int
953 if (SPEC_NOUN(val->etype) == V_CHAR) {
954 if (SPEC_CVAL(val->etype).v_int < -128) {
955 SPEC_NOUN(val->etype) = V_INT;
961 /*------------------------------------------------------------------*/
962 /* valueComplement - complements a constant */
963 /*------------------------------------------------------------------*/
965 valComplement (value * val)
967 /* depending on type */
968 if (SPEC_LONG (val->etype))
970 if (SPEC_USIGN (val->etype))
971 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
973 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
977 if (SPEC_USIGN (val->etype))
978 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
980 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
982 // ~(unsigned 3) now really is signed
983 SPEC_USIGN(val->etype)=0;
987 /*------------------------------------------------------------------*/
988 /* valueNot - complements a constant */
989 /*------------------------------------------------------------------*/
993 /* depending on type */
994 if (SPEC_LONG (val->etype))
996 if (SPEC_USIGN (val->etype))
997 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
999 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1003 if (SPEC_USIGN (val->etype))
1004 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1006 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1011 /*------------------------------------------------------------------*/
1012 /* valMult - multiply constants */
1013 /*------------------------------------------------------------------*/
1015 valMult (value * lval, value * rval)
1019 /* create a new value */
1021 val->type = val->etype = newLink ();
1022 val->type->class = SPECIFIER;
1023 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1024 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1025 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1026 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1027 SPEC_LONG (val->type) = 1;
1029 if (IS_FLOAT (val->type))
1030 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1033 if (SPEC_LONG (val->type))
1035 if (SPEC_USIGN (val->type))
1036 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1037 (unsigned long) floatFromVal (rval);
1039 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1040 (long) floatFromVal (rval);
1043 return cheapestVal(val);
1046 /*------------------------------------------------------------------*/
1047 /* valDiv - Divide constants */
1048 /*------------------------------------------------------------------*/
1050 valDiv (value * lval, value * rval)
1054 if (floatFromVal (rval) == 0)
1056 werror (E_DIVIDE_BY_ZERO);
1060 /* create a new value */
1062 val->type = val->etype = newLink();
1063 val->type->class = SPECIFIER;
1064 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1065 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1066 SPEC_SCLS (val->etype) = S_LITERAL;
1067 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1068 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1070 if (IS_FLOAT (val->type))
1071 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1074 if (SPEC_LONG (val->type))
1076 if (SPEC_USIGN (val->type))
1077 SPEC_CVAL (val->type).v_ulong =
1078 (unsigned long) floatFromVal (lval) /
1079 (unsigned long) floatFromVal (rval);
1081 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1082 (long) floatFromVal (rval);
1086 if (SPEC_USIGN (val->type)) {
1087 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1088 (unsigned) floatFromVal (rval);
1090 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1091 (int) floatFromVal (rval);
1095 return cheapestVal(val);
1098 /*------------------------------------------------------------------*/
1099 /* valMod - Modulus constants */
1100 /*------------------------------------------------------------------*/
1102 valMod (value * lval, value * rval)
1106 /* create a new value */
1108 val->type = val->etype = newLink ();
1109 val->type->class = SPECIFIER;
1110 SPEC_NOUN (val->type) = V_INT; /* type is int */
1111 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1112 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1113 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1115 if (SPEC_LONG (val->type))
1117 if (SPEC_USIGN (val->type))
1118 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1119 (unsigned long) floatFromVal (rval);
1121 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1122 (unsigned long) floatFromVal (rval);
1126 if (SPEC_USIGN (val->type)) {
1127 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1128 (unsigned) floatFromVal (rval);
1130 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1131 (unsigned) floatFromVal (rval);
1135 return cheapestVal(val);
1138 /*------------------------------------------------------------------*/
1139 /* valPlus - Addition constants */
1140 /*------------------------------------------------------------------*/
1142 valPlus (value * lval, value * rval)
1146 /* create a new value */
1148 val->type = val->etype = newLink ();
1149 val->type->class = SPECIFIER;
1150 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1151 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1152 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1153 SPEC_USIGN (val->type) =
1154 SPEC_USIGN (lval->etype) &&
1155 SPEC_USIGN (rval->etype) &&
1156 (floatFromVal(lval)+floatFromVal(rval))>=0;
1158 SPEC_LONG (val->type) = 1;
1160 if (IS_FLOAT (val->type))
1161 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1164 if (SPEC_LONG (val->type))
1166 if (SPEC_USIGN (val->type))
1167 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1168 (unsigned long) floatFromVal (rval);
1170 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1171 (long) floatFromVal (rval);
1174 return cheapestVal(val);
1177 /*------------------------------------------------------------------*/
1178 /* valMinus - Addition constants */
1179 /*------------------------------------------------------------------*/
1181 valMinus (value * lval, value * rval)
1185 /* create a new value */
1187 val->type = val->etype = newLink ();
1188 val->type->class = SPECIFIER;
1189 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1190 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1191 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1192 SPEC_USIGN (val->type) =
1193 SPEC_USIGN (lval->etype) &&
1194 SPEC_USIGN (rval->etype) &&
1195 (floatFromVal(lval)-floatFromVal(rval))>=0;
1197 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1199 if (IS_FLOAT (val->type))
1200 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1203 if (SPEC_LONG (val->type))
1205 if (SPEC_USIGN (val->type)) {
1206 SPEC_CVAL (val->type).v_ulong =
1207 (unsigned long) floatFromVal (lval) -
1208 (unsigned long) floatFromVal (rval);
1210 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1211 (long) floatFromVal (rval);
1216 if (SPEC_USIGN (val->type)) {
1217 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1218 (unsigned) floatFromVal (rval);
1220 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1221 (int) floatFromVal (rval);
1225 return cheapestVal(val);
1228 /*------------------------------------------------------------------*/
1229 /* valShift - Shift left or right */
1230 /*------------------------------------------------------------------*/
1232 valShift (value * lval, value * rval, int lr)
1236 /* create a new value */
1238 val->type = val->etype = newIntLink ();
1239 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1240 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1241 SPEC_LONG (val->type) = 1;
1243 if (SPEC_LONG (val->type))
1245 if (SPEC_USIGN (val->type))
1246 SPEC_CVAL (val->type).v_ulong = lr ?
1247 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1248 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1250 SPEC_CVAL (val->type).v_long = lr ?
1251 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1252 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1255 return cheapestVal(val);
1258 /*------------------------------------------------------------------*/
1259 /* valCompare- Compares two literal */
1260 /*------------------------------------------------------------------*/
1262 valCompare (value * lval, value * rval, int ctype)
1266 /* create a new value */
1268 val->type = val->etype = newCharLink ();
1269 val->type->class = SPECIFIER;
1270 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1271 SPEC_USIGN (val->type) = 1;
1272 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1277 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1281 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1285 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1289 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1293 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1297 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1305 /*------------------------------------------------------------------*/
1306 /* valBitwise - Bitwise operation */
1307 /*------------------------------------------------------------------*/
1309 valBitwise (value * lval, value * rval, int op)
1313 /* create a new value */
1315 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1316 rval->type : lval->type);
1317 val->etype = getSpec (val->type);
1322 if (SPEC_LONG (val->type))
1324 if (SPEC_USIGN (val->type))
1325 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1326 (unsigned long) floatFromVal (rval);
1328 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1329 (long) floatFromVal (rval);
1333 if (SPEC_USIGN (val->type))
1334 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1335 (unsigned) floatFromVal (rval);
1337 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1342 if (SPEC_LONG (val->type))
1344 if (SPEC_USIGN (val->type))
1345 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1346 (unsigned long) floatFromVal (rval);
1348 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1349 (long) floatFromVal (rval);
1353 if (SPEC_USIGN (val->type))
1354 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1355 (unsigned) floatFromVal (rval);
1357 SPEC_CVAL (val->type).v_int =
1358 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1364 if (SPEC_LONG (val->type))
1366 if (SPEC_USIGN (val->type))
1367 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1368 (unsigned long) floatFromVal (rval);
1370 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1371 (long) floatFromVal (rval);
1375 if (SPEC_USIGN (val->type))
1376 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1377 (unsigned) floatFromVal (rval);
1379 SPEC_CVAL (val->type).v_int =
1380 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1385 return cheapestVal(val);
1388 /*------------------------------------------------------------------*/
1389 /* valAndOr - Generates code for and / or operation */
1390 /*------------------------------------------------------------------*/
1392 valLogicAndOr (value * lval, value * rval, int op)
1396 /* create a new value */
1398 val->type = val->etype = newCharLink ();
1399 val->type->class = SPECIFIER;
1400 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1401 SPEC_USIGN (val->type) = 0;
1406 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1410 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1418 /*------------------------------------------------------------------*/
1419 /* valCastLiteral - casts a literal value to another type */
1420 /*------------------------------------------------------------------*/
1422 valCastLiteral (sym_link * dtype, double fval)
1430 val->etype = getSpec (val->type = copyLinkChain (dtype));
1431 SPEC_SCLS (val->etype) = S_LITERAL;
1432 /* if it is not a specifier then we can assume that */
1433 /* it will be an unsigned long */
1434 if (!IS_SPEC (val->type)) {
1435 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1439 if (SPEC_NOUN (val->etype) == V_FLOAT)
1440 SPEC_CVAL (val->etype).v_float = fval;
1442 unsigned long l = fval;
1443 if (SPEC_LONG (val->etype)) {
1444 if (SPEC_USIGN (val->etype))
1445 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1447 SPEC_CVAL (val->etype).v_long = (long) l;
1449 if (SPEC_USIGN (val->etype))
1450 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1452 SPEC_CVAL (val->etype).v_int = (short)l;
1458 /*------------------------------------------------------------------*/
1459 /* getNelements - determines # of elements from init list */
1460 /*------------------------------------------------------------------*/
1462 getNelements (sym_link * type, initList * ilist)
1469 if (ilist->type == INIT_DEEP)
1470 ilist = ilist->init.deep;
1472 /* if type is a character array and there is only one
1473 (string) initialiser then get the length of the string */
1474 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1476 ast *iast = ilist->init.node;
1477 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1480 werror (E_CONST_EXPECTED);
1484 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1485 // yep, it's a string
1487 return DCL_ELEM (v->type);
1495 ilist = ilist->next;
1500 /*-----------------------------------------------------------------*/
1501 /* valForArray - returns a value with name of array index */
1502 /*-----------------------------------------------------------------*/
1504 valForArray (ast * arrExpr)
1506 value *val, *lval = NULL;
1508 int size = getSize (arrExpr->left->ftype->next);
1509 /* if the right or left is an array
1511 if (IS_AST_OP (arrExpr->left))
1513 if (arrExpr->left->opval.op == '[')
1514 lval = valForArray (arrExpr->left);
1515 else if (arrExpr->left->opval.op == '.')
1516 lval = valForStructElem (arrExpr->left->left,
1517 arrExpr->left->right);
1518 else if (arrExpr->left->opval.op == PTR_OP &&
1519 IS_ADDRESS_OF_OP (arrExpr->left->left))
1520 lval = valForStructElem (arrExpr->left->left->left,
1521 arrExpr->left->right);
1526 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1529 if (!IS_AST_LIT_VALUE (arrExpr->right))
1535 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1539 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1542 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1543 (int) AST_LIT_VALUE (arrExpr->right) * size);
1545 val->type = newLink ();
1546 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1548 DCL_TYPE (val->type) = CPOINTER;
1549 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1551 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1552 DCL_TYPE (val->type) = FPOINTER;
1553 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1554 DCL_TYPE (val->type) = PPOINTER;
1555 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1556 DCL_TYPE (val->type) = IPOINTER;
1557 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1558 DCL_TYPE (val->type) = EEPPOINTER;
1560 DCL_TYPE (val->type) = POINTER;
1561 val->type->next = arrExpr->left->ftype;
1562 val->etype = getSpec (val->type);
1566 /*-----------------------------------------------------------------*/
1567 /* valForStructElem - returns value with name of struct element */
1568 /*-----------------------------------------------------------------*/
1570 valForStructElem (ast * structT, ast * elemT)
1572 value *val, *lval = NULL;
1576 /* left could be furthur derefed */
1577 if (IS_AST_OP (structT))
1579 if (structT->opval.op == '[')
1580 lval = valForArray (structT);
1581 else if (structT->opval.op == '.')
1582 lval = valForStructElem (structT->left, structT->right);
1583 else if (structT->opval.op == PTR_OP &&
1584 IS_ADDRESS_OF_OP (structT->left))
1585 lval = valForStructElem (structT->left->left,
1591 if (!IS_AST_SYM_VALUE (elemT))
1594 if (!IS_STRUCT (structT->etype))
1597 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1598 AST_SYMBOL (elemT))) == NULL)
1606 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1610 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1613 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1616 val->type = newLink ();
1617 if (SPEC_SCLS (structT->etype) == S_CODE)
1619 DCL_TYPE (val->type) = CPOINTER;
1620 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1622 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1623 DCL_TYPE (val->type) = FPOINTER;
1624 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1625 DCL_TYPE (val->type) = PPOINTER;
1626 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1627 DCL_TYPE (val->type) = IPOINTER;
1628 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1629 DCL_TYPE (val->type) = EEPPOINTER;
1631 DCL_TYPE (val->type) = POINTER;
1632 val->type->next = sym->type;
1633 val->etype = getSpec (val->type);
1637 /*-----------------------------------------------------------------*/
1638 /* valForCastAggr - will return value for a cast of an aggregate */
1639 /* plus minus a constant */
1640 /*-----------------------------------------------------------------*/
1642 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1646 if (!IS_AST_SYM_VALUE (aexpr))
1648 if (!IS_AST_LIT_VALUE (cnst))
1653 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1654 AST_SYMBOL (aexpr)->rname, op,
1655 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1658 val->etype = getSpec (val->type);
1662 /*-----------------------------------------------------------------*/
1663 /* valForCastAggr - will return value for a cast of an aggregate */
1664 /* with no constant */
1665 /*-----------------------------------------------------------------*/
1667 valForCastArr (ast * aexpr, sym_link * type)
1671 if (!IS_AST_SYM_VALUE (aexpr))
1676 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1677 AST_SYMBOL (aexpr)->rname);
1680 val->etype = getSpec (val->type);