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';
456 scanFmt[scI++] = 'o';
458 scanFmt[scI++] = 'x';
460 scanFmt[scI++] = 'd';
462 scanFmt[scI++] = '\0';
464 sscanf (s, scanFmt, &sval);
466 if (sval<0) { // "-28u" will still be signed and negative
467 SPEC_USIGN (val->type) = 0;
468 if (sval<-32768) { // check if we have to promote to long
469 SPEC_NOUN (val->type) = V_INT;
470 SPEC_LONG (val->type) = 1;
471 SPEC_CVAL (val->type).v_long=sval;
473 SPEC_CVAL (val->type).v_int=sval;
474 if (sval<-128) { // check if we have to promote to int
475 SPEC_NOUN (val->type) = V_INT;
479 if (sval>0xffff) { // check if we have to promote to long
480 SPEC_NOUN (val->type) = V_INT;
481 SPEC_LONG (val->type) = 1;
482 SPEC_CVAL (val->type).v_ulong=sval;
484 SPEC_CVAL (val->type).v_uint=sval;
485 if (sval>0xff) { // check if we have to promote to int
486 SPEC_NOUN (val->type) = V_INT;
494 /*! /fn char hexEscape(char **src)
496 /param src Pointer to 'x' from start of hex character value
499 unsigned char hexEscape(char **src)
502 unsigned long value ;
504 (*src)++ ; /* Skip over the 'x' */
505 s = *src ; /* Save for error detection */
507 value = strtol (*src, src, 16);
510 // no valid hex found
511 werror(E_INVALID_HEX);
514 werror(W_ESC_SEQ_OOR_FOR_CHAR);
520 /*------------------------------------------------------------------*/
521 /* octalEscape - process an octal constant of max three digits */
522 /* return the octal value, throw a warning for illegal octal */
523 /* adjust src to point at the last proccesed char */
524 /*------------------------------------------------------------------*/
526 unsigned char octalEscape (char **str) {
530 for (digits=0; digits<3; digits++) {
531 if (**str>='0' && **str<='7') {
532 value = value*8 + (**str-'0');
539 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
540 werror (W_ESC_SEQ_OOR_FOR_CHAR);
547 /fn int copyStr (char *dest, char *src)
549 Copies a source string to a dest buffer interpreting escape sequences
550 and special characters
552 /param dest Buffer to receive the resultant string
553 /param src Buffer containing the source string with escape sequecnes
554 /return Number of characters in output string
559 copyStr (char *dest, char *src)
562 char *OriginalDest = dest ;
568 else if (*src == '\\')
603 *dest++ = octalEscape(&src);
608 *dest++ = hexEscape(&src) ;
635 return dest - OriginalDest ;
638 /*------------------------------------------------------------------*/
639 /* strVal - converts a string constant to a value */
640 /*------------------------------------------------------------------*/
646 val = newValue (); /* get a new one */
648 /* get a declarator */
649 val->type = newLink ();
650 DCL_TYPE (val->type) = ARRAY;
651 val->type->next = val->etype = newLink ();
652 val->etype->class = SPECIFIER;
653 SPEC_NOUN (val->etype) = V_CHAR;
654 SPEC_SCLS (val->etype) = S_LITERAL;
656 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
657 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
663 /*------------------------------------------------------------------*/
664 /* reverseValWithType - reverses value chain with type & etype */
665 /*------------------------------------------------------------------*/
667 reverseValWithType (value * val)
675 /* save the type * etype chains */
679 /* set the current one 2b null */
680 val->type = val->etype = NULL;
681 val = reverseVal (val);
683 /* restore type & etype */
690 /*------------------------------------------------------------------*/
691 /* reverseVal - reverses the values for a value chain */
692 /*------------------------------------------------------------------*/
694 reverseVal (value * val)
696 value *prev, *curr, *next;
711 val->next = (void *) NULL;
715 /*------------------------------------------------------------------*/
716 /* copyValueChain - will copy a chain of values */
717 /*------------------------------------------------------------------*/
719 copyValueChain (value * src)
726 dest = copyValue (src);
727 dest->next = copyValueChain (src->next);
732 /*------------------------------------------------------------------*/
733 /* copyValue - copies contents of a value to a fresh one */
734 /*------------------------------------------------------------------*/
736 copyValue (value * src)
741 dest->sym = copySymbol (src->sym);
742 strcpy (dest->name, src->name);
743 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
744 dest->etype = (src->type ? getSpec (dest->type) : NULL);
749 /*------------------------------------------------------------------*/
750 /* charVal - converts a character constant to a value */
751 /*------------------------------------------------------------------*/
760 val->type = val->etype = newLink ();
761 val->type->class = SPECIFIER;
762 SPEC_NOUN (val->type) = V_CHAR;
763 SPEC_USIGN(val->type) = 1;
764 SPEC_SCLS (val->type) = S_LITERAL;
766 s++; /* get rid of quotation */
767 /* if \ then special processing */
770 s++; /* go beyond the backslash */
774 SPEC_CVAL (val->type).v_int = '\n';
777 SPEC_CVAL (val->type).v_int = '\t';
780 SPEC_CVAL (val->type).v_int = '\v';
783 SPEC_CVAL (val->type).v_int = '\b';
786 SPEC_CVAL (val->type).v_int = '\r';
789 SPEC_CVAL (val->type).v_int = '\f';
792 SPEC_CVAL (val->type).v_int = '\a';
795 SPEC_CVAL (val->type).v_int = '\\';
798 SPEC_CVAL (val->type).v_int = '\?';
801 SPEC_CVAL (val->type).v_int = '\'';
804 SPEC_CVAL (val->type).v_int = '\"';
815 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
819 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
823 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
827 else /* not a backslash */
828 SPEC_CVAL (val->type).v_int = (unsigned char)*s;
833 /*------------------------------------------------------------------*/
834 /* valFromType - creates a value from type given */
835 /*------------------------------------------------------------------*/
837 valFromType (sym_link * type)
839 value *val = newValue ();
840 val->type = copyLinkChain (type);
841 val->etype = getSpec (val->type);
845 /*------------------------------------------------------------------*/
846 /* floatFromVal - value to unsinged integer conversion */
847 /*------------------------------------------------------------------*/
849 floatFromVal (value * val)
854 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
856 werror (E_CONST_EXPECTED, val->name);
860 /* if it is not a specifier then we can assume that */
861 /* it will be an unsigned long */
862 if (!IS_SPEC (val->type))
863 return (double) SPEC_CVAL (val->etype).v_ulong;
865 if (SPEC_NOUN (val->etype) == V_FLOAT)
866 return (double) SPEC_CVAL (val->etype).v_float;
869 if (SPEC_LONG (val->etype))
871 if (SPEC_USIGN (val->etype))
872 return (double) SPEC_CVAL (val->etype).v_ulong;
874 return (double) SPEC_CVAL (val->etype).v_long;
878 if (SPEC_USIGN (val->etype))
879 return (double) SPEC_CVAL (val->etype).v_uint;
881 return (double) SPEC_CVAL (val->etype).v_int;
887 /*------------------------------------------------------------------*/
888 /* valUnaryPM - does the unary +/- operation on a constant */
889 /*------------------------------------------------------------------*/
891 valUnaryPM (value * val)
893 /* depending on type */
894 if (SPEC_NOUN (val->etype) == V_FLOAT)
895 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
898 if (SPEC_LONG (val->etype))
900 if (SPEC_USIGN (val->etype))
901 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
903 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
907 if (SPEC_USIGN (val->etype))
908 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
910 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
916 /*------------------------------------------------------------------*/
917 /* valueComplement - complements a constant */
918 /*------------------------------------------------------------------*/
920 valComplement (value * val)
922 /* depending on type */
923 if (SPEC_LONG (val->etype))
925 if (SPEC_USIGN (val->etype))
926 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
928 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
932 if (SPEC_USIGN (val->etype))
933 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
935 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
940 /*------------------------------------------------------------------*/
941 /* valueNot - complements a constant */
942 /*------------------------------------------------------------------*/
946 /* depending on type */
947 if (SPEC_LONG (val->etype))
949 if (SPEC_USIGN (val->etype))
950 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
952 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
956 if (SPEC_USIGN (val->etype))
957 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
959 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
964 /*------------------------------------------------------------------*/
965 /* valMult - multiply constants */
966 /*------------------------------------------------------------------*/
968 valMult (value * lval, value * rval)
972 /* create a new value */
974 val->type = val->etype = newLink ();
975 val->type->class = SPECIFIER;
976 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
977 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
978 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
979 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
980 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
982 if (IS_FLOAT (val->type))
983 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
986 if (SPEC_LONG (val->type))
988 if (SPEC_USIGN (val->type))
989 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
990 (unsigned long) floatFromVal (rval);
992 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
993 (long) floatFromVal (rval);
997 if (SPEC_USIGN (val->type))
998 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
999 (unsigned) floatFromVal (rval);
1001 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1002 (int) floatFromVal (rval);
1005 return cheapestVal(val);
1008 /*------------------------------------------------------------------*/
1009 /* valDiv - Divide constants */
1010 /*------------------------------------------------------------------*/
1012 valDiv (value * lval, value * rval)
1016 if (floatFromVal (rval) == 0)
1018 werror (E_DIVIDE_BY_ZERO);
1022 /* create a new value */
1024 val->type = val->etype = newLink();
1025 val->type->class = SPECIFIER;
1026 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1027 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1028 SPEC_SCLS (val->etype) = S_LITERAL;
1029 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1030 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1032 if (IS_FLOAT (val->type))
1033 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1036 if (SPEC_LONG (val->type))
1038 if (SPEC_USIGN (val->type))
1039 SPEC_CVAL (val->type).v_ulong =
1040 (unsigned long) floatFromVal (lval) /
1041 (unsigned long) floatFromVal (rval);
1043 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1044 (long) floatFromVal (rval);
1048 if (SPEC_USIGN (val->type)) {
1049 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1050 (unsigned) floatFromVal (rval);
1052 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1053 (int) floatFromVal (rval);
1057 return cheapestVal(val);
1060 /*------------------------------------------------------------------*/
1061 /* valMod - Modulus constants */
1062 /*------------------------------------------------------------------*/
1064 valMod (value * lval, value * rval)
1068 /* create a new value */
1070 val->type = val->etype = newLink ();
1071 val->type->class = SPECIFIER;
1072 SPEC_NOUN (val->type) = V_INT; /* type is int */
1073 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1074 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1075 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1077 if (SPEC_LONG (val->type))
1079 if (SPEC_USIGN (val->type))
1080 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1081 (unsigned long) floatFromVal (rval);
1083 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1084 (unsigned long) floatFromVal (rval);
1088 if (SPEC_USIGN (val->type)) {
1089 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1090 (unsigned) floatFromVal (rval);
1092 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1093 (unsigned) floatFromVal (rval);
1097 return cheapestVal(val);
1100 /*------------------------------------------------------------------*/
1101 /* valPlus - Addition constants */
1102 /*------------------------------------------------------------------*/
1104 valPlus (value * lval, value * rval)
1108 /* create a new value */
1110 val->type = val->etype = newLink ();
1111 val->type->class = SPECIFIER;
1112 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1113 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1114 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1115 SPEC_USIGN (val->type) =
1116 SPEC_USIGN (lval->etype) &&
1117 SPEC_USIGN (rval->etype) &&
1118 (floatFromVal(lval)+floatFromVal(rval))>=0;
1120 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1122 if (IS_FLOAT (val->type))
1123 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1126 if (SPEC_LONG (val->type))
1128 if (SPEC_USIGN (val->type))
1129 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1130 (unsigned long) floatFromVal (rval);
1132 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1133 (long) floatFromVal (rval);
1137 if (SPEC_USIGN (val->type)) {
1138 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1139 (unsigned) floatFromVal (rval);
1141 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1142 (int) floatFromVal (rval);
1146 return cheapestVal(val);
1149 /*------------------------------------------------------------------*/
1150 /* valMinus - Addition constants */
1151 /*------------------------------------------------------------------*/
1153 valMinus (value * lval, value * rval)
1157 /* create a new value */
1159 val->type = val->etype = newLink ();
1160 val->type->class = SPECIFIER;
1161 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1162 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1163 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1164 SPEC_USIGN (val->type) =
1165 SPEC_USIGN (lval->etype) &&
1166 SPEC_USIGN (rval->etype) &&
1167 (floatFromVal(lval)-floatFromVal(rval))>=0;
1169 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1171 if (IS_FLOAT (val->type))
1172 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1175 if (SPEC_LONG (val->type))
1177 if (SPEC_USIGN (val->type)) {
1178 SPEC_CVAL (val->type).v_ulong =
1179 (unsigned long) floatFromVal (lval) -
1180 (unsigned long) floatFromVal (rval);
1182 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1183 (long) floatFromVal (rval);
1188 if (SPEC_USIGN (val->type)) {
1189 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1190 (unsigned) floatFromVal (rval);
1192 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1193 (int) floatFromVal (rval);
1197 return cheapestVal(val);
1200 /*------------------------------------------------------------------*/
1201 /* valShift - Shift left or right */
1202 /*------------------------------------------------------------------*/
1204 valShift (value * lval, value * rval, int lr)
1208 /* create a new value */
1210 val->type = val->etype = newIntLink ();
1211 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1212 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1213 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1215 if (SPEC_LONG (val->type))
1217 if (SPEC_USIGN (val->type))
1218 SPEC_CVAL (val->type).v_ulong = lr ?
1219 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1220 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1222 SPEC_CVAL (val->type).v_long = lr ?
1223 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1224 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1228 if (SPEC_USIGN (val->type)) {
1229 SPEC_CVAL (val->type).v_uint = lr ?
1230 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1231 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1233 SPEC_CVAL (val->type).v_int = lr ?
1234 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1235 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1239 return cheapestVal(val);
1242 /*------------------------------------------------------------------*/
1243 /* valCompare- Compares two literal */
1244 /*------------------------------------------------------------------*/
1246 valCompare (value * lval, value * rval, int ctype)
1250 /* create a new value */
1252 val->type = val->etype = newCharLink ();
1253 val->type->class = SPECIFIER;
1254 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1255 SPEC_USIGN (val->type) = 1;
1256 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1261 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1265 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1269 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1273 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1277 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1281 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1289 /*------------------------------------------------------------------*/
1290 /* valBitwise - Bitwise operation */
1291 /*------------------------------------------------------------------*/
1293 valBitwise (value * lval, value * rval, int op)
1297 /* create a new value */
1299 val->type = copyLinkChain (lval->type);
1300 val->etype = getSpec (val->type);
1305 if (SPEC_LONG (val->type))
1307 if (SPEC_USIGN (val->type))
1308 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1309 (unsigned long) floatFromVal (rval);
1311 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1312 (long) floatFromVal (rval);
1316 if (SPEC_USIGN (val->type))
1317 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1318 (unsigned) floatFromVal (rval);
1320 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1325 if (SPEC_LONG (val->type))
1327 if (SPEC_USIGN (val->type))
1328 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1329 (unsigned long) floatFromVal (rval);
1331 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1332 (long) floatFromVal (rval);
1336 if (SPEC_USIGN (val->type))
1337 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1338 (unsigned) floatFromVal (rval);
1340 SPEC_CVAL (val->type).v_int =
1341 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1347 if (SPEC_LONG (val->type))
1349 if (SPEC_USIGN (val->type))
1350 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1351 (unsigned long) floatFromVal (rval);
1353 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1354 (long) floatFromVal (rval);
1358 if (SPEC_USIGN (val->type))
1359 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1360 (unsigned) floatFromVal (rval);
1362 SPEC_CVAL (val->type).v_int =
1363 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1368 return cheapestVal(val);
1371 /*------------------------------------------------------------------*/
1372 /* valAndOr - Generates code for and / or operation */
1373 /*------------------------------------------------------------------*/
1375 valLogicAndOr (value * lval, value * rval, int op)
1379 /* create a new value */
1381 val->type = val->etype = newCharLink ();
1382 val->type->class = SPECIFIER;
1383 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1384 SPEC_USIGN (val->type) = 0;
1389 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1393 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1401 /*------------------------------------------------------------------*/
1402 /* valCastLiteral - casts a literal value to another type */
1403 /*------------------------------------------------------------------*/
1405 valCastLiteral (sym_link * dtype, double fval)
1413 val->etype = getSpec (val->type = copyLinkChain (dtype));
1414 SPEC_SCLS (val->etype) = S_LITERAL;
1415 /* if it is not a specifier then we can assume that */
1416 /* it will be an unsigned long */
1417 if (!IS_SPEC (val->type))
1419 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1423 if (SPEC_NOUN (val->etype) == V_FLOAT)
1424 SPEC_CVAL (val->etype).v_float = fval;
1427 if (SPEC_LONG (val->etype))
1429 if (SPEC_USIGN (val->etype))
1430 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1432 SPEC_CVAL (val->etype).v_long = (long) fval;
1436 if (SPEC_USIGN (val->etype))
1437 if (SPEC_NOUN (val->etype)==V_CHAR) {
1438 SPEC_CVAL (val->etype).v_uint = (unsigned char) fval;
1440 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1443 if (SPEC_NOUN (val->etype)==V_CHAR) {
1444 SPEC_CVAL (val->etype).v_int = (char) fval;
1446 SPEC_CVAL (val->etype).v_int = (int) fval;
1453 /*------------------------------------------------------------------*/
1454 /* getNelements - determines # of elements from init list */
1455 /*------------------------------------------------------------------*/
1457 getNelements (sym_link * type, initList * ilist)
1459 sym_link *etype = getSpec (type);
1465 if (ilist->type == INIT_DEEP)
1466 ilist = ilist->init.deep;
1468 /* if type is a character array and there is only one
1469 (string) initialiser then get the length of the string */
1470 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1472 ast *iast = ilist->init.node;
1473 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1476 werror (W_INIT_WRONG);
1480 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1481 // yep, it's a string
1483 return DCL_ELEM (v->type);
1491 ilist = ilist->next;
1497 /*-----------------------------------------------------------------*/
1498 /* valForArray - returns a value with name of array index */
1499 /*-----------------------------------------------------------------*/
1501 valForArray (ast * arrExpr)
1503 value *val, *lval = NULL;
1505 int size = getSize (arrExpr->left->ftype->next);
1506 /* if the right or left is an array
1508 if (IS_AST_OP (arrExpr->left))
1510 if (arrExpr->left->opval.op == '[')
1511 lval = valForArray (arrExpr->left);
1512 else if (arrExpr->left->opval.op == '.')
1513 lval = valForStructElem (arrExpr->left->left,
1514 arrExpr->left->right);
1515 else if (arrExpr->left->opval.op == PTR_OP &&
1516 IS_ADDRESS_OF_OP (arrExpr->left->left))
1517 lval = valForStructElem (arrExpr->left->left->left,
1518 arrExpr->left->right);
1523 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1526 if (!IS_AST_LIT_VALUE (arrExpr->right))
1531 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1533 sprintf (buffer, "%s", lval->name);
1535 sprintf (val->name, "(%s + %d)", buffer,
1536 (int) AST_LIT_VALUE (arrExpr->right) * size);
1538 val->type = newLink ();
1539 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1541 DCL_TYPE (val->type) = CPOINTER;
1542 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1544 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1545 DCL_TYPE (val->type) = FPOINTER;
1546 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1547 DCL_TYPE (val->type) = PPOINTER;
1548 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1549 DCL_TYPE (val->type) = IPOINTER;
1550 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1551 DCL_TYPE (val->type) = EEPPOINTER;
1553 DCL_TYPE (val->type) = POINTER;
1554 val->type->next = arrExpr->left->ftype;
1555 val->etype = getSpec (val->type);
1559 /*-----------------------------------------------------------------*/
1560 /* valForStructElem - returns value with name of struct element */
1561 /*-----------------------------------------------------------------*/
1563 valForStructElem (ast * structT, ast * elemT)
1565 value *val, *lval = NULL;
1569 /* left could be furthur derefed */
1570 if (IS_AST_OP (structT))
1572 if (structT->opval.op == '[')
1573 lval = valForArray (structT);
1574 else if (structT->opval.op == '.')
1575 lval = valForStructElem (structT->left, structT->right);
1576 else if (structT->opval.op == PTR_OP &&
1577 IS_ADDRESS_OF_OP (structT->left))
1578 lval = valForStructElem (structT->left->left,
1584 if (!IS_AST_SYM_VALUE (elemT))
1587 if (!IS_STRUCT (structT->etype))
1590 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1591 AST_SYMBOL (elemT))) == NULL)
1598 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1600 sprintf (buffer, "%s", lval->name);
1602 sprintf (val->name, "(%s + %d)", buffer,
1605 val->type = newLink ();
1606 if (SPEC_SCLS (structT->etype) == S_CODE)
1608 DCL_TYPE (val->type) = CPOINTER;
1609 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1611 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1612 DCL_TYPE (val->type) = FPOINTER;
1613 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1614 DCL_TYPE (val->type) = PPOINTER;
1615 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1616 DCL_TYPE (val->type) = IPOINTER;
1617 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1618 DCL_TYPE (val->type) = EEPPOINTER;
1620 DCL_TYPE (val->type) = POINTER;
1621 val->type->next = sym->type;
1622 val->etype = getSpec (val->type);
1626 /*-----------------------------------------------------------------*/
1627 /* valForCastAggr - will return value for a cast of an aggregate */
1628 /* plus minus a constant */
1629 /*-----------------------------------------------------------------*/
1631 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1635 if (!IS_AST_SYM_VALUE (aexpr))
1637 if (!IS_AST_LIT_VALUE (cnst))
1642 sprintf (val->name, "(%s %c %d)",
1643 AST_SYMBOL (aexpr)->rname, op,
1644 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1647 val->etype = getSpec (val->type);
1651 /*-----------------------------------------------------------------*/
1652 /* valForCastAggr - will return value for a cast of an aggregate */
1653 /* with no constant */
1654 /*-----------------------------------------------------------------*/
1656 valForCastArr (ast * aexpr, sym_link * type)
1660 if (!IS_AST_SYM_VALUE (aexpr))
1665 sprintf (val->name, "(%s)",
1666 AST_SYMBOL (aexpr)->rname);
1669 val->etype = getSpec (val->type);