1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_alloc (sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->lineno = mylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_alloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_alloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
308 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
312 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
318 /*--------------------------------------------------------------------*/
319 /* cheapestVal - convert a val to the cheapest as possible value */
320 /*--------------------------------------------------------------------*/
321 value *cheapestVal (value *val) {
323 unsigned long uval=0;
325 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
328 if (SPEC_LONG(val->type)) {
329 if (SPEC_USIGN(val->type)) {
330 uval=SPEC_CVAL(val->type).v_ulong;
332 sval=SPEC_CVAL(val->type).v_long;
335 if (SPEC_USIGN(val->type)) {
336 uval=SPEC_CVAL(val->type).v_uint;
338 sval=SPEC_CVAL(val->type).v_int;
342 if (SPEC_USIGN(val->type)) {
344 SPEC_LONG(val->type)=0;
345 SPEC_CVAL(val->type).v_uint = uval;
347 SPEC_NOUN(val->type)=V_CHAR;
350 } else { // not unsigned
353 SPEC_LONG(val->type)=0;
354 SPEC_CVAL(val->type).v_int = sval;
356 SPEC_NOUN(val->type)=V_CHAR;
360 SPEC_USIGN(val->type)=1;
362 SPEC_LONG(val->type)=0;
363 SPEC_CVAL(val->type).v_int = sval;
365 SPEC_NOUN(val->type)=V_CHAR;
373 /*-----------------------------------------------------------------*/
374 /* valueFromLit - creates a value from a literal */
375 /*-----------------------------------------------------------------*/
377 valueFromLit (double lit)
381 if ((((long) lit) - lit) == 0)
383 SNPRINTF (buffer, sizeof(buffer), "%ld", (long) lit);
384 return constVal (buffer);
387 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
388 return constFloatVal (buffer);
391 /*-----------------------------------------------------------------*/
392 /* constFloatVal - converts a FLOAT constant to value */
393 /*-----------------------------------------------------------------*/
395 constFloatVal (char *s)
397 value *val = newValue ();
400 if (sscanf (s, "%lf", &sval) != 1)
402 werror (E_INVALID_FLOAT_CONST, s);
403 return constVal ("0");
406 val->type = val->etype = newLink (SPECIFIER);
407 SPEC_NOUN (val->type) = V_FLOAT;
408 SPEC_SCLS (val->type) = S_LITERAL;
409 SPEC_CVAL (val->type).v_float = sval;
414 /*-----------------------------------------------------------------*/
415 /* constVal - converts an INTEGER constant into a cheapest value */
416 /*-----------------------------------------------------------------*/
417 value *constVal (char *s)
420 short hex = 0, octal = 0;
425 val = newValue (); /* alloc space for value */
427 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
428 SPEC_SCLS (val->type) = S_LITERAL;
429 // let's start with an unsigned char
430 SPEC_NOUN (val->type) = V_CHAR;
431 SPEC_USIGN (val->type) = 1;
433 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
435 /* set the octal flag */
436 if (!hex && *s == '0' && *(s + 1))
439 /* create the scan string */
440 scanFmt[scI++] = '%';
442 scanFmt[scI++] = 'l';
445 scanFmt[scI++] = 'o';
447 scanFmt[scI++] = 'x';
449 scanFmt[scI++] = 'f';
451 scanFmt[scI++] = '\0';
455 sscanf (s, scanFmt, &sval);
458 sscanf (s, scanFmt, &dval);
461 /* Setup the flags first */
462 /* set the _long flag if 'lL' is found */
463 if (strchr (s, 'l') || strchr (s, 'L')) {
464 SPEC_NOUN (val->type) = V_INT;
465 SPEC_LONG (val->type) = 1;
468 if (dval<0) { // "-28u" will still be signed and negative
469 SPEC_USIGN (val->type) = 0;
470 if (dval<-128) { // check if we have to promote to int
471 SPEC_NOUN (val->type) = V_INT;
473 if (dval<-32768) { // check if we have to promote to long int
474 SPEC_LONG (val->type) = 1;
477 if (dval>0xff) { // check if we have to promote to int
478 SPEC_NOUN (val->type) = V_INT;
480 if (dval>0xffff) { // check if we have to promote to long int
481 SPEC_LONG (val->type) = 1;
485 if (SPEC_LONG (val->type))
487 if (SPEC_USIGN (val->type))
489 SPEC_CVAL (val->type).v_ulong = dval;
493 SPEC_CVAL (val->type).v_long = dval;
498 if (SPEC_USIGN (val->type))
500 SPEC_CVAL (val->type).v_uint = dval;
504 SPEC_CVAL (val->type).v_int = dval;
511 /*! /fn char hexEscape(char **src)
513 /param src Pointer to 'x' from start of hex character value
516 unsigned char hexEscape(char **src)
519 unsigned long value ;
521 (*src)++ ; /* Skip over the 'x' */
522 s = *src ; /* Save for error detection */
524 value = strtol (*src, src, 16);
527 // no valid hex found
528 werror(E_INVALID_HEX);
531 werror(W_ESC_SEQ_OOR_FOR_CHAR);
537 /*------------------------------------------------------------------*/
538 /* octalEscape - process an octal constant of max three digits */
539 /* return the octal value, throw a warning for illegal octal */
540 /* adjust src to point at the last proccesed char */
541 /*------------------------------------------------------------------*/
543 unsigned char octalEscape (char **str) {
547 for (digits=0; digits<3; digits++) {
548 if (**str>='0' && **str<='7') {
549 value = value*8 + (**str-'0');
556 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
557 werror (W_ESC_SEQ_OOR_FOR_CHAR);
564 /fn int copyStr (char *dest, char *src)
566 Copies a source string to a dest buffer interpreting escape sequences
567 and special characters
569 /param dest Buffer to receive the resultant string
570 /param src Buffer containing the source string with escape sequecnes
571 /return Number of characters in output string
576 copyStr (char *dest, char *src)
579 char *OriginalDest = dest ;
585 else if (*src == '\\')
620 *dest++ = octalEscape(&src);
625 *dest++ = hexEscape(&src) ;
652 return dest - OriginalDest ;
655 /*------------------------------------------------------------------*/
656 /* strVal - converts a string constant to a value */
657 /*------------------------------------------------------------------*/
663 val = newValue (); /* get a new one */
665 /* get a declarator */
666 val->type = newLink (DECLARATOR);
667 DCL_TYPE (val->type) = ARRAY;
668 val->type->next = val->etype = newLink (SPECIFIER);
669 SPEC_NOUN (val->etype) = V_CHAR;
670 SPEC_SCLS (val->etype) = S_LITERAL;
672 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
673 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
679 /*------------------------------------------------------------------*/
680 /* reverseValWithType - reverses value chain with type & etype */
681 /*------------------------------------------------------------------*/
683 reverseValWithType (value * val)
691 /* save the type * etype chains */
695 /* set the current one 2b null */
696 val->type = val->etype = NULL;
697 val = reverseVal (val);
699 /* restore type & etype */
706 /*------------------------------------------------------------------*/
707 /* reverseVal - reverses the values for a value chain */
708 /*------------------------------------------------------------------*/
710 reverseVal (value * val)
712 value *prev, *curr, *next;
727 val->next = (void *) NULL;
731 /*------------------------------------------------------------------*/
732 /* copyValueChain - will copy a chain of values */
733 /*------------------------------------------------------------------*/
735 copyValueChain (value * src)
742 dest = copyValue (src);
743 dest->next = copyValueChain (src->next);
748 /*------------------------------------------------------------------*/
749 /* copyValue - copies contents of a value to a fresh one */
750 /*------------------------------------------------------------------*/
752 copyValue (value * src)
757 dest->sym = copySymbol (src->sym);
758 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
759 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
760 dest->etype = (src->type ? getSpec (dest->type) : NULL);
765 /*------------------------------------------------------------------*/
766 /* charVal - converts a character constant to a value */
767 /*------------------------------------------------------------------*/
776 val->type = val->etype = newLink (SPECIFIER);
777 SPEC_NOUN (val->type) = V_CHAR;
778 SPEC_USIGN(val->type) = 1;
779 SPEC_SCLS (val->type) = S_LITERAL;
781 s++; /* get rid of quotation */
782 /* if \ then special processing */
785 s++; /* go beyond the backslash */
789 SPEC_CVAL (val->type).v_uint = '\n';
792 SPEC_CVAL (val->type).v_uint = '\t';
795 SPEC_CVAL (val->type).v_uint = '\v';
798 SPEC_CVAL (val->type).v_uint = '\b';
801 SPEC_CVAL (val->type).v_uint = '\r';
804 SPEC_CVAL (val->type).v_uint = '\f';
807 SPEC_CVAL (val->type).v_uint = '\a';
810 SPEC_CVAL (val->type).v_uint = '\\';
813 SPEC_CVAL (val->type).v_uint = '\?';
816 SPEC_CVAL (val->type).v_uint = '\'';
819 SPEC_CVAL (val->type).v_uint = '\"';
830 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
834 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
838 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
842 else /* not a backslash */
843 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
848 /*------------------------------------------------------------------*/
849 /* valFromType - creates a value from type given */
850 /*------------------------------------------------------------------*/
852 valFromType (sym_link * type)
854 value *val = newValue ();
855 val->type = copyLinkChain (type);
856 val->etype = getSpec (val->type);
860 /*------------------------------------------------------------------*/
861 /* floatFromVal - value to double float conversion */
862 /*------------------------------------------------------------------*/
864 floatFromVal (value * val)
869 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
871 werror (E_CONST_EXPECTED, val->name);
875 /* if it is not a specifier then we can assume that */
876 /* it will be an unsigned long */
877 if (!IS_SPEC (val->type))
878 return (double) SPEC_CVAL (val->etype).v_ulong;
880 if (SPEC_NOUN (val->etype) == V_FLOAT)
881 return (double) SPEC_CVAL (val->etype).v_float;
883 if (SPEC_LONG (val->etype))
885 if (SPEC_USIGN (val->etype))
886 return (double) SPEC_CVAL (val->etype).v_ulong;
888 return (double) SPEC_CVAL (val->etype).v_long;
891 if (SPEC_NOUN (val->etype) == V_INT) {
892 if (SPEC_USIGN (val->etype))
893 return (double) SPEC_CVAL (val->etype).v_uint;
895 return (double) SPEC_CVAL (val->etype).v_int;
898 if (SPEC_NOUN (val->etype) == V_CHAR) {
899 if (SPEC_USIGN (val->etype))
900 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
902 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
905 if (IS_BITVAR(val->etype)) {
906 return (double) SPEC_CVAL (val->etype).v_uint;
909 if (SPEC_NOUN (val->etype) == V_VOID) {
910 return (double) SPEC_CVAL (val->etype).v_ulong;
914 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
915 "floatFromVal: unknown value");
920 /*------------------------------------------------------------------*/
921 /* valUnaryPM - does the unary +/- operation on a constant */
922 /*------------------------------------------------------------------*/
924 valUnaryPM (value * val)
926 /* depending on type */
927 if (SPEC_NOUN (val->etype) == V_FLOAT)
928 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
931 if (SPEC_LONG (val->etype))
933 if (SPEC_USIGN (val->etype))
934 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
936 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
940 if (SPEC_USIGN (val->etype))
941 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
943 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
946 // -(unsigned 3) now really is signed
947 SPEC_USIGN(val->etype)=0;
948 // -(unsigned char)135 now really is an int
949 if (SPEC_NOUN(val->etype) == V_CHAR) {
950 if (SPEC_CVAL(val->etype).v_int < -128) {
951 SPEC_NOUN(val->etype) = V_INT;
957 /*------------------------------------------------------------------*/
958 /* valueComplement - complements a constant */
959 /*------------------------------------------------------------------*/
961 valComplement (value * val)
963 /* depending on type */
964 if (SPEC_LONG (val->etype))
966 if (SPEC_USIGN (val->etype))
967 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
969 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
973 if (SPEC_USIGN (val->etype))
974 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
976 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
978 // ~(unsigned 3) now really is signed
979 SPEC_USIGN(val->etype)=0;
983 /*------------------------------------------------------------------*/
984 /* valueNot - complements a constant */
985 /*------------------------------------------------------------------*/
989 /* depending on type */
990 if (SPEC_LONG (val->etype))
992 if (SPEC_USIGN (val->etype))
993 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
995 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
999 if (SPEC_USIGN (val->etype))
1000 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1002 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1007 /*------------------------------------------------------------------*/
1008 /* valMult - multiply constants */
1009 /*------------------------------------------------------------------*/
1011 valMult (value * lval, value * rval)
1015 /* create a new value */
1017 val->type = val->etype = newLink (SPECIFIER);
1018 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1019 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1020 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1021 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1022 SPEC_LONG (val->type) = 1;
1024 if (IS_FLOAT (val->type))
1025 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1028 if (SPEC_LONG (val->type))
1030 if (SPEC_USIGN (val->type))
1031 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1032 (unsigned long) floatFromVal (rval);
1034 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1035 (long) floatFromVal (rval);
1038 return cheapestVal(val);
1041 /*------------------------------------------------------------------*/
1042 /* valDiv - Divide constants */
1043 /*------------------------------------------------------------------*/
1045 valDiv (value * lval, value * rval)
1049 if (floatFromVal (rval) == 0)
1051 werror (E_DIVIDE_BY_ZERO);
1055 /* create a new value */
1057 val->type = val->etype = newLink(SPECIFIER);
1058 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1059 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1060 SPEC_SCLS (val->etype) = S_LITERAL;
1061 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1062 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1064 if (IS_FLOAT (val->type))
1065 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1068 if (SPEC_LONG (val->type))
1070 if (SPEC_USIGN (val->type))
1071 SPEC_CVAL (val->type).v_ulong =
1072 (unsigned long) floatFromVal (lval) /
1073 (unsigned long) floatFromVal (rval);
1075 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1076 (long) floatFromVal (rval);
1080 if (SPEC_USIGN (val->type)) {
1081 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1082 (unsigned) floatFromVal (rval);
1084 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1085 (int) floatFromVal (rval);
1089 return cheapestVal(val);
1092 /*------------------------------------------------------------------*/
1093 /* valMod - Modulus constants */
1094 /*------------------------------------------------------------------*/
1096 valMod (value * lval, value * rval)
1100 /* create a new value */
1102 val->type = val->etype = newLink (SPECIFIER);
1103 SPEC_NOUN (val->type) = V_INT; /* type is int */
1104 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1105 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1106 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1108 if (SPEC_LONG (val->type))
1110 if (SPEC_USIGN (val->type))
1111 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1112 (unsigned long) floatFromVal (rval);
1114 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1115 (unsigned long) floatFromVal (rval);
1119 if (SPEC_USIGN (val->type)) {
1120 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1121 (unsigned) floatFromVal (rval);
1123 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1124 (unsigned) floatFromVal (rval);
1128 return cheapestVal(val);
1131 /*------------------------------------------------------------------*/
1132 /* valPlus - Addition constants */
1133 /*------------------------------------------------------------------*/
1135 valPlus (value * lval, value * rval)
1139 /* create a new value */
1141 val->type = val->etype = newLink (SPECIFIER);
1142 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1143 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1144 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1145 SPEC_USIGN (val->type) =
1146 SPEC_USIGN (lval->etype) &&
1147 SPEC_USIGN (rval->etype) &&
1148 (floatFromVal(lval)+floatFromVal(rval))>=0;
1150 SPEC_LONG (val->type) = 1;
1152 if (IS_FLOAT (val->type))
1153 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1156 if (SPEC_LONG (val->type))
1158 if (SPEC_USIGN (val->type))
1159 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1160 (unsigned long) floatFromVal (rval);
1162 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1163 (long) floatFromVal (rval);
1166 return cheapestVal(val);
1169 /*------------------------------------------------------------------*/
1170 /* valMinus - Addition constants */
1171 /*------------------------------------------------------------------*/
1173 valMinus (value * lval, value * rval)
1177 /* create a new value */
1179 val->type = val->etype = newLink (SPECIFIER);
1180 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1181 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1182 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1183 SPEC_USIGN (val->type) =
1184 SPEC_USIGN (lval->etype) &&
1185 SPEC_USIGN (rval->etype) &&
1186 (floatFromVal(lval)-floatFromVal(rval))>=0;
1188 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1190 if (IS_FLOAT (val->type))
1191 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1194 if (SPEC_LONG (val->type))
1196 if (SPEC_USIGN (val->type)) {
1197 SPEC_CVAL (val->type).v_ulong =
1198 (unsigned long) floatFromVal (lval) -
1199 (unsigned long) floatFromVal (rval);
1201 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1202 (long) floatFromVal (rval);
1207 if (SPEC_USIGN (val->type)) {
1208 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1209 (unsigned) floatFromVal (rval);
1211 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1212 (int) floatFromVal (rval);
1216 return cheapestVal(val);
1219 /*------------------------------------------------------------------*/
1220 /* valShift - Shift left or right */
1221 /*------------------------------------------------------------------*/
1223 valShift (value * lval, value * rval, int lr)
1227 /* create a new value */
1229 val->type = val->etype = newIntLink ();
1230 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1231 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1232 SPEC_LONG (val->type) = 1;
1234 if (SPEC_LONG (val->type))
1236 if (SPEC_USIGN (val->type))
1237 SPEC_CVAL (val->type).v_ulong = lr ?
1238 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1239 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1241 SPEC_CVAL (val->type).v_long = lr ?
1242 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1243 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1246 return cheapestVal(val);
1249 /*------------------------------------------------------------------*/
1250 /* valCompare- Compares two literal */
1251 /*------------------------------------------------------------------*/
1253 valCompare (value * lval, value * rval, int ctype)
1257 /* create a new value */
1259 val->type = val->etype = newCharLink ();
1260 val->type->class = SPECIFIER;
1261 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1262 SPEC_USIGN (val->type) = 1;
1263 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1268 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1272 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1276 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1280 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1284 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1288 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1296 /*------------------------------------------------------------------*/
1297 /* valBitwise - Bitwise operation */
1298 /*------------------------------------------------------------------*/
1300 valBitwise (value * lval, value * rval, int op)
1304 /* create a new value */
1306 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1307 rval->type : lval->type);
1308 val->etype = getSpec (val->type);
1313 if (SPEC_LONG (val->type))
1315 if (SPEC_USIGN (val->type))
1316 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1317 (unsigned long) floatFromVal (rval);
1319 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1320 (long) floatFromVal (rval);
1324 if (SPEC_USIGN (val->type))
1325 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1326 (unsigned) floatFromVal (rval);
1328 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1333 if (SPEC_LONG (val->type))
1335 if (SPEC_USIGN (val->type))
1336 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1337 (unsigned long) floatFromVal (rval);
1339 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1340 (long) floatFromVal (rval);
1344 if (SPEC_USIGN (val->type))
1345 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1346 (unsigned) floatFromVal (rval);
1348 SPEC_CVAL (val->type).v_int =
1349 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1355 if (SPEC_LONG (val->type))
1357 if (SPEC_USIGN (val->type))
1358 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1359 (unsigned long) floatFromVal (rval);
1361 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1362 (long) floatFromVal (rval);
1366 if (SPEC_USIGN (val->type))
1367 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1368 (unsigned) floatFromVal (rval);
1370 SPEC_CVAL (val->type).v_int =
1371 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1376 return cheapestVal(val);
1379 /*------------------------------------------------------------------*/
1380 /* valAndOr - Generates code for and / or operation */
1381 /*------------------------------------------------------------------*/
1383 valLogicAndOr (value * lval, value * rval, int op)
1387 /* create a new value */
1389 val->type = val->etype = newCharLink ();
1390 val->type->class = SPECIFIER;
1391 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1392 SPEC_USIGN (val->type) = 0;
1397 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1401 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1409 /*------------------------------------------------------------------*/
1410 /* valCastLiteral - casts a literal value to another type */
1411 /*------------------------------------------------------------------*/
1413 valCastLiteral (sym_link * dtype, double fval)
1421 val->etype = getSpec (val->type = copyLinkChain (dtype));
1422 SPEC_SCLS (val->etype) = S_LITERAL;
1423 /* if it is not a specifier then we can assume that */
1424 /* it will be an unsigned long */
1425 if (!IS_SPEC (val->type)) {
1426 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1430 if (SPEC_NOUN (val->etype) == V_FLOAT)
1431 SPEC_CVAL (val->etype).v_float = fval;
1433 unsigned long l = fval;
1434 if (SPEC_LONG (val->etype)) {
1435 if (SPEC_USIGN (val->etype))
1436 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1438 SPEC_CVAL (val->etype).v_long = (long) l;
1440 if (SPEC_USIGN (val->etype))
1441 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1443 SPEC_CVAL (val->etype).v_int = (short)l;
1449 /*------------------------------------------------------------------*/
1450 /* getNelements - determines # of elements from init list */
1451 /*------------------------------------------------------------------*/
1453 getNelements (sym_link * type, initList * ilist)
1460 if (ilist->type == INIT_DEEP)
1461 ilist = ilist->init.deep;
1463 /* if type is a character array and there is only one
1464 (string) initialiser then get the length of the string */
1465 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1467 ast *iast = ilist->init.node;
1468 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1471 werror (E_CONST_EXPECTED);
1475 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1476 // yep, it's a string
1478 return DCL_ELEM (v->type);
1486 ilist = ilist->next;
1491 /*-----------------------------------------------------------------*/
1492 /* valForArray - returns a value with name of array index */
1493 /*-----------------------------------------------------------------*/
1495 valForArray (ast * arrExpr)
1497 value *val, *lval = NULL;
1499 int size = getSize (arrExpr->left->ftype->next);
1500 /* if the right or left is an array
1502 if (IS_AST_OP (arrExpr->left))
1504 if (arrExpr->left->opval.op == '[')
1505 lval = valForArray (arrExpr->left);
1506 else if (arrExpr->left->opval.op == '.')
1507 lval = valForStructElem (arrExpr->left->left,
1508 arrExpr->left->right);
1509 else if (arrExpr->left->opval.op == PTR_OP &&
1510 IS_ADDRESS_OF_OP (arrExpr->left->left))
1511 lval = valForStructElem (arrExpr->left->left->left,
1512 arrExpr->left->right);
1517 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1520 if (!IS_AST_LIT_VALUE (arrExpr->right))
1526 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1530 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1533 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1534 (int) AST_LIT_VALUE (arrExpr->right) * size);
1536 val->type = newLink (DECLARATOR);
1537 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1539 DCL_TYPE (val->type) = CPOINTER;
1540 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1542 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1543 DCL_TYPE (val->type) = FPOINTER;
1544 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1545 DCL_TYPE (val->type) = PPOINTER;
1546 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1547 DCL_TYPE (val->type) = IPOINTER;
1548 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1549 DCL_TYPE (val->type) = EEPPOINTER;
1551 DCL_TYPE (val->type) = POINTER;
1552 val->type->next = arrExpr->left->ftype;
1553 val->etype = getSpec (val->type);
1557 /*-----------------------------------------------------------------*/
1558 /* valForStructElem - returns value with name of struct element */
1559 /*-----------------------------------------------------------------*/
1561 valForStructElem (ast * structT, ast * elemT)
1563 value *val, *lval = NULL;
1567 /* left could be furthur derefed */
1568 if (IS_AST_OP (structT))
1570 if (structT->opval.op == '[')
1571 lval = valForArray (structT);
1572 else if (structT->opval.op == '.')
1573 lval = valForStructElem (structT->left, structT->right);
1574 else if (structT->opval.op == PTR_OP &&
1575 IS_ADDRESS_OF_OP (structT->left))
1576 lval = valForStructElem (structT->left->left,
1582 if (!IS_AST_SYM_VALUE (elemT))
1585 if (!IS_STRUCT (structT->etype))
1588 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1589 AST_SYMBOL (elemT))) == NULL)
1597 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1601 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1604 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1607 val->type = newLink (DECLARATOR);
1608 if (SPEC_SCLS (structT->etype) == S_CODE)
1610 DCL_TYPE (val->type) = CPOINTER;
1611 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1613 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1614 DCL_TYPE (val->type) = FPOINTER;
1615 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1616 DCL_TYPE (val->type) = PPOINTER;
1617 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1618 DCL_TYPE (val->type) = IPOINTER;
1619 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1620 DCL_TYPE (val->type) = EEPPOINTER;
1622 DCL_TYPE (val->type) = POINTER;
1623 val->type->next = sym->type;
1624 val->etype = getSpec (val->type);
1628 /*-----------------------------------------------------------------*/
1629 /* valForCastAggr - will return value for a cast of an aggregate */
1630 /* plus minus a constant */
1631 /*-----------------------------------------------------------------*/
1633 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1637 if (!IS_AST_SYM_VALUE (aexpr))
1639 if (!IS_AST_LIT_VALUE (cnst))
1644 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1645 AST_SYMBOL (aexpr)->rname, op,
1646 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1649 val->etype = getSpec (val->type);
1653 /*-----------------------------------------------------------------*/
1654 /* valForCastAggr - will return value for a cast of an aggregate */
1655 /* with no constant */
1656 /*-----------------------------------------------------------------*/
1658 valForCastArr (ast * aexpr, sym_link * type)
1662 if (!IS_AST_SYM_VALUE (aexpr))
1667 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1668 AST_SYMBOL (aexpr)->rname);
1671 val->etype = getSpec (val->type);