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 -------------------------------------------------------------------------*/
32 #if defined(__BORLANDC__) || defined(_MSC_VER)
33 #define LONG_LONG __int64
35 #define LONG_LONG long long
40 /*-----------------------------------------------------------------*/
41 /* newValue - allocates and returns a new value */
42 /*-----------------------------------------------------------------*/
48 val = Safe_alloc (sizeof (value));
53 /*-----------------------------------------------------------------*/
54 /* newiList - new initializer list */
55 /*-----------------------------------------------------------------*/
57 newiList (int type, void *ilist)
62 nilist = Safe_alloc (sizeof (initList));
65 nilist->lineno = yylineno;
70 nilist->init.node = (struct ast *) ilist;
74 nilist->init.deep = (struct initList *) ilist;
81 /*------------------------------------------------------------------*/
82 /* revinit - reverses the initial values for a value chain */
83 /*------------------------------------------------------------------*/
85 revinit (initList * val)
87 initList *prev, *curr, *next;
102 val->next = (void *) NULL;
107 convertIListToConstList(initList *src, literalList **lList)
110 literalList *head, *last, *newL;
114 if (!src || src->type != INIT_DEEP)
119 iLoop = src->init.deep;
123 if (iLoop->type != INIT_NODE)
128 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
135 // We've now established that the initializer list contains only literal values.
137 iLoop = src->init.deep;
140 double val = AST_LIT_VALUE(iLoop->init.node);
142 if (last && last->literalValue == val)
148 newL = Safe_alloc(sizeof(literalList));
149 newL->literalValue = val;
176 copyLiteralList(literalList *src)
178 literalList *head, *prev, *newL;
184 newL = Safe_alloc(sizeof(literalList));
186 newL->literalValue = src->literalValue;
187 newL->count = src->count;
207 /*------------------------------------------------------------------*/
208 /* copyIlist - copy initializer list */
209 /*------------------------------------------------------------------*/
211 copyIlist (initList * src)
213 initList *dest = NULL;
221 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
224 dest = newiList (INIT_NODE, copyAst (src->init.node));
229 dest->next = copyIlist (src->next);
234 /*------------------------------------------------------------------*/
235 /* list2int - converts the first element of the list to value */
236 /*------------------------------------------------------------------*/
238 list2int (initList * val)
242 if (i->type == INIT_DEEP)
243 return list2int (val->init.deep);
245 return floatFromVal (constExprValue (val->init.node, TRUE));
248 /*------------------------------------------------------------------*/
249 /* list2val - converts the first element of the list to value */
250 /*------------------------------------------------------------------*/
252 list2val (initList * val)
257 if (val->type == INIT_DEEP)
258 return list2val (val->init.deep);
260 return constExprValue (val->init.node, TRUE);
263 /*------------------------------------------------------------------*/
264 /* list2expr - returns the first expression in the initializer list */
265 /*------------------------------------------------------------------*/
267 list2expr (initList * ilist)
269 if (ilist->type == INIT_DEEP)
270 return list2expr (ilist->init.deep);
271 return ilist->init.node;
274 /*------------------------------------------------------------------*/
275 /* resolveIvalSym - resolve symbols in initial values */
276 /*------------------------------------------------------------------*/
278 resolveIvalSym (initList * ilist)
283 if (ilist->type == INIT_NODE)
284 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
286 if (ilist->type == INIT_DEEP)
287 resolveIvalSym (ilist->init.deep);
289 resolveIvalSym (ilist->next);
292 /*-----------------------------------------------------------------*/
293 /* symbolVal - creates a value for a symbol */
294 /*-----------------------------------------------------------------*/
296 symbolVal (symbol * sym)
308 val->type = sym->type;
309 val->etype = getSpec (val->type);
313 sprintf (val->name, "%s", sym->rname);
315 sprintf (val->name, "_%s", sym->name);
321 /*--------------------------------------------------------------------*/
322 /* cheapestVal - convert a val to the cheapest as possible value */
323 /*--------------------------------------------------------------------*/
324 value *cheapestVal (value *val) {
326 unsigned long uval=0;
328 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
331 if (SPEC_LONG(val->type)) {
332 if (SPEC_USIGN(val->type)) {
333 uval=SPEC_CVAL(val->type).v_ulong;
335 sval=SPEC_CVAL(val->type).v_long;
338 if (SPEC_USIGN(val->type)) {
339 uval=SPEC_CVAL(val->type).v_uint;
341 sval=SPEC_CVAL(val->type).v_int;
345 if (SPEC_USIGN(val->type)) {
347 SPEC_NOUN(val->type)=V_CHAR;
348 SPEC_LONG(val->type)=0;
351 SPEC_LONG(val->type)=0;
357 SPEC_NOUN(val->type)=V_CHAR;
358 SPEC_LONG(val->type)=0;
361 SPEC_LONG(val->type)=0;
366 SPEC_NOUN(val->type)=V_CHAR;
367 SPEC_LONG(val->type)=0;
370 SPEC_LONG(val->type)=0;
378 /*-----------------------------------------------------------------*/
379 /* valueFromLit - creates a value from a literal */
380 /*-----------------------------------------------------------------*/
382 valueFromLit (double lit)
386 if ((((long) lit) - lit) == 0)
388 sprintf (buffer, "%ld", (long) lit);
389 return constVal (buffer);
392 sprintf (buffer, "%f", lit);
393 return constFloatVal (buffer);
396 /*-----------------------------------------------------------------*/
397 /* constFloatVal - converts a FLOAT constant to value */
398 /*-----------------------------------------------------------------*/
400 constFloatVal (char *s)
402 value *val = newValue ();
405 if (sscanf (s, "%lf", &sval) != 1)
407 werror (E_INVALID_FLOAT_CONST, s);
408 return constVal ("0");
411 val->type = val->etype = newLink ();
412 val->type->class = SPECIFIER;
413 SPEC_NOUN (val->type) = V_FLOAT;
414 SPEC_SCLS (val->type) = S_LITERAL;
415 SPEC_CVAL (val->type).v_float = sval;
420 /*-----------------------------------------------------------------*/
421 /* constVal - converts an INTEGER constant into a cheapest value */
422 /*-----------------------------------------------------------------*/
423 value *constVal (char *s)
426 short hex = 0, octal = 0;
431 val = newValue (); /* alloc space for value */
433 val->type = val->etype = newLink (); /* create the spcifier */
434 val->type->class = SPECIFIER;
435 SPEC_SCLS (val->type) = S_LITERAL;
436 // let's start with an unsigned char
437 SPEC_NOUN (val->type) = V_CHAR;
438 SPEC_USIGN (val->type) = 1;
440 /* set the _long flag if 'lL' is found */
441 if (strchr (s, 'l') || strchr (s, 'L'))
442 SPEC_LONG (val->type) = 1;
444 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
446 /* set the octal flag */
447 if (!hex && *s == '0' && *(s + 1))
450 /* create the scan string */
451 scanFmt[scI++] = '%';
453 scanFmt[scI++] = 'l';
454 scanFmt[scI++] = 'l';
457 scanFmt[scI++] = 'o';
459 scanFmt[scI++] = 'x';
461 scanFmt[scI++] = 'd';
463 scanFmt[scI++] = '\0';
465 sscanf (s, scanFmt, &sval);
467 if (sval<0) { // "-28u" will still be signed and negative
468 SPEC_USIGN (val->type) = 0;
469 if (sval<-32768) { // check if we have to promote to long
470 SPEC_NOUN (val->type) = V_INT;
471 SPEC_LONG (val->type) = 1;
472 SPEC_CVAL (val->type).v_long=sval;
474 SPEC_CVAL (val->type).v_int=sval;
475 if (sval<-128) { // check if we have to promote to int
476 SPEC_NOUN (val->type) = V_INT;
480 if (sval>0xffff) { // check if we have to promote to long
481 SPEC_NOUN (val->type) = V_INT;
482 SPEC_LONG (val->type) = 1;
483 SPEC_CVAL (val->type).v_ulong=sval;
485 SPEC_CVAL (val->type).v_uint=sval;
486 if (sval>0xff) { // check if we have to promote to int
487 SPEC_NOUN (val->type) = V_INT;
495 /*! /fn char hexEscape(char **src)
497 /param src Pointer to 'x' from start of hex character value
500 unsigned char hexEscape(char **src)
503 unsigned long value ;
505 (*src)++ ; /* Skip over the 'x' */
506 s = *src ; /* Save for error detection */
508 value = strtol (*src, src, 16);
511 // no valid hex found
512 werror(E_INVALID_HEX);
515 werror(W_ESC_SEQ_OOR_FOR_CHAR);
521 /*------------------------------------------------------------------*/
522 /* octalEscape - process an octal constant of max three digits */
523 /* return the octal value, throw a warning for illegal octal */
524 /* adjust src to point at the last proccesed char */
525 /*------------------------------------------------------------------*/
527 unsigned char octalEscape (char **str) {
531 for (digits=0; digits<3; digits++) {
532 if (**str>='0' && **str<='7') {
533 value = value*8 + (**str-'0');
540 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
541 werror (W_ESC_SEQ_OOR_FOR_CHAR);
548 /fn int copyStr (char *dest, char *src)
550 Copies a source string to a dest buffer interpreting escape sequences
551 and special characters
553 /param dest Buffer to receive the resultant string
554 /param src Buffer containing the source string with escape sequecnes
555 /return Number of characters in output string
560 copyStr (char *dest, char *src)
563 char *OriginalDest = dest ;
569 else if (*src == '\\')
604 *dest++ = octalEscape(&src);
609 *dest++ = hexEscape(&src) ;
636 return dest - OriginalDest ;
639 /*------------------------------------------------------------------*/
640 /* strVal - converts a string constant to a value */
641 /*------------------------------------------------------------------*/
647 val = newValue (); /* get a new one */
649 /* get a declarator */
650 val->type = newLink ();
651 DCL_TYPE (val->type) = ARRAY;
652 val->type->next = val->etype = newLink ();
653 val->etype->class = SPECIFIER;
654 SPEC_NOUN (val->etype) = V_CHAR;
655 SPEC_SCLS (val->etype) = S_LITERAL;
657 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
658 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
664 /*------------------------------------------------------------------*/
665 /* reverseValWithType - reverses value chain with type & etype */
666 /*------------------------------------------------------------------*/
668 reverseValWithType (value * val)
676 /* save the type * etype chains */
680 /* set the current one 2b null */
681 val->type = val->etype = NULL;
682 val = reverseVal (val);
684 /* restore type & etype */
691 /*------------------------------------------------------------------*/
692 /* reverseVal - reverses the values for a value chain */
693 /*------------------------------------------------------------------*/
695 reverseVal (value * val)
697 value *prev, *curr, *next;
712 val->next = (void *) NULL;
716 /*------------------------------------------------------------------*/
717 /* copyValueChain - will copy a chain of values */
718 /*------------------------------------------------------------------*/
720 copyValueChain (value * src)
727 dest = copyValue (src);
728 dest->next = copyValueChain (src->next);
733 /*------------------------------------------------------------------*/
734 /* copyValue - copies contents of a value to a fresh one */
735 /*------------------------------------------------------------------*/
737 copyValue (value * src)
742 dest->sym = copySymbol (src->sym);
743 strcpy (dest->name, src->name);
744 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
745 dest->etype = (src->type ? getSpec (dest->type) : NULL);
750 /*------------------------------------------------------------------*/
751 /* charVal - converts a character constant to a value */
752 /*------------------------------------------------------------------*/
761 val->type = val->etype = newLink ();
762 val->type->class = SPECIFIER;
763 SPEC_NOUN (val->type) = V_CHAR;
764 SPEC_USIGN(val->type) = 1;
765 SPEC_SCLS (val->type) = S_LITERAL;
767 s++; /* get rid of quotation */
768 /* if \ then special processing */
771 s++; /* go beyond the backslash */
775 SPEC_CVAL (val->type).v_int = '\n';
778 SPEC_CVAL (val->type).v_int = '\t';
781 SPEC_CVAL (val->type).v_int = '\v';
784 SPEC_CVAL (val->type).v_int = '\b';
787 SPEC_CVAL (val->type).v_int = '\r';
790 SPEC_CVAL (val->type).v_int = '\f';
793 SPEC_CVAL (val->type).v_int = '\a';
796 SPEC_CVAL (val->type).v_int = '\\';
799 SPEC_CVAL (val->type).v_int = '\?';
802 SPEC_CVAL (val->type).v_int = '\'';
805 SPEC_CVAL (val->type).v_int = '\"';
816 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
820 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
824 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
828 else /* not a backslash */
829 SPEC_CVAL (val->type).v_int = (unsigned char)*s;
834 /*------------------------------------------------------------------*/
835 /* valFromType - creates a value from type given */
836 /*------------------------------------------------------------------*/
838 valFromType (sym_link * type)
840 value *val = newValue ();
841 val->type = copyLinkChain (type);
842 val->etype = getSpec (val->type);
846 /*------------------------------------------------------------------*/
847 /* floatFromVal - value to unsinged integer conversion */
848 /*------------------------------------------------------------------*/
850 floatFromVal (value * val)
855 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
857 werror (E_CONST_EXPECTED, val->name);
861 /* if it is not a specifier then we can assume that */
862 /* it will be an unsigned long */
863 if (!IS_SPEC (val->type))
864 return (double) SPEC_CVAL (val->etype).v_ulong;
866 if (SPEC_NOUN (val->etype) == V_FLOAT)
867 return (double) SPEC_CVAL (val->etype).v_float;
870 if (SPEC_LONG (val->etype))
872 if (SPEC_USIGN (val->etype))
873 return (double) SPEC_CVAL (val->etype).v_ulong;
875 return (double) SPEC_CVAL (val->etype).v_long;
879 if (SPEC_USIGN (val->etype))
880 return (double) SPEC_CVAL (val->etype).v_uint;
882 return (double) SPEC_CVAL (val->etype).v_int;
888 /*------------------------------------------------------------------*/
889 /* valUnaryPM - does the unary +/- operation on a constant */
890 /*------------------------------------------------------------------*/
892 valUnaryPM (value * val)
894 /* depending on type */
895 if (SPEC_NOUN (val->etype) == V_FLOAT)
896 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
899 if (SPEC_LONG (val->etype))
901 if (SPEC_USIGN (val->etype))
902 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
904 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
908 if (SPEC_USIGN (val->etype))
909 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
911 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
917 /*------------------------------------------------------------------*/
918 /* valueComplement - complements a constant */
919 /*------------------------------------------------------------------*/
921 valComplement (value * val)
923 /* depending on type */
924 if (SPEC_LONG (val->etype))
926 if (SPEC_USIGN (val->etype))
927 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
929 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
933 if (SPEC_USIGN (val->etype))
934 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
936 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
941 /*------------------------------------------------------------------*/
942 /* valueNot - complements a constant */
943 /*------------------------------------------------------------------*/
947 /* depending on type */
948 if (SPEC_LONG (val->etype))
950 if (SPEC_USIGN (val->etype))
951 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
953 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
957 if (SPEC_USIGN (val->etype))
958 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
960 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
965 /*------------------------------------------------------------------*/
966 /* valMult - multiply constants */
967 /*------------------------------------------------------------------*/
969 valMult (value * lval, value * rval)
973 /* create a new value */
975 val->type = val->etype = newLink ();
976 val->type->class = SPECIFIER;
977 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
978 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
979 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
980 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
981 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
983 if (IS_FLOAT (val->type))
984 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
987 if (SPEC_LONG (val->type))
989 if (SPEC_USIGN (val->type))
990 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
991 (unsigned long) floatFromVal (rval);
993 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
994 (long) floatFromVal (rval);
998 if (SPEC_USIGN (val->type))
999 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1000 (unsigned) floatFromVal (rval);
1002 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1003 (int) floatFromVal (rval);
1006 return cheapestVal(val);
1009 /*------------------------------------------------------------------*/
1010 /* valDiv - Divide constants */
1011 /*------------------------------------------------------------------*/
1013 valDiv (value * lval, value * rval)
1017 if (floatFromVal (rval) == 0)
1019 werror (E_DIVIDE_BY_ZERO);
1023 /* create a new value */
1025 val->type = val->etype = newLink();
1026 val->type->class = SPECIFIER;
1027 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1028 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1029 SPEC_SCLS (val->etype) = S_LITERAL;
1030 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1031 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1033 if (IS_FLOAT (val->type))
1034 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1037 if (SPEC_LONG (val->type))
1039 if (SPEC_USIGN (val->type))
1040 SPEC_CVAL (val->type).v_ulong =
1041 (unsigned long) floatFromVal (lval) /
1042 (unsigned long) floatFromVal (rval);
1044 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1045 (long) floatFromVal (rval);
1049 if (SPEC_USIGN (val->type)) {
1050 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1051 (unsigned) floatFromVal (rval);
1053 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1054 (int) floatFromVal (rval);
1058 return cheapestVal(val);
1061 /*------------------------------------------------------------------*/
1062 /* valMod - Modulus constants */
1063 /*------------------------------------------------------------------*/
1065 valMod (value * lval, value * rval)
1069 /* create a new value */
1071 val->type = val->etype = newLink ();
1072 val->type->class = SPECIFIER;
1073 SPEC_NOUN (val->type) = V_INT; /* type is int */
1074 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1075 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1076 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1078 if (SPEC_LONG (val->type))
1080 if (SPEC_USIGN (val->type))
1081 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1082 (unsigned long) floatFromVal (rval);
1084 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1085 (unsigned long) floatFromVal (rval);
1089 if (SPEC_USIGN (val->type)) {
1090 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1091 (unsigned) floatFromVal (rval);
1093 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1094 (unsigned) floatFromVal (rval);
1098 return cheapestVal(val);
1101 /*------------------------------------------------------------------*/
1102 /* valPlus - Addition constants */
1103 /*------------------------------------------------------------------*/
1105 valPlus (value * lval, value * rval)
1109 /* create a new value */
1111 val->type = val->etype = newLink ();
1112 val->type->class = SPECIFIER;
1113 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1114 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1115 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1116 SPEC_USIGN (val->type) =
1117 SPEC_USIGN (lval->etype) &&
1118 SPEC_USIGN (rval->etype) &&
1119 (floatFromVal(lval)+floatFromVal(rval))>=0;
1121 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1123 if (IS_FLOAT (val->type))
1124 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1127 if (SPEC_LONG (val->type))
1129 if (SPEC_USIGN (val->type))
1130 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1131 (unsigned long) floatFromVal (rval);
1133 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1134 (long) floatFromVal (rval);
1138 if (SPEC_USIGN (val->type)) {
1139 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1140 (unsigned) floatFromVal (rval);
1142 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1143 (int) floatFromVal (rval);
1147 return cheapestVal(val);
1150 /*------------------------------------------------------------------*/
1151 /* valMinus - Addition constants */
1152 /*------------------------------------------------------------------*/
1154 valMinus (value * lval, value * rval)
1158 /* create a new value */
1160 val->type = val->etype = newLink ();
1161 val->type->class = SPECIFIER;
1162 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1163 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1164 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1165 SPEC_USIGN (val->type) =
1166 SPEC_USIGN (lval->etype) &&
1167 SPEC_USIGN (rval->etype) &&
1168 (floatFromVal(lval)-floatFromVal(rval))>=0;
1170 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1172 if (IS_FLOAT (val->type))
1173 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1176 if (SPEC_LONG (val->type))
1178 if (SPEC_USIGN (val->type)) {
1179 SPEC_CVAL (val->type).v_ulong =
1180 (unsigned long) floatFromVal (lval) -
1181 (unsigned long) floatFromVal (rval);
1183 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1184 (long) floatFromVal (rval);
1189 if (SPEC_USIGN (val->type)) {
1190 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1191 (unsigned) floatFromVal (rval);
1193 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1194 (int) floatFromVal (rval);
1198 return cheapestVal(val);
1201 /*------------------------------------------------------------------*/
1202 /* valShift - Shift left or right */
1203 /*------------------------------------------------------------------*/
1205 valShift (value * lval, value * rval, int lr)
1209 /* create a new value */
1211 val->type = val->etype = newIntLink ();
1212 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1213 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1214 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1216 if (SPEC_LONG (val->type))
1218 if (SPEC_USIGN (val->type))
1219 SPEC_CVAL (val->type).v_ulong = lr ?
1220 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1221 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1223 SPEC_CVAL (val->type).v_long = lr ?
1224 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1225 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1229 if (SPEC_USIGN (val->type)) {
1230 SPEC_CVAL (val->type).v_uint = lr ?
1231 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1232 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1234 SPEC_CVAL (val->type).v_int = lr ?
1235 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1236 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1240 return cheapestVal(val);
1243 /*------------------------------------------------------------------*/
1244 /* valCompare- Compares two literal */
1245 /*------------------------------------------------------------------*/
1247 valCompare (value * lval, value * rval, int ctype)
1251 /* create a new value */
1253 val->type = val->etype = newCharLink ();
1254 val->type->class = SPECIFIER;
1255 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1256 SPEC_USIGN (val->type) = 1;
1257 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1262 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1266 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1270 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1274 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1278 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1282 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1290 /*------------------------------------------------------------------*/
1291 /* valBitwise - Bitwise operation */
1292 /*------------------------------------------------------------------*/
1294 valBitwise (value * lval, value * rval, int op)
1298 /* create a new value */
1300 val->type = copyLinkChain (lval->type);
1301 val->etype = getSpec (val->type);
1306 if (SPEC_LONG (val->type))
1308 if (SPEC_USIGN (val->type))
1309 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1310 (unsigned long) floatFromVal (rval);
1312 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1313 (long) floatFromVal (rval);
1317 if (SPEC_USIGN (val->type))
1318 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1319 (unsigned) floatFromVal (rval);
1321 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1326 if (SPEC_LONG (val->type))
1328 if (SPEC_USIGN (val->type))
1329 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1330 (unsigned long) floatFromVal (rval);
1332 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1333 (long) floatFromVal (rval);
1337 if (SPEC_USIGN (val->type))
1338 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1339 (unsigned) floatFromVal (rval);
1341 SPEC_CVAL (val->type).v_int =
1342 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1348 if (SPEC_LONG (val->type))
1350 if (SPEC_USIGN (val->type))
1351 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1352 (unsigned long) floatFromVal (rval);
1354 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1355 (long) floatFromVal (rval);
1359 if (SPEC_USIGN (val->type))
1360 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1361 (unsigned) floatFromVal (rval);
1363 SPEC_CVAL (val->type).v_int =
1364 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1369 return cheapestVal(val);
1372 /*------------------------------------------------------------------*/
1373 /* valAndOr - Generates code for and / or operation */
1374 /*------------------------------------------------------------------*/
1376 valLogicAndOr (value * lval, value * rval, int op)
1380 /* create a new value */
1382 val->type = val->etype = newCharLink ();
1383 val->type->class = SPECIFIER;
1384 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1385 SPEC_USIGN (val->type) = 0;
1390 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1394 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1402 /*------------------------------------------------------------------*/
1403 /* valCastLiteral - casts a literal value to another type */
1404 /*------------------------------------------------------------------*/
1406 valCastLiteral (sym_link * dtype, double fval)
1414 val->etype = getSpec (val->type = copyLinkChain (dtype));
1415 SPEC_SCLS (val->etype) = S_LITERAL;
1416 /* if it is not a specifier then we can assume that */
1417 /* it will be an unsigned long */
1418 if (!IS_SPEC (val->type))
1420 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1424 if (SPEC_NOUN (val->etype) == V_FLOAT)
1425 SPEC_CVAL (val->etype).v_float = fval;
1428 if (SPEC_LONG (val->etype))
1430 if (SPEC_USIGN (val->etype))
1431 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1433 SPEC_CVAL (val->etype).v_long = (long) fval;
1437 if (SPEC_USIGN (val->etype))
1438 if (SPEC_NOUN (val->etype)==V_CHAR) {
1439 SPEC_CVAL (val->etype).v_uint = (unsigned char)fval;
1441 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1444 if (SPEC_NOUN (val->etype)==V_CHAR) {
1445 SPEC_CVAL (val->etype).v_int = (char)fval;
1447 SPEC_CVAL (val->etype).v_int = (short)fval;
1454 /*------------------------------------------------------------------*/
1455 /* getNelements - determines # of elements from init list */
1456 /*------------------------------------------------------------------*/
1458 getNelements (sym_link * type, initList * ilist)
1460 sym_link *etype = getSpec (type);
1466 if (ilist->type == INIT_DEEP)
1467 ilist = ilist->init.deep;
1469 /* if type is a character array and there is only one
1470 (string) initialiser then get the length of the string */
1471 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1473 ast *iast = ilist->init.node;
1474 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1477 werror (W_INIT_WRONG);
1481 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1482 // yep, it's a string
1484 return DCL_ELEM (v->type);
1492 ilist = ilist->next;
1498 /*-----------------------------------------------------------------*/
1499 /* valForArray - returns a value with name of array index */
1500 /*-----------------------------------------------------------------*/
1502 valForArray (ast * arrExpr)
1504 value *val, *lval = NULL;
1506 int size = getSize (arrExpr->left->ftype->next);
1507 /* if the right or left is an array
1509 if (IS_AST_OP (arrExpr->left))
1511 if (arrExpr->left->opval.op == '[')
1512 lval = valForArray (arrExpr->left);
1513 else if (arrExpr->left->opval.op == '.')
1514 lval = valForStructElem (arrExpr->left->left,
1515 arrExpr->left->right);
1516 else if (arrExpr->left->opval.op == PTR_OP &&
1517 IS_ADDRESS_OF_OP (arrExpr->left->left))
1518 lval = valForStructElem (arrExpr->left->left->left,
1519 arrExpr->left->right);
1524 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1527 if (!IS_AST_LIT_VALUE (arrExpr->right))
1532 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1534 sprintf (buffer, "%s", lval->name);
1536 sprintf (val->name, "(%s + %d)", buffer,
1537 (int) AST_LIT_VALUE (arrExpr->right) * size);
1539 val->type = newLink ();
1540 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1542 DCL_TYPE (val->type) = CPOINTER;
1543 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1545 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1546 DCL_TYPE (val->type) = FPOINTER;
1547 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1548 DCL_TYPE (val->type) = PPOINTER;
1549 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1550 DCL_TYPE (val->type) = IPOINTER;
1551 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1552 DCL_TYPE (val->type) = EEPPOINTER;
1554 DCL_TYPE (val->type) = POINTER;
1555 val->type->next = arrExpr->left->ftype;
1556 val->etype = getSpec (val->type);
1560 /*-----------------------------------------------------------------*/
1561 /* valForStructElem - returns value with name of struct element */
1562 /*-----------------------------------------------------------------*/
1564 valForStructElem (ast * structT, ast * elemT)
1566 value *val, *lval = NULL;
1570 /* left could be furthur derefed */
1571 if (IS_AST_OP (structT))
1573 if (structT->opval.op == '[')
1574 lval = valForArray (structT);
1575 else if (structT->opval.op == '.')
1576 lval = valForStructElem (structT->left, structT->right);
1577 else if (structT->opval.op == PTR_OP &&
1578 IS_ADDRESS_OF_OP (structT->left))
1579 lval = valForStructElem (structT->left->left,
1585 if (!IS_AST_SYM_VALUE (elemT))
1588 if (!IS_STRUCT (structT->etype))
1591 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1592 AST_SYMBOL (elemT))) == NULL)
1599 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1601 sprintf (buffer, "%s", lval->name);
1603 sprintf (val->name, "(%s + %d)", buffer,
1606 val->type = newLink ();
1607 if (SPEC_SCLS (structT->etype) == S_CODE)
1609 DCL_TYPE (val->type) = CPOINTER;
1610 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1612 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1613 DCL_TYPE (val->type) = FPOINTER;
1614 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1615 DCL_TYPE (val->type) = PPOINTER;
1616 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1617 DCL_TYPE (val->type) = IPOINTER;
1618 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1619 DCL_TYPE (val->type) = EEPPOINTER;
1621 DCL_TYPE (val->type) = POINTER;
1622 val->type->next = sym->type;
1623 val->etype = getSpec (val->type);
1627 /*-----------------------------------------------------------------*/
1628 /* valForCastAggr - will return value for a cast of an aggregate */
1629 /* plus minus a constant */
1630 /*-----------------------------------------------------------------*/
1632 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1636 if (!IS_AST_SYM_VALUE (aexpr))
1638 if (!IS_AST_LIT_VALUE (cnst))
1643 sprintf (val->name, "(%s %c %d)",
1644 AST_SYMBOL (aexpr)->rname, op,
1645 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1648 val->etype = getSpec (val->type);
1652 /*-----------------------------------------------------------------*/
1653 /* valForCastAggr - will return value for a cast of an aggregate */
1654 /* with no constant */
1655 /*-----------------------------------------------------------------*/
1657 valForCastArr (ast * aexpr, sym_link * type)
1661 if (!IS_AST_SYM_VALUE (aexpr))
1666 sprintf (val->name, "(%s)",
1667 AST_SYMBOL (aexpr)->rname);
1670 val->etype = getSpec (val->type);