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;
353 SPEC_NOUN(val->type)=V_CHAR;
357 SPEC_USIGN(val->type)=1;
359 SPEC_LONG(val->type)=0;
360 SPEC_CVAL(val->type).v_int = sval;
362 SPEC_NOUN(val->type)=V_CHAR;
370 /*-----------------------------------------------------------------*/
371 /* valueFromLit - creates a value from a literal */
372 /*-----------------------------------------------------------------*/
374 valueFromLit (double lit)
378 if ((((long) lit) - lit) == 0)
380 sprintf (buffer, "%ld", (long) lit);
381 return constVal (buffer);
384 sprintf (buffer, "%f", lit);
385 return constFloatVal (buffer);
388 /*-----------------------------------------------------------------*/
389 /* constFloatVal - converts a FLOAT constant to value */
390 /*-----------------------------------------------------------------*/
392 constFloatVal (char *s)
394 value *val = newValue ();
397 if (sscanf (s, "%lf", &sval) != 1)
399 werror (E_INVALID_FLOAT_CONST, s);
400 return constVal ("0");
403 val->type = val->etype = newLink ();
404 val->type->class = SPECIFIER;
405 SPEC_NOUN (val->type) = V_FLOAT;
406 SPEC_SCLS (val->type) = S_LITERAL;
407 SPEC_CVAL (val->type).v_float = sval;
412 /*-----------------------------------------------------------------*/
413 /* constVal - converts an INTEGER constant into a cheapest value */
414 /*-----------------------------------------------------------------*/
415 value *constVal (char *s)
418 short hex = 0, octal = 0;
423 val = newValue (); /* alloc space for value */
425 val->type = val->etype = newLink (); /* create the spcifier */
426 val->type->class = SPECIFIER;
427 SPEC_SCLS (val->type) = S_LITERAL;
428 // let's start with an unsigned char
429 SPEC_NOUN (val->type) = V_CHAR;
430 SPEC_USIGN (val->type) = 1;
432 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
434 /* set the octal flag */
435 if (!hex && *s == '0' && *(s + 1))
438 /* create the scan string */
439 scanFmt[scI++] = '%';
441 scanFmt[scI++] = 'l';
444 scanFmt[scI++] = 'o';
446 scanFmt[scI++] = 'x';
448 scanFmt[scI++] = 'f';
450 scanFmt[scI++] = '\0';
454 sscanf (s, scanFmt, &sval);
457 sscanf (s, scanFmt, &dval);
460 /* Setup the flags first */
461 /* set the _long flag if 'lL' is found */
462 if (strchr (s, 'l') || strchr (s, 'L')) {
463 SPEC_NOUN (val->type) = V_INT;
464 SPEC_LONG (val->type) = 1;
467 if (dval<0) { // "-28u" will still be signed and negative
468 SPEC_USIGN (val->type) = 0;
469 if (dval<-128) { // check if we have to promote to int
470 SPEC_NOUN (val->type) = V_INT;
472 if (dval<-32768) { // check if we have to promote to long int
473 SPEC_LONG (val->type) = 1;
476 if (dval>0xff) { // check if we have to promote to int
477 SPEC_NOUN (val->type) = V_INT;
479 if (dval>0xffff) { // check if we have to promote to long int
480 SPEC_LONG (val->type) = 1;
484 if (SPEC_LONG (val->type))
486 if (SPEC_USIGN (val->type))
488 SPEC_CVAL (val->type).v_ulong = dval;
492 SPEC_CVAL (val->type).v_long = dval;
497 if (SPEC_USIGN (val->type))
499 SPEC_CVAL (val->type).v_uint = dval;
503 SPEC_CVAL (val->type).v_int = dval;
510 /*! /fn char hexEscape(char **src)
512 /param src Pointer to 'x' from start of hex character value
515 unsigned char hexEscape(char **src)
518 unsigned long value ;
520 (*src)++ ; /* Skip over the 'x' */
521 s = *src ; /* Save for error detection */
523 value = strtol (*src, src, 16);
526 // no valid hex found
527 werror(E_INVALID_HEX);
530 werror(W_ESC_SEQ_OOR_FOR_CHAR);
536 /*------------------------------------------------------------------*/
537 /* octalEscape - process an octal constant of max three digits */
538 /* return the octal value, throw a warning for illegal octal */
539 /* adjust src to point at the last proccesed char */
540 /*------------------------------------------------------------------*/
542 unsigned char octalEscape (char **str) {
546 for (digits=0; digits<3; digits++) {
547 if (**str>='0' && **str<='7') {
548 value = value*8 + (**str-'0');
555 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
556 werror (W_ESC_SEQ_OOR_FOR_CHAR);
563 /fn int copyStr (char *dest, char *src)
565 Copies a source string to a dest buffer interpreting escape sequences
566 and special characters
568 /param dest Buffer to receive the resultant string
569 /param src Buffer containing the source string with escape sequecnes
570 /return Number of characters in output string
575 copyStr (char *dest, char *src)
578 char *OriginalDest = dest ;
584 else if (*src == '\\')
619 *dest++ = octalEscape(&src);
624 *dest++ = hexEscape(&src) ;
651 return dest - OriginalDest ;
654 /*------------------------------------------------------------------*/
655 /* strVal - converts a string constant to a value */
656 /*------------------------------------------------------------------*/
662 val = newValue (); /* get a new one */
664 /* get a declarator */
665 val->type = newLink ();
666 DCL_TYPE (val->type) = ARRAY;
667 val->type->next = val->etype = newLink ();
668 val->etype->class = SPECIFIER;
669 SPEC_NOUN (val->etype) = V_CHAR;
670 SPEC_SCLS (val->etype) = S_LITERAL;
672 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
673 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
679 /*------------------------------------------------------------------*/
680 /* reverseValWithType - reverses value chain with type & etype */
681 /*------------------------------------------------------------------*/
683 reverseValWithType (value * val)
691 /* save the type * etype chains */
695 /* set the current one 2b null */
696 val->type = val->etype = NULL;
697 val = reverseVal (val);
699 /* restore type & etype */
706 /*------------------------------------------------------------------*/
707 /* reverseVal - reverses the values for a value chain */
708 /*------------------------------------------------------------------*/
710 reverseVal (value * val)
712 value *prev, *curr, *next;
727 val->next = (void *) NULL;
731 /*------------------------------------------------------------------*/
732 /* copyValueChain - will copy a chain of values */
733 /*------------------------------------------------------------------*/
735 copyValueChain (value * src)
742 dest = copyValue (src);
743 dest->next = copyValueChain (src->next);
748 /*------------------------------------------------------------------*/
749 /* copyValue - copies contents of a value to a fresh one */
750 /*------------------------------------------------------------------*/
752 copyValue (value * src)
757 dest->sym = copySymbol (src->sym);
758 strcpy (dest->name, src->name);
759 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
760 dest->etype = (src->type ? getSpec (dest->type) : NULL);
765 /*------------------------------------------------------------------*/
766 /* charVal - converts a character constant to a value */
767 /*------------------------------------------------------------------*/
776 val->type = val->etype = newLink ();
777 val->type->class = SPECIFIER;
778 SPEC_NOUN (val->type) = V_CHAR;
779 SPEC_USIGN(val->type) = 1;
780 SPEC_SCLS (val->type) = S_LITERAL;
782 s++; /* get rid of quotation */
783 /* if \ then special processing */
786 s++; /* go beyond the backslash */
790 SPEC_CVAL (val->type).v_int = '\n';
793 SPEC_CVAL (val->type).v_int = '\t';
796 SPEC_CVAL (val->type).v_int = '\v';
799 SPEC_CVAL (val->type).v_int = '\b';
802 SPEC_CVAL (val->type).v_int = '\r';
805 SPEC_CVAL (val->type).v_int = '\f';
808 SPEC_CVAL (val->type).v_int = '\a';
811 SPEC_CVAL (val->type).v_int = '\\';
814 SPEC_CVAL (val->type).v_int = '\?';
817 SPEC_CVAL (val->type).v_int = '\'';
820 SPEC_CVAL (val->type).v_int = '\"';
831 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
835 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
839 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
843 else /* not a backslash */
844 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
849 /*------------------------------------------------------------------*/
850 /* valFromType - creates a value from type given */
851 /*------------------------------------------------------------------*/
853 valFromType (sym_link * type)
855 value *val = newValue ();
856 val->type = copyLinkChain (type);
857 val->etype = getSpec (val->type);
861 /*------------------------------------------------------------------*/
862 /* floatFromVal - value to double float conversion */
863 /*------------------------------------------------------------------*/
865 floatFromVal (value * val)
870 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
872 werror (E_CONST_EXPECTED, val->name);
876 /* if it is not a specifier then we can assume that */
877 /* it will be an unsigned long */
878 if (!IS_SPEC (val->type))
879 return (double) SPEC_CVAL (val->etype).v_ulong;
881 if (SPEC_NOUN (val->etype) == V_FLOAT)
882 return (double) SPEC_CVAL (val->etype).v_float;
884 if (SPEC_LONG (val->etype))
886 if (SPEC_USIGN (val->etype))
887 return (double) SPEC_CVAL (val->etype).v_ulong;
889 return (double) SPEC_CVAL (val->etype).v_long;
892 if (SPEC_USIGN (val->etype))
893 return (double) SPEC_CVAL (val->etype).v_uint;
895 return (double) SPEC_CVAL (val->etype).v_int;
899 /*------------------------------------------------------------------*/
900 /* valUnaryPM - does the unary +/- operation on a constant */
901 /*------------------------------------------------------------------*/
903 valUnaryPM (value * val)
905 /* depending on type */
906 if (SPEC_NOUN (val->etype) == V_FLOAT)
907 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
910 if (SPEC_LONG (val->etype))
912 if (SPEC_USIGN (val->etype))
913 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
915 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
919 if (SPEC_USIGN (val->etype))
920 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
922 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
925 // -(unsigned 3) now really is signed
926 SPEC_USIGN(val->etype)=0;
930 /*------------------------------------------------------------------*/
931 /* valueComplement - complements a constant */
932 /*------------------------------------------------------------------*/
934 valComplement (value * val)
936 /* depending on type */
937 if (SPEC_LONG (val->etype))
939 if (SPEC_USIGN (val->etype))
940 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
942 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
946 if (SPEC_USIGN (val->etype))
947 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
949 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
954 /*------------------------------------------------------------------*/
955 /* valueNot - complements a constant */
956 /*------------------------------------------------------------------*/
960 /* depending on type */
961 if (SPEC_LONG (val->etype))
963 if (SPEC_USIGN (val->etype))
964 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
966 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
970 if (SPEC_USIGN (val->etype))
971 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
973 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
978 /*------------------------------------------------------------------*/
979 /* valMult - multiply constants */
980 /*------------------------------------------------------------------*/
982 valMult (value * lval, value * rval)
986 /* create a new value */
988 val->type = val->etype = newLink ();
989 val->type->class = SPECIFIER;
990 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
991 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
992 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
993 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
994 SPEC_LONG (val->type) = 1;
996 if (IS_FLOAT (val->type))
997 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1000 if (SPEC_LONG (val->type))
1002 if (SPEC_USIGN (val->type))
1003 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1004 (unsigned long) floatFromVal (rval);
1006 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1007 (long) floatFromVal (rval);
1010 return cheapestVal(val);
1013 /*------------------------------------------------------------------*/
1014 /* valDiv - Divide constants */
1015 /*------------------------------------------------------------------*/
1017 valDiv (value * lval, value * rval)
1021 if (floatFromVal (rval) == 0)
1023 werror (E_DIVIDE_BY_ZERO);
1027 /* create a new value */
1029 val->type = val->etype = newLink();
1030 val->type->class = SPECIFIER;
1031 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1032 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1033 SPEC_SCLS (val->etype) = S_LITERAL;
1034 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1035 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1037 if (IS_FLOAT (val->type))
1038 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1041 if (SPEC_LONG (val->type))
1043 if (SPEC_USIGN (val->type))
1044 SPEC_CVAL (val->type).v_ulong =
1045 (unsigned long) floatFromVal (lval) /
1046 (unsigned long) floatFromVal (rval);
1048 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1049 (long) floatFromVal (rval);
1053 if (SPEC_USIGN (val->type)) {
1054 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1055 (unsigned) floatFromVal (rval);
1057 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1058 (int) floatFromVal (rval);
1062 return cheapestVal(val);
1065 /*------------------------------------------------------------------*/
1066 /* valMod - Modulus constants */
1067 /*------------------------------------------------------------------*/
1069 valMod (value * lval, value * rval)
1073 /* create a new value */
1075 val->type = val->etype = newLink ();
1076 val->type->class = SPECIFIER;
1077 SPEC_NOUN (val->type) = V_INT; /* type is int */
1078 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1079 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1080 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1082 if (SPEC_LONG (val->type))
1084 if (SPEC_USIGN (val->type))
1085 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1086 (unsigned long) floatFromVal (rval);
1088 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1089 (unsigned long) floatFromVal (rval);
1093 if (SPEC_USIGN (val->type)) {
1094 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1095 (unsigned) floatFromVal (rval);
1097 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1098 (unsigned) floatFromVal (rval);
1102 return cheapestVal(val);
1105 /*------------------------------------------------------------------*/
1106 /* valPlus - Addition constants */
1107 /*------------------------------------------------------------------*/
1109 valPlus (value * lval, value * rval)
1113 /* create a new value */
1115 val->type = val->etype = newLink ();
1116 val->type->class = SPECIFIER;
1117 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1118 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1119 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1120 SPEC_USIGN (val->type) =
1121 SPEC_USIGN (lval->etype) &&
1122 SPEC_USIGN (rval->etype) &&
1123 (floatFromVal(lval)+floatFromVal(rval))>=0;
1125 SPEC_LONG (val->type) = 1;
1127 if (IS_FLOAT (val->type))
1128 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1131 if (SPEC_LONG (val->type))
1133 if (SPEC_USIGN (val->type))
1134 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1135 (unsigned long) floatFromVal (rval);
1137 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1138 (long) floatFromVal (rval);
1141 return cheapestVal(val);
1144 /*------------------------------------------------------------------*/
1145 /* valMinus - Addition constants */
1146 /*------------------------------------------------------------------*/
1148 valMinus (value * lval, value * rval)
1152 /* create a new value */
1154 val->type = val->etype = newLink ();
1155 val->type->class = SPECIFIER;
1156 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1157 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1158 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1159 SPEC_USIGN (val->type) =
1160 SPEC_USIGN (lval->etype) &&
1161 SPEC_USIGN (rval->etype) &&
1162 (floatFromVal(lval)-floatFromVal(rval))>=0;
1164 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1166 if (IS_FLOAT (val->type))
1167 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1170 if (SPEC_LONG (val->type))
1172 if (SPEC_USIGN (val->type)) {
1173 SPEC_CVAL (val->type).v_ulong =
1174 (unsigned long) floatFromVal (lval) -
1175 (unsigned long) floatFromVal (rval);
1177 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1178 (long) floatFromVal (rval);
1183 if (SPEC_USIGN (val->type)) {
1184 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1185 (unsigned) floatFromVal (rval);
1187 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1188 (int) floatFromVal (rval);
1192 return cheapestVal(val);
1195 /*------------------------------------------------------------------*/
1196 /* valShift - Shift left or right */
1197 /*------------------------------------------------------------------*/
1199 valShift (value * lval, value * rval, int lr)
1203 /* create a new value */
1205 val->type = val->etype = newIntLink ();
1206 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1207 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1208 SPEC_LONG (val->type) = 1;
1210 if (SPEC_LONG (val->type))
1212 if (SPEC_USIGN (val->type))
1213 SPEC_CVAL (val->type).v_ulong = lr ?
1214 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1215 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1217 SPEC_CVAL (val->type).v_long = lr ?
1218 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1219 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1222 return cheapestVal(val);
1225 /*------------------------------------------------------------------*/
1226 /* valCompare- Compares two literal */
1227 /*------------------------------------------------------------------*/
1229 valCompare (value * lval, value * rval, int ctype)
1233 /* create a new value */
1235 val->type = val->etype = newCharLink ();
1236 val->type->class = SPECIFIER;
1237 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1238 SPEC_USIGN (val->type) = 1;
1239 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1244 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1248 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1252 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1256 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1260 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1264 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1272 /*------------------------------------------------------------------*/
1273 /* valBitwise - Bitwise operation */
1274 /*------------------------------------------------------------------*/
1276 valBitwise (value * lval, value * rval, int op)
1280 /* create a new value */
1282 val->type = copyLinkChain (lval->type);
1283 val->etype = getSpec (val->type);
1288 if (SPEC_LONG (val->type))
1290 if (SPEC_USIGN (val->type))
1291 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1292 (unsigned long) floatFromVal (rval);
1294 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1295 (long) floatFromVal (rval);
1299 if (SPEC_USIGN (val->type))
1300 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1301 (unsigned) floatFromVal (rval);
1303 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1308 if (SPEC_LONG (val->type))
1310 if (SPEC_USIGN (val->type))
1311 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1312 (unsigned long) floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1315 (long) floatFromVal (rval);
1319 if (SPEC_USIGN (val->type))
1320 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1321 (unsigned) floatFromVal (rval);
1323 SPEC_CVAL (val->type).v_int =
1324 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1330 if (SPEC_LONG (val->type))
1332 if (SPEC_USIGN (val->type))
1333 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1334 (unsigned long) floatFromVal (rval);
1336 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1337 (long) floatFromVal (rval);
1341 if (SPEC_USIGN (val->type))
1342 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1343 (unsigned) floatFromVal (rval);
1345 SPEC_CVAL (val->type).v_int =
1346 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1351 return cheapestVal(val);
1354 /*------------------------------------------------------------------*/
1355 /* valAndOr - Generates code for and / or operation */
1356 /*------------------------------------------------------------------*/
1358 valLogicAndOr (value * lval, value * rval, int op)
1362 /* create a new value */
1364 val->type = val->etype = newCharLink ();
1365 val->type->class = SPECIFIER;
1366 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1367 SPEC_USIGN (val->type) = 0;
1372 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1376 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1384 /*------------------------------------------------------------------*/
1385 /* valCastLiteral - casts a literal value to another type */
1386 /*------------------------------------------------------------------*/
1388 valCastLiteral (sym_link * dtype, double fval)
1396 val->etype = getSpec (val->type = copyLinkChain (dtype));
1397 SPEC_SCLS (val->etype) = S_LITERAL;
1398 /* if it is not a specifier then we can assume that */
1399 /* it will be an unsigned long */
1400 if (!IS_SPEC (val->type)) {
1401 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1405 if (SPEC_NOUN (val->etype) == V_FLOAT)
1406 SPEC_CVAL (val->etype).v_float = fval;
1408 unsigned long l = fval;
1409 if (SPEC_LONG (val->etype)) {
1410 if (SPEC_USIGN (val->etype))
1411 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1413 SPEC_CVAL (val->etype).v_long = (long) l;
1415 if (SPEC_USIGN (val->etype))
1416 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1418 SPEC_CVAL (val->etype).v_int = (short)l;
1424 /*------------------------------------------------------------------*/
1425 /* getNelements - determines # of elements from init list */
1426 /*------------------------------------------------------------------*/
1428 getNelements (sym_link * type, initList * ilist)
1430 sym_link *etype = getSpec (type);
1436 if (ilist->type == INIT_DEEP)
1437 ilist = ilist->init.deep;
1439 /* if type is a character array and there is only one
1440 (string) initialiser then get the length of the string */
1441 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1443 ast *iast = ilist->init.node;
1444 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1447 werror (W_INIT_WRONG);
1451 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1452 // yep, it's a string
1454 return DCL_ELEM (v->type);
1462 ilist = ilist->next;
1468 /*-----------------------------------------------------------------*/
1469 /* valForArray - returns a value with name of array index */
1470 /*-----------------------------------------------------------------*/
1472 valForArray (ast * arrExpr)
1474 value *val, *lval = NULL;
1476 int size = getSize (arrExpr->left->ftype->next);
1477 /* if the right or left is an array
1479 if (IS_AST_OP (arrExpr->left))
1481 if (arrExpr->left->opval.op == '[')
1482 lval = valForArray (arrExpr->left);
1483 else if (arrExpr->left->opval.op == '.')
1484 lval = valForStructElem (arrExpr->left->left,
1485 arrExpr->left->right);
1486 else if (arrExpr->left->opval.op == PTR_OP &&
1487 IS_ADDRESS_OF_OP (arrExpr->left->left))
1488 lval = valForStructElem (arrExpr->left->left->left,
1489 arrExpr->left->right);
1494 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1497 if (!IS_AST_LIT_VALUE (arrExpr->right))
1502 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1504 sprintf (buffer, "%s", lval->name);
1506 sprintf (val->name, "(%s + %d)", buffer,
1507 (int) AST_LIT_VALUE (arrExpr->right) * size);
1509 val->type = newLink ();
1510 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1512 DCL_TYPE (val->type) = CPOINTER;
1513 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1515 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1516 DCL_TYPE (val->type) = FPOINTER;
1517 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1518 DCL_TYPE (val->type) = PPOINTER;
1519 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1520 DCL_TYPE (val->type) = IPOINTER;
1521 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1522 DCL_TYPE (val->type) = EEPPOINTER;
1524 DCL_TYPE (val->type) = POINTER;
1525 val->type->next = arrExpr->left->ftype;
1526 val->etype = getSpec (val->type);
1530 /*-----------------------------------------------------------------*/
1531 /* valForStructElem - returns value with name of struct element */
1532 /*-----------------------------------------------------------------*/
1534 valForStructElem (ast * structT, ast * elemT)
1536 value *val, *lval = NULL;
1540 /* left could be furthur derefed */
1541 if (IS_AST_OP (structT))
1543 if (structT->opval.op == '[')
1544 lval = valForArray (structT);
1545 else if (structT->opval.op == '.')
1546 lval = valForStructElem (structT->left, structT->right);
1547 else if (structT->opval.op == PTR_OP &&
1548 IS_ADDRESS_OF_OP (structT->left))
1549 lval = valForStructElem (structT->left->left,
1555 if (!IS_AST_SYM_VALUE (elemT))
1558 if (!IS_STRUCT (structT->etype))
1561 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1562 AST_SYMBOL (elemT))) == NULL)
1569 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1571 sprintf (buffer, "%s", lval->name);
1573 sprintf (val->name, "(%s + %d)", buffer,
1576 val->type = newLink ();
1577 if (SPEC_SCLS (structT->etype) == S_CODE)
1579 DCL_TYPE (val->type) = CPOINTER;
1580 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1582 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1583 DCL_TYPE (val->type) = FPOINTER;
1584 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1585 DCL_TYPE (val->type) = PPOINTER;
1586 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1587 DCL_TYPE (val->type) = IPOINTER;
1588 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1589 DCL_TYPE (val->type) = EEPPOINTER;
1591 DCL_TYPE (val->type) = POINTER;
1592 val->type->next = sym->type;
1593 val->etype = getSpec (val->type);
1597 /*-----------------------------------------------------------------*/
1598 /* valForCastAggr - will return value for a cast of an aggregate */
1599 /* plus minus a constant */
1600 /*-----------------------------------------------------------------*/
1602 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1606 if (!IS_AST_SYM_VALUE (aexpr))
1608 if (!IS_AST_LIT_VALUE (cnst))
1613 sprintf (val->name, "(%s %c %d)",
1614 AST_SYMBOL (aexpr)->rname, op,
1615 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1618 val->etype = getSpec (val->type);
1622 /*-----------------------------------------------------------------*/
1623 /* valForCastAggr - will return value for a cast of an aggregate */
1624 /* with no constant */
1625 /*-----------------------------------------------------------------*/
1627 valForCastArr (ast * aexpr, sym_link * type)
1631 if (!IS_AST_SYM_VALUE (aexpr))
1636 sprintf (val->name, "(%s)",
1637 AST_SYMBOL (aexpr)->rname);
1640 val->etype = getSpec (val->type);