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 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);
512 // no valid hex found
513 werror(E_INVALID_HEX);
520 werror(W_ESC_SEQ_OOR_FOR_CHAR);
526 /*------------------------------------------------------------------*/
527 /* octalEscape - process an octal constant of max three digits */
528 /* return the octal value, throw a warning for illegal octal */
529 /* adjust src to point at the last proccesed char */
530 /*------------------------------------------------------------------*/
532 char octalEscape (char **str) {
536 for (digits=0; digits<3; digits++) {
537 if (**str>='0' && **str<='7') {
538 value = value*8 + (**str-'0');
545 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
546 werror (W_ESC_SEQ_OOR_FOR_CHAR);
553 /fn int copyStr (char *dest, char *src)
555 Copies a source string to a dest buffer interpreting escape sequences
556 and special characters
558 /param dest Buffer to receive the resultant string
559 /param src Buffer containing the source string with escape sequecnes
560 /return Number of characters in output string
565 copyStr (char *dest, char *src)
568 char *OriginalDest = dest ;
574 else if (*src == '\\')
609 *dest++ = octalEscape(&src);
614 *dest++ = hexEscape(&src) ;
641 return dest - OriginalDest ;
644 /*------------------------------------------------------------------*/
645 /* strVal - converts a string constant to a value */
646 /*------------------------------------------------------------------*/
652 val = newValue (); /* get a new one */
654 /* get a declarator */
655 val->type = newLink ();
656 DCL_TYPE (val->type) = ARRAY;
657 val->type->next = val->etype = newLink ();
658 val->etype->class = SPECIFIER;
659 SPEC_NOUN (val->etype) = V_CHAR;
660 SPEC_SCLS (val->etype) = S_LITERAL;
662 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
663 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
669 /*------------------------------------------------------------------*/
670 /* reverseValWithType - reverses value chain with type & etype */
671 /*------------------------------------------------------------------*/
673 reverseValWithType (value * val)
681 /* save the type * etype chains */
685 /* set the current one 2b null */
686 val->type = val->etype = NULL;
687 val = reverseVal (val);
689 /* restore type & etype */
696 /*------------------------------------------------------------------*/
697 /* reverseVal - reverses the values for a value chain */
698 /*------------------------------------------------------------------*/
700 reverseVal (value * val)
702 value *prev, *curr, *next;
717 val->next = (void *) NULL;
721 /*------------------------------------------------------------------*/
722 /* copyValueChain - will copy a chain of values */
723 /*------------------------------------------------------------------*/
725 copyValueChain (value * src)
732 dest = copyValue (src);
733 dest->next = copyValueChain (src->next);
738 /*------------------------------------------------------------------*/
739 /* copyValue - copies contents of a value to a fresh one */
740 /*------------------------------------------------------------------*/
742 copyValue (value * src)
747 dest->sym = copySymbol (src->sym);
748 strcpy (dest->name, src->name);
749 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
750 dest->etype = (src->type ? getSpec (dest->type) : NULL);
755 /*------------------------------------------------------------------*/
756 /* charVal - converts a character constant to a value */
757 /*------------------------------------------------------------------*/
766 val->type = val->etype = newLink ();
767 val->type->class = SPECIFIER;
768 SPEC_NOUN (val->type) = V_CHAR;
769 SPEC_USIGN(val->type) = 1;
770 SPEC_SCLS (val->type) = S_LITERAL;
772 s++; /* get rid of quotation */
773 /* if \ then special processing */
776 s++; /* go beyond the backslash */
780 SPEC_CVAL (val->type).v_int = '\n';
783 SPEC_CVAL (val->type).v_int = '\t';
786 SPEC_CVAL (val->type).v_int = '\v';
789 SPEC_CVAL (val->type).v_int = '\b';
792 SPEC_CVAL (val->type).v_int = '\r';
795 SPEC_CVAL (val->type).v_int = '\f';
798 SPEC_CVAL (val->type).v_int = '\a';
801 SPEC_CVAL (val->type).v_int = '\\';
804 SPEC_CVAL (val->type).v_int = '\?';
807 SPEC_CVAL (val->type).v_int = '\'';
810 SPEC_CVAL (val->type).v_int = '\"';
821 SPEC_CVAL (val->type).v_int = octalEscape(&s);
825 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
829 SPEC_CVAL (val->type).v_int = *s;
833 else /* not a backslash */
834 SPEC_CVAL (val->type).v_int = *s;
839 /*------------------------------------------------------------------*/
840 /* valFromType - creates a value from type given */
841 /*------------------------------------------------------------------*/
843 valFromType (sym_link * type)
845 value *val = newValue ();
846 val->type = copyLinkChain (type);
847 val->etype = getSpec (val->type);
851 /*------------------------------------------------------------------*/
852 /* floatFromVal - value to unsinged integer conversion */
853 /*------------------------------------------------------------------*/
855 floatFromVal (value * val)
860 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
862 werror (E_CONST_EXPECTED, val->name);
866 /* if it is not a specifier then we can assume that */
867 /* it will be an unsigned long */
868 if (!IS_SPEC (val->type))
869 return (double) SPEC_CVAL (val->etype).v_ulong;
871 if (SPEC_NOUN (val->etype) == V_FLOAT)
872 return (double) SPEC_CVAL (val->etype).v_float;
875 if (SPEC_LONG (val->etype))
877 if (SPEC_USIGN (val->etype))
878 return (double) SPEC_CVAL (val->etype).v_ulong;
880 return (double) SPEC_CVAL (val->etype).v_long;
884 if (SPEC_USIGN (val->etype))
885 return (double) SPEC_CVAL (val->etype).v_uint;
887 return (double) SPEC_CVAL (val->etype).v_int;
893 /*------------------------------------------------------------------*/
894 /* valUnaryPM - does the unary +/- operation on a constant */
895 /*------------------------------------------------------------------*/
897 valUnaryPM (value * val)
899 /* depending on type */
900 if (SPEC_NOUN (val->etype) == V_FLOAT)
901 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
904 if (SPEC_LONG (val->etype))
906 if (SPEC_USIGN (val->etype))
907 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
909 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
913 if (SPEC_USIGN (val->etype))
914 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
916 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
922 /*------------------------------------------------------------------*/
923 /* valueComplement - complements a constant */
924 /*------------------------------------------------------------------*/
926 valComplement (value * val)
928 /* depending on type */
929 if (SPEC_LONG (val->etype))
931 if (SPEC_USIGN (val->etype))
932 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
934 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
938 if (SPEC_USIGN (val->etype))
939 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
941 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
946 /*------------------------------------------------------------------*/
947 /* valueNot - complements a constant */
948 /*------------------------------------------------------------------*/
952 /* depending on type */
953 if (SPEC_LONG (val->etype))
955 if (SPEC_USIGN (val->etype))
956 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
958 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
962 if (SPEC_USIGN (val->etype))
963 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
965 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
970 /*------------------------------------------------------------------*/
971 /* valMult - multiply constants */
972 /*------------------------------------------------------------------*/
974 valMult (value * lval, value * rval)
978 /* create a new value */
980 val->type = val->etype = newLink ();
981 val->type->class = SPECIFIER;
982 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
983 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
984 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
985 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
986 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
988 if (IS_FLOAT (val->type))
989 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
992 if (SPEC_LONG (val->type))
994 if (SPEC_USIGN (val->type))
995 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
996 (unsigned long) floatFromVal (rval);
998 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
999 (long) floatFromVal (rval);
1003 if (SPEC_USIGN (val->type))
1004 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1005 (unsigned) floatFromVal (rval);
1007 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1008 (int) floatFromVal (rval);
1011 return cheapestVal(val);
1014 /*------------------------------------------------------------------*/
1015 /* valDiv - Divide constants */
1016 /*------------------------------------------------------------------*/
1018 valDiv (value * lval, value * rval)
1022 if (floatFromVal (rval) == 0)
1024 werror (E_DIVIDE_BY_ZERO);
1028 /* create a new value */
1030 val->type = val->etype = newLink();
1031 val->type->class = SPECIFIER;
1032 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1033 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1034 SPEC_SCLS (val->etype) = S_LITERAL;
1035 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1036 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1038 if (IS_FLOAT (val->type))
1039 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1042 if (SPEC_LONG (val->type))
1044 if (SPEC_USIGN (val->type))
1045 SPEC_CVAL (val->type).v_ulong =
1046 (unsigned long) floatFromVal (lval) /
1047 (unsigned long) floatFromVal (rval);
1049 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1050 (long) floatFromVal (rval);
1054 if (SPEC_USIGN (val->type)) {
1055 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1056 (unsigned) floatFromVal (rval);
1058 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1059 (int) floatFromVal (rval);
1063 return cheapestVal(val);
1066 /*------------------------------------------------------------------*/
1067 /* valMod - Modulus constants */
1068 /*------------------------------------------------------------------*/
1070 valMod (value * lval, value * rval)
1074 /* create a new value */
1076 val->type = val->etype = newLink ();
1077 val->type->class = SPECIFIER;
1078 SPEC_NOUN (val->type) = V_INT; /* type is int */
1079 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1080 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1081 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1083 if (SPEC_LONG (val->type))
1085 if (SPEC_USIGN (val->type))
1086 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1087 (unsigned long) floatFromVal (rval);
1089 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1090 (unsigned long) floatFromVal (rval);
1094 if (SPEC_USIGN (val->type)) {
1095 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1096 (unsigned) floatFromVal (rval);
1098 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1099 (unsigned) floatFromVal (rval);
1103 return cheapestVal(val);
1106 /*------------------------------------------------------------------*/
1107 /* valPlus - Addition constants */
1108 /*------------------------------------------------------------------*/
1110 valPlus (value * lval, value * rval)
1114 /* create a new value */
1116 val->type = val->etype = newLink ();
1117 val->type->class = SPECIFIER;
1118 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1119 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1120 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1121 SPEC_USIGN (val->type) =
1122 SPEC_USIGN (lval->etype) &&
1123 SPEC_USIGN (rval->etype) &&
1124 (floatFromVal(lval)+floatFromVal(rval))>=0;
1126 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1128 if (IS_FLOAT (val->type))
1129 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1132 if (SPEC_LONG (val->type))
1134 if (SPEC_USIGN (val->type))
1135 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1136 (unsigned long) floatFromVal (rval);
1138 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1139 (long) floatFromVal (rval);
1143 if (SPEC_USIGN (val->type)) {
1144 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1145 (unsigned) floatFromVal (rval);
1147 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1148 (int) floatFromVal (rval);
1152 return cheapestVal(val);
1155 /*------------------------------------------------------------------*/
1156 /* valMinus - Addition constants */
1157 /*------------------------------------------------------------------*/
1159 valMinus (value * lval, value * rval)
1163 /* create a new value */
1165 val->type = val->etype = newLink ();
1166 val->type->class = SPECIFIER;
1167 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1168 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1169 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1170 SPEC_USIGN (val->type) =
1171 SPEC_USIGN (lval->etype) &&
1172 SPEC_USIGN (rval->etype) &&
1173 (floatFromVal(lval)-floatFromVal(rval))>=0;
1175 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1177 if (IS_FLOAT (val->type))
1178 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1181 if (SPEC_LONG (val->type))
1183 if (SPEC_USIGN (val->type)) {
1184 SPEC_CVAL (val->type).v_ulong =
1185 (unsigned long) floatFromVal (lval) -
1186 (unsigned long) floatFromVal (rval);
1188 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1189 (long) floatFromVal (rval);
1194 if (SPEC_USIGN (val->type)) {
1195 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1196 (unsigned) floatFromVal (rval);
1198 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1199 (int) floatFromVal (rval);
1203 return cheapestVal(val);
1206 /*------------------------------------------------------------------*/
1207 /* valShift - Shift left or right */
1208 /*------------------------------------------------------------------*/
1210 valShift (value * lval, value * rval, int lr)
1214 /* create a new value */
1216 val->type = val->etype = newIntLink ();
1217 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1218 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1219 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1221 if (SPEC_LONG (val->type))
1223 if (SPEC_USIGN (val->type))
1224 SPEC_CVAL (val->type).v_ulong = lr ?
1225 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1226 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1228 SPEC_CVAL (val->type).v_long = lr ?
1229 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1230 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1234 if (SPEC_USIGN (val->type)) {
1235 SPEC_CVAL (val->type).v_uint = lr ?
1236 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1237 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1239 SPEC_CVAL (val->type).v_int = lr ?
1240 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1241 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1245 return cheapestVal(val);
1248 /*------------------------------------------------------------------*/
1249 /* valCompare- Compares two literal */
1250 /*------------------------------------------------------------------*/
1252 valCompare (value * lval, value * rval, int ctype)
1256 /* create a new value */
1258 val->type = val->etype = newCharLink ();
1259 val->type->class = SPECIFIER;
1260 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1261 SPEC_USIGN (val->type) = 1;
1262 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1267 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1271 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1275 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1279 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1283 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1287 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1295 /*------------------------------------------------------------------*/
1296 /* valBitwise - Bitwise operation */
1297 /*------------------------------------------------------------------*/
1299 valBitwise (value * lval, value * rval, int op)
1303 /* create a new value */
1305 val->type = copyLinkChain (lval->type);
1306 val->etype = getSpec (val->type);
1311 if (SPEC_LONG (val->type))
1313 if (SPEC_USIGN (val->type))
1314 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1315 (unsigned long) floatFromVal (rval);
1317 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1318 (long) floatFromVal (rval);
1322 if (SPEC_USIGN (val->type))
1323 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1324 (unsigned) floatFromVal (rval);
1326 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1331 if (SPEC_LONG (val->type))
1333 if (SPEC_USIGN (val->type))
1334 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1335 (unsigned long) floatFromVal (rval);
1337 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1338 (long) floatFromVal (rval);
1342 if (SPEC_USIGN (val->type))
1343 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1344 (unsigned) floatFromVal (rval);
1346 SPEC_CVAL (val->type).v_int =
1347 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1353 if (SPEC_LONG (val->type))
1355 if (SPEC_USIGN (val->type))
1356 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1357 (unsigned long) floatFromVal (rval);
1359 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1360 (long) floatFromVal (rval);
1364 if (SPEC_USIGN (val->type))
1365 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1366 (unsigned) floatFromVal (rval);
1368 SPEC_CVAL (val->type).v_int =
1369 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1374 return cheapestVal(val);
1377 /*------------------------------------------------------------------*/
1378 /* valAndOr - Generates code for and / or operation */
1379 /*------------------------------------------------------------------*/
1381 valLogicAndOr (value * lval, value * rval, int op)
1385 /* create a new value */
1387 val->type = val->etype = newCharLink ();
1388 val->type->class = SPECIFIER;
1389 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1390 SPEC_USIGN (val->type) = 0;
1395 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1399 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1407 /*------------------------------------------------------------------*/
1408 /* valCastLiteral - casts a literal value to another type */
1409 /*------------------------------------------------------------------*/
1411 valCastLiteral (sym_link * dtype, double fval)
1419 val->etype = getSpec (val->type = copyLinkChain (dtype));
1420 SPEC_SCLS (val->etype) = S_LITERAL;
1421 /* if it is not a specifier then we can assume that */
1422 /* it will be an unsigned long */
1423 if (!IS_SPEC (val->type))
1425 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1429 if (SPEC_NOUN (val->etype) == V_FLOAT)
1430 SPEC_CVAL (val->etype).v_float = fval;
1433 if (SPEC_LONG (val->etype))
1435 if (SPEC_USIGN (val->etype))
1436 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1438 SPEC_CVAL (val->etype).v_long = (long) fval;
1442 if (SPEC_USIGN (val->etype))
1443 if (SPEC_NOUN (val->etype)==V_CHAR) {
1444 SPEC_CVAL (val->etype).v_uint = (unsigned char) fval;
1446 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1449 if (SPEC_NOUN (val->etype)==V_CHAR) {
1450 SPEC_CVAL (val->etype).v_int = (char) fval;
1452 SPEC_CVAL (val->etype).v_int = (int) fval;
1459 /*------------------------------------------------------------------*/
1460 /* getNelements - determines # of elements from init list */
1461 /*------------------------------------------------------------------*/
1463 getNelements (sym_link * type, initList * ilist)
1465 sym_link *etype = getSpec (type);
1471 if (ilist->type == INIT_DEEP)
1472 ilist = ilist->init.deep;
1474 /* if type is a character array and there is only one
1475 (string) initialiser then get the length of the string */
1476 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1478 ast *iast = ilist->init.node;
1479 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1482 werror (W_INIT_WRONG);
1486 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1487 // yep, it's a string
1489 return DCL_ELEM (v->type);
1497 ilist = ilist->next;
1503 /*-----------------------------------------------------------------*/
1504 /* valForArray - returns a value with name of array index */
1505 /*-----------------------------------------------------------------*/
1507 valForArray (ast * arrExpr)
1509 value *val, *lval = NULL;
1511 int size = getSize (arrExpr->left->ftype->next);
1512 /* if the right or left is an array
1514 if (IS_AST_OP (arrExpr->left))
1516 if (arrExpr->left->opval.op == '[')
1517 lval = valForArray (arrExpr->left);
1518 else if (arrExpr->left->opval.op == '.')
1519 lval = valForStructElem (arrExpr->left->left,
1520 arrExpr->left->right);
1521 else if (arrExpr->left->opval.op == PTR_OP &&
1522 IS_ADDRESS_OF_OP (arrExpr->left->left))
1523 lval = valForStructElem (arrExpr->left->left->left,
1524 arrExpr->left->right);
1529 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1532 if (!IS_AST_LIT_VALUE (arrExpr->right))
1537 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1539 sprintf (buffer, "%s", lval->name);
1541 sprintf (val->name, "(%s + %d)", buffer,
1542 (int) AST_LIT_VALUE (arrExpr->right) * size);
1544 val->type = newLink ();
1545 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1547 DCL_TYPE (val->type) = CPOINTER;
1548 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1550 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1551 DCL_TYPE (val->type) = FPOINTER;
1552 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1553 DCL_TYPE (val->type) = PPOINTER;
1554 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1555 DCL_TYPE (val->type) = IPOINTER;
1556 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1557 DCL_TYPE (val->type) = EEPPOINTER;
1559 DCL_TYPE (val->type) = POINTER;
1560 val->type->next = arrExpr->left->ftype;
1561 val->etype = getSpec (val->type);
1565 /*-----------------------------------------------------------------*/
1566 /* valForStructElem - returns value with name of struct element */
1567 /*-----------------------------------------------------------------*/
1569 valForStructElem (ast * structT, ast * elemT)
1571 value *val, *lval = NULL;
1575 /* left could be furthur derefed */
1576 if (IS_AST_OP (structT))
1578 if (structT->opval.op == '[')
1579 lval = valForArray (structT);
1580 else if (structT->opval.op == '.')
1581 lval = valForStructElem (structT->left, structT->right);
1582 else if (structT->opval.op == PTR_OP &&
1583 IS_ADDRESS_OF_OP (structT->left))
1584 lval = valForStructElem (structT->left->left,
1590 if (!IS_AST_SYM_VALUE (elemT))
1593 if (!IS_STRUCT (structT->etype))
1596 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1597 AST_SYMBOL (elemT))) == NULL)
1604 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1606 sprintf (buffer, "%s", lval->name);
1608 sprintf (val->name, "(%s + %d)", buffer,
1611 val->type = newLink ();
1612 if (SPEC_SCLS (structT->etype) == S_CODE)
1614 DCL_TYPE (val->type) = CPOINTER;
1615 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1617 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1618 DCL_TYPE (val->type) = FPOINTER;
1619 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1620 DCL_TYPE (val->type) = PPOINTER;
1621 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1622 DCL_TYPE (val->type) = IPOINTER;
1623 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1624 DCL_TYPE (val->type) = EEPPOINTER;
1626 DCL_TYPE (val->type) = POINTER;
1627 val->type->next = sym->type;
1628 val->etype = getSpec (val->type);
1632 /*-----------------------------------------------------------------*/
1633 /* valForCastAggr - will return value for a cast of an aggregate */
1634 /* plus minus a constant */
1635 /*-----------------------------------------------------------------*/
1637 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1641 if (!IS_AST_SYM_VALUE (aexpr))
1643 if (!IS_AST_LIT_VALUE (cnst))
1648 sprintf (val->name, "(%s %c %d)",
1649 AST_SYMBOL (aexpr)->rname, op,
1650 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1653 val->etype = getSpec (val->type);
1657 /*-----------------------------------------------------------------*/
1658 /* valForCastAggr - will return value for a cast of an aggregate */
1659 /* with no constant */
1660 /*-----------------------------------------------------------------*/
1662 valForCastArr (ast * aexpr, sym_link * type)
1666 if (!IS_AST_SYM_VALUE (aexpr))
1671 sprintf (val->name, "(%s)",
1672 AST_SYMBOL (aexpr)->rname);
1675 val->etype = getSpec (val->type);