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 -------------------------------------------------------------------------*/
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value */
37 /*-----------------------------------------------------------------*/
43 val = Safe_alloc (sizeof (value));
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list */
50 /*-----------------------------------------------------------------*/
52 newiList (int type, void *ilist)
57 nilist = Safe_alloc (sizeof (initList));
60 nilist->lineno = mylineno;
61 nilist->filename = currFname;
66 nilist->init.node = (struct ast *) ilist;
70 nilist->init.deep = (struct initList *) ilist;
77 /*------------------------------------------------------------------*/
78 /* revinit - reverses the initial values for a value chain */
79 /*------------------------------------------------------------------*/
81 revinit (initList * val)
83 initList *prev, *curr, *next;
98 val->next = (void *) NULL;
103 convertIListToConstList(initList *src, literalList **lList)
106 literalList *head, *last, *newL;
110 if (!src || src->type != INIT_DEEP)
115 iLoop = src->init.deep;
119 if (iLoop->type != INIT_NODE)
124 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
131 // We've now established that the initializer list contains only literal values.
133 iLoop = src->init.deep;
136 double val = AST_LIT_VALUE(iLoop->init.node);
138 if (last && last->literalValue == val)
144 newL = Safe_alloc(sizeof(literalList));
145 newL->literalValue = val;
172 copyLiteralList(literalList *src)
174 literalList *head, *prev, *newL;
180 newL = Safe_alloc(sizeof(literalList));
182 newL->literalValue = src->literalValue;
183 newL->count = src->count;
203 /*------------------------------------------------------------------*/
204 /* copyIlist - copy initializer list */
205 /*------------------------------------------------------------------*/
207 copyIlist (initList * src)
209 initList *dest = NULL;
217 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
220 dest = newiList (INIT_NODE, copyAst (src->init.node));
225 dest->next = copyIlist (src->next);
230 /*------------------------------------------------------------------*/
231 /* list2int - converts the first element of the list to value */
232 /*------------------------------------------------------------------*/
234 list2int (initList * val)
238 if (i->type == INIT_DEEP)
239 return list2int (val->init.deep);
241 return floatFromVal (constExprValue (val->init.node, TRUE));
244 /*------------------------------------------------------------------*/
245 /* list2val - converts the first element of the list to value */
246 /*------------------------------------------------------------------*/
248 list2val (initList * val)
253 if (val->type == INIT_DEEP)
254 return list2val (val->init.deep);
256 return constExprValue (val->init.node, TRUE);
259 /*------------------------------------------------------------------*/
260 /* list2expr - returns the first expression in the initializer list */
261 /*------------------------------------------------------------------*/
263 list2expr (initList * ilist)
265 if (ilist->type == INIT_DEEP)
266 return list2expr (ilist->init.deep);
267 return ilist->init.node;
270 /*------------------------------------------------------------------*/
271 /* resolveIvalSym - resolve symbols in initial values */
272 /*------------------------------------------------------------------*/
274 resolveIvalSym (initList * ilist, sym_link * type)
276 RESULT_TYPE resultType;
281 if (ilist->type == INIT_NODE)
284 resultType = RESULT_TYPE_INT;
286 resultType = getResultTypeFromType (getSpec (type));
287 ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
291 if (ilist->type == INIT_DEEP)
292 resolveIvalSym (ilist->init.deep, type);
294 resolveIvalSym (ilist->next, type);
297 /*-----------------------------------------------------------------*/
298 /* symbolVal - creates a value for a symbol */
299 /*-----------------------------------------------------------------*/
301 symbolVal (symbol * sym)
313 val->type = sym->type;
314 val->etype = getSpec (val->type);
319 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
323 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
329 /*--------------------------------------------------------------------*/
330 /* cheapestVal - convert a val to the cheapest as possible value */
331 /*--------------------------------------------------------------------*/
333 cheapestVal (value *val)
335 if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type))
338 /* long must not be changed */
339 if (SPEC_LONG(val->type))
342 /* only int can be reduced */
343 if (!IS_INT(val->type))
346 /* unsigned must not be changed */
347 if (SPEC_USIGN(val->type))
350 /* the only possible reduction is from signed int to (un)signed char,
351 because it's automatically promoted back to signed int.
353 a reduction from unsigned int to unsigned char is a bug,
354 because an _unsigned_ char is promoted to _signed_ int! */
355 if (SPEC_CVAL(val->type).v_int < -128 ||
356 SPEC_CVAL(val->type).v_int > 255)
358 /* not in the range of (un)signed char */
362 SPEC_NOUN(val->type) = V_CHAR;
364 /* 'unsigned char' promotes to 'signed int', so that we can
365 reduce it the other way */
366 if (SPEC_CVAL(val->type).v_int >= 0)
368 SPEC_USIGN(val->type) = 1;
373 /*-----------------------------------------------------------------*/
374 /* valueFromLit - creates a value from a literal */
375 /*-----------------------------------------------------------------*/
377 valueFromLit (double lit)
381 if ((((TYPE_DWORD) lit) - lit) == 0)
383 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) 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 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
416 /*-----------------------------------------------------------------*/
418 constFixed16x16Val (char *s)
420 value *val = newValue ();
423 if (sscanf (s, "%lf", &sval) != 1)
425 werror (E_INVALID_FLOAT_CONST, s);
426 return constVal ("0");
429 val->type = val->etype = newLink (SPECIFIER);
430 SPEC_NOUN (val->type) = V_FLOAT;
431 SPEC_SCLS (val->type) = S_LITERAL;
432 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
437 /*-----------------------------------------------------------------*/
438 /* constVal - converts an INTEGER constant into a cheapest value */
439 /*-----------------------------------------------------------------*/
440 value *constVal (char *s)
443 short hex = 0, octal = 0;
446 val = newValue (); /* alloc space for value */
448 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
449 SPEC_SCLS (val->type) = S_LITERAL;
450 // let's start with a signed char
451 SPEC_NOUN (val->type) = V_CHAR;
452 SPEC_USIGN (val->type) = 0;
454 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
456 /* set the octal flag */
457 if (!hex && *s == '0' && *(s + 1))
463 sval = strtoul (s, NULL, 0);
467 werror (W_INVALID_INT_CONST, s, dval);
470 sscanf (s, "%lf", &dval);
473 /* Setup the flags first */
474 /* set the unsigned flag if 'uU' is found */
475 if (strchr (s, 'u') || strchr (s, 'U')) {
476 SPEC_USIGN (val->type) = 1;
479 /* set the b_long flag if 'lL' is found */
480 if (strchr (s, 'l') || strchr (s, 'L')) {
481 SPEC_NOUN (val->type) = V_INT;
482 SPEC_LONG (val->type) = 1;
484 if (dval<0) { // "-28u" will still be signed and negative
485 if (dval<-128) { // check if we have to promote to int
486 SPEC_NOUN (val->type) = V_INT;
488 if (dval<-32768) { // check if we have to promote to long int
489 SPEC_LONG (val->type) = 1;
492 if (dval>0xff || /* check if we have to promote to int */
493 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
494 char. After an integral promotion it will
495 be a signed int; this certainly isn't what
496 the programer wants */
497 SPEC_NOUN (val->type) = V_INT;
499 else { /* store char's always as unsigned; this helps other optimizations */
500 SPEC_USIGN (val->type) = 1;
502 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
503 SPEC_LONG (val->type) = 1;
505 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
506 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
508 SPEC_USIGN (val->type) = 1;
510 SPEC_LONG (val->type) = 1;
511 if (dval>0x7fffffff) {
512 SPEC_USIGN (val->type) = 1;
519 /* check for out of range */
520 if (dval<-2147483648.0) {
521 dval = -2147483648.0;
522 werror (W_INVALID_INT_CONST, s, dval);
524 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
526 werror (W_INVALID_INT_CONST, s, dval);
528 if (dval>4294967295.0) {
530 werror (W_INVALID_INT_CONST, s, dval);
533 if (SPEC_LONG (val->type))
535 if (SPEC_USIGN (val->type))
537 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
541 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
546 if (SPEC_USIGN (val->type))
548 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
552 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
559 /*! /fn char hexEscape(char **src)
561 /param src Pointer to 'x' from start of hex character value
564 unsigned char hexEscape(char **src)
567 unsigned long value ;
569 (*src)++ ; /* Skip over the 'x' */
570 s = *src ; /* Save for error detection */
572 value = strtol (*src, src, 16);
575 // no valid hex found
576 werror(E_INVALID_HEX);
579 werror(W_ESC_SEQ_OOR_FOR_CHAR);
585 /*------------------------------------------------------------------*/
586 /* octalEscape - process an octal constant of max three digits */
587 /* return the octal value, throw a warning for illegal octal */
588 /* adjust src to point at the last proccesed char */
589 /*------------------------------------------------------------------*/
591 unsigned char octalEscape (char **str) {
595 for (digits=0; digits<3; digits++) {
596 if (**str>='0' && **str<='7') {
597 value = value*8 + (**str-'0');
604 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
605 werror (W_ESC_SEQ_OOR_FOR_CHAR);
612 /fn int copyStr (char *dest, char *src)
614 Copies a source string to a dest buffer interpreting escape sequences
615 and special characters
617 /param dest Buffer to receive the resultant string
618 /param src Buffer containing the source string with escape sequecnes
619 /return Number of characters in output string
624 copyStr (char *dest, char *src)
627 char *OriginalDest = dest ;
633 else if (*src == '\\')
668 *dest++ = octalEscape(&src);
673 *dest++ = hexEscape(&src) ;
700 return dest - OriginalDest ;
703 /*------------------------------------------------------------------*/
704 /* strVal - converts a string constant to a value */
705 /*------------------------------------------------------------------*/
711 val = newValue (); /* get a new one */
713 /* get a declarator */
714 val->type = newLink (DECLARATOR);
715 DCL_TYPE (val->type) = ARRAY;
716 val->type->next = val->etype = newLink (SPECIFIER);
717 SPEC_NOUN (val->etype) = V_CHAR;
718 SPEC_SCLS (val->etype) = S_LITERAL;
720 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
721 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
727 /*------------------------------------------------------------------*/
728 /* reverseValWithType - reverses value chain with type & etype */
729 /*------------------------------------------------------------------*/
731 reverseValWithType (value * val)
739 /* save the type * etype chains */
743 /* set the current one 2b null */
744 val->type = val->etype = NULL;
745 val = reverseVal (val);
747 /* restore type & etype */
754 /*------------------------------------------------------------------*/
755 /* reverseVal - reverses the values for a value chain */
756 /*------------------------------------------------------------------*/
758 reverseVal (value * val)
760 value *prev, *curr, *next;
775 val->next = (void *) NULL;
779 /*------------------------------------------------------------------*/
780 /* copyValueChain - will copy a chain of values */
781 /*------------------------------------------------------------------*/
783 copyValueChain (value * src)
790 dest = copyValue (src);
791 dest->next = copyValueChain (src->next);
796 /*------------------------------------------------------------------*/
797 /* copyValue - copies contents of a value to a fresh one */
798 /*------------------------------------------------------------------*/
800 copyValue (value * src)
805 dest->sym = copySymbol (src->sym);
806 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
807 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
808 dest->etype = (src->type ? getSpec (dest->type) : NULL);
813 /*------------------------------------------------------------------*/
814 /* charVal - converts a character constant to a value */
815 /*------------------------------------------------------------------*/
823 val->type = val->etype = newLink (SPECIFIER);
824 SPEC_NOUN (val->type) = V_CHAR;
825 SPEC_USIGN(val->type) = 1;
826 SPEC_SCLS (val->type) = S_LITERAL;
828 s++; /* get rid of quotation */
829 /* if \ then special processing */
832 s++; /* go beyond the backslash */
836 SPEC_CVAL (val->type).v_uint = '\n';
839 SPEC_CVAL (val->type).v_uint = '\t';
842 SPEC_CVAL (val->type).v_uint = '\v';
845 SPEC_CVAL (val->type).v_uint = '\b';
848 SPEC_CVAL (val->type).v_uint = '\r';
851 SPEC_CVAL (val->type).v_uint = '\f';
854 SPEC_CVAL (val->type).v_uint = '\a';
857 SPEC_CVAL (val->type).v_uint = '\\';
860 SPEC_CVAL (val->type).v_uint = '\?';
863 SPEC_CVAL (val->type).v_uint = '\'';
866 SPEC_CVAL (val->type).v_uint = '\"';
877 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
881 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
885 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
889 else /* not a backslash */
890 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
895 /*------------------------------------------------------------------*/
896 /* valFromType - creates a value from type given */
897 /*------------------------------------------------------------------*/
899 valFromType (sym_link * type)
901 value *val = newValue ();
902 val->type = copyLinkChain (type);
903 val->etype = getSpec (val->type);
907 /*------------------------------------------------------------------*/
908 /* floatFromVal - value to double float conversion */
909 /*------------------------------------------------------------------*/
911 floatFromVal (value * val)
916 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
918 werror (E_CONST_EXPECTED, val->name);
922 /* if it is not a specifier then we can assume that */
923 /* it will be an unsigned long */
924 if (!IS_SPEC (val->type))
925 return (double) SPEC_CVAL (val->etype).v_ulong;
927 if (SPEC_NOUN (val->etype) == V_FLOAT)
928 return (double) SPEC_CVAL (val->etype).v_float;
930 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
931 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
933 if (SPEC_LONG (val->etype))
935 if (SPEC_USIGN (val->etype))
936 return (double) SPEC_CVAL (val->etype).v_ulong;
938 return (double) SPEC_CVAL (val->etype).v_long;
941 if (SPEC_NOUN (val->etype) == V_INT) {
942 if (SPEC_USIGN (val->etype))
943 return (double) SPEC_CVAL (val->etype).v_uint;
945 return (double) SPEC_CVAL (val->etype).v_int;
948 if (SPEC_NOUN (val->etype) == V_CHAR) {
949 if (SPEC_USIGN (val->etype))
950 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
952 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
955 if (IS_BITVAR(val->etype)) {
956 return (double) SPEC_CVAL (val->etype).v_uint;
959 if (SPEC_NOUN (val->etype) == V_VOID) {
960 return (double) SPEC_CVAL (val->etype).v_ulong;
964 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
965 "floatFromVal: unknown value");
969 /*------------------------------------------------------------------*/
970 /* valUnaryPM - does the unary +/- operation on a constant */
971 /*------------------------------------------------------------------*/
973 valUnaryPM (value * val)
975 /* depending on type */
976 if (SPEC_NOUN (val->etype) == V_FLOAT)
977 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
978 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
979 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
982 if (SPEC_LONG (val->etype))
984 if (SPEC_USIGN (val->etype))
985 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
987 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
991 if (SPEC_USIGN (val->etype))
992 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
994 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
996 if (SPEC_NOUN(val->etype) == V_CHAR)
998 /* promote to 'signed int', cheapestVal() might reduce it again */
999 SPEC_USIGN(val->etype) = 0;
1000 SPEC_NOUN(val->etype) = V_INT;
1002 return cheapestVal (val);
1008 /*------------------------------------------------------------------*/
1009 /* valueComplement - complements a constant */
1010 /*------------------------------------------------------------------*/
1012 valComplement (value * val)
1014 /* depending on type */
1015 if (SPEC_LONG (val->etype))
1017 if (SPEC_USIGN (val->etype))
1018 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1020 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1024 if (SPEC_USIGN (val->etype))
1025 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1027 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1029 if (SPEC_NOUN(val->etype) == V_CHAR)
1031 /* promote to 'signed int', cheapestVal() might reduce it again */
1032 SPEC_USIGN(val->etype) = 0;
1033 SPEC_NOUN(val->etype) = V_INT;
1035 return cheapestVal (val);
1040 /*------------------------------------------------------------------*/
1041 /* valueNot - complements a constant */
1042 /*------------------------------------------------------------------*/
1044 valNot (value * val)
1046 /* depending on type */
1047 if (SPEC_LONG (val->etype))
1049 if (SPEC_USIGN (val->etype))
1050 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1052 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1056 if (SPEC_USIGN (val->etype))
1057 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1059 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1061 if (SPEC_NOUN(val->etype) == V_CHAR)
1063 /* promote to 'signed int', cheapestVal() might reduce it again */
1064 SPEC_USIGN(val->etype) = 0;
1065 SPEC_NOUN(val->etype) = V_INT;
1067 return cheapestVal (val);
1072 /*------------------------------------------------------------------*/
1073 /* valMult - multiply constants */
1074 /*------------------------------------------------------------------*/
1076 valMult (value * lval, value * rval)
1080 /* create a new value */
1082 val->type = val->etype = computeType (lval->etype,
1086 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1088 if (IS_FLOAT (val->type))
1089 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1091 if (IS_FIXED16X16 (val->type))
1092 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1093 /* signed and unsigned mul are the same, as long as the precision of the
1094 result isn't bigger than the precision of the operands. */
1095 else if (SPEC_LONG (val->type))
1096 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1097 (TYPE_UDWORD) floatFromVal (rval);
1098 else if (SPEC_USIGN (val->type)) /* unsigned int */
1100 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1101 (TYPE_UWORD) floatFromVal (rval);
1103 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1104 if (ul != (TYPE_UWORD) ul)
1107 else /* signed int */
1109 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1110 (TYPE_WORD) floatFromVal (rval);
1112 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1113 if (l != (TYPE_WORD) l)
1116 return cheapestVal (val);
1119 /*------------------------------------------------------------------*/
1120 /* valDiv - Divide constants */
1121 /*------------------------------------------------------------------*/
1123 valDiv (value * lval, value * rval)
1127 if (floatFromVal (rval) == 0)
1129 werror (E_DIVIDE_BY_ZERO);
1133 /* create a new value */
1135 val->type = val->etype = computeType (lval->etype,
1139 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1141 if (IS_FLOAT (val->type))
1142 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1144 if (IS_FIXED16X16 (val->type))
1145 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1146 else if (SPEC_LONG (val->type))
1148 if (SPEC_USIGN (val->type))
1149 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1150 (TYPE_UDWORD) floatFromVal (rval);
1152 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1153 (TYPE_DWORD) floatFromVal (rval);
1157 if (SPEC_USIGN (val->type))
1158 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1159 (TYPE_UWORD) floatFromVal (rval);
1161 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1162 (TYPE_WORD) floatFromVal (rval);
1164 return cheapestVal (val);
1167 /*------------------------------------------------------------------*/
1168 /* valMod - Modulus constants */
1169 /*------------------------------------------------------------------*/
1171 valMod (value * lval, value * rval)
1175 /* create a new value */
1177 val->type = val->etype = computeType (lval->etype,
1181 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1183 if (SPEC_LONG (val->type))
1185 if (SPEC_USIGN (val->type))
1186 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1187 (TYPE_UDWORD) floatFromVal (rval);
1189 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1190 (TYPE_DWORD) floatFromVal (rval);
1194 if (SPEC_USIGN (val->type))
1195 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1196 (TYPE_UWORD) floatFromVal (rval);
1198 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1199 (TYPE_WORD) floatFromVal (rval);
1201 return cheapestVal (val);
1204 /*------------------------------------------------------------------*/
1205 /* valPlus - Addition constants */
1206 /*------------------------------------------------------------------*/
1208 valPlus (value * lval, value * rval)
1212 /* create a new value */
1214 val->type = val->etype = computeType (lval->etype,
1218 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1220 if (IS_FLOAT (val->type))
1221 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1223 if (IS_FIXED16X16 (val->type))
1224 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1225 else if (SPEC_LONG (val->type))
1227 if (SPEC_USIGN (val->type))
1228 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1229 (TYPE_UDWORD) floatFromVal (rval);
1231 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1232 (TYPE_DWORD) floatFromVal (rval);
1236 if (SPEC_USIGN (val->type))
1237 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1238 (TYPE_UWORD) floatFromVal (rval);
1240 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1241 (TYPE_WORD) floatFromVal (rval);
1243 return cheapestVal (val);
1246 /*------------------------------------------------------------------*/
1247 /* valMinus - Addition constants */
1248 /*------------------------------------------------------------------*/
1250 valMinus (value * lval, value * rval)
1254 /* create a new value */
1256 val->type = val->etype = computeType (lval->etype,
1260 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1262 if (IS_FLOAT (val->type))
1263 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1265 if (IS_FIXED16X16 (val->type))
1266 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1267 else if (SPEC_LONG (val->type))
1269 if (SPEC_USIGN (val->type))
1270 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1271 (TYPE_UDWORD) floatFromVal (rval);
1273 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1274 (TYPE_DWORD) floatFromVal (rval);
1278 if (SPEC_USIGN (val->type))
1279 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1280 (TYPE_UWORD) floatFromVal (rval);
1282 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1283 (TYPE_WORD) floatFromVal (rval);
1285 return cheapestVal (val);
1288 /*------------------------------------------------------------------*/
1289 /* valShift - Shift left or right */
1290 /*------------------------------------------------------------------*/
1292 valShift (value * lval, value * rval, int lr)
1296 /* create a new value */
1298 val->type = val->etype = computeType (lval->etype,
1302 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1304 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1307 /* right shift and unsigned */
1308 (!lr && SPEC_USIGN (rval->type))))
1310 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1313 if (SPEC_LONG (val->type))
1315 if (SPEC_USIGN (val->type))
1317 SPEC_CVAL (val->type).v_ulong = lr ?
1318 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1319 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1323 SPEC_CVAL (val->type).v_long = lr ?
1324 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1325 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1330 if (SPEC_USIGN (val->type))
1332 SPEC_CVAL (val->type).v_uint = lr ?
1333 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1334 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1338 SPEC_CVAL (val->type).v_int = lr ?
1339 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1340 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1343 return cheapestVal (val);
1346 /*------------------------------------------------------------------*/
1347 /* valCompare- Compares two literal */
1348 /*------------------------------------------------------------------*/
1350 valCompare (value * lval, value * rval, int ctype)
1354 /* create a new value */
1356 val->type = val->etype = newCharLink ();
1357 val->type->class = SPECIFIER;
1358 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1359 SPEC_USIGN (val->type) = 1;
1360 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1365 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1369 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1373 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1377 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1381 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1382 SPEC_NOUN(rval->type) == V_FLOAT)
1384 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1387 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1388 SPEC_NOUN(rval->type) == V_FIXED16X16)
1390 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1394 /* integrals: ignore signedness */
1397 l = (TYPE_UDWORD) floatFromVal (lval);
1398 r = (TYPE_UDWORD) floatFromVal (rval);
1399 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1400 neccessary to strip them to 16 bit.
1401 Literals are reduced to their cheapest type, therefore left and
1402 right might have different types. It's neccessary to find a
1403 common type: int (used for char too) or long */
1404 if (!IS_LONG (lval->etype) &&
1405 !IS_LONG (rval->etype))
1410 SPEC_CVAL (val->type).v_int = l == r;
1414 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1415 SPEC_NOUN(rval->type) == V_FLOAT)
1417 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1420 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1421 SPEC_NOUN(rval->type) == V_FIXED16X16)
1423 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1427 /* integrals: ignore signedness */
1430 l = (TYPE_UDWORD) floatFromVal (lval);
1431 r = (TYPE_UDWORD) floatFromVal (rval);
1432 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1433 neccessary to strip them to 16 bit.
1434 Literals are reduced to their cheapest type, therefore left and
1435 right might have different types. It's neccessary to find a
1436 common type: int (used for char too) or long */
1437 if (!IS_LONG (lval->etype) &&
1438 !IS_LONG (rval->etype))
1443 SPEC_CVAL (val->type).v_int = l != r;
1452 /*------------------------------------------------------------------*/
1453 /* valBitwise - Bitwise operation */
1454 /*------------------------------------------------------------------*/
1456 valBitwise (value * lval, value * rval, int op)
1460 /* create a new value */
1462 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1463 val->etype = getSpec (val->type);
1464 SPEC_SCLS (val->etype) = S_LITERAL;
1469 if (SPEC_LONG (val->type))
1471 if (SPEC_USIGN (val->type))
1472 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1473 (TYPE_UDWORD) floatFromVal (rval);
1475 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1476 (TYPE_DWORD) floatFromVal (rval);
1480 if (SPEC_USIGN (val->type))
1481 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1482 (TYPE_UWORD) floatFromVal (rval);
1484 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1489 if (SPEC_LONG (val->type))
1491 if (SPEC_USIGN (val->type))
1492 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1493 (TYPE_UDWORD) floatFromVal (rval);
1495 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1496 (TYPE_DWORD) floatFromVal (rval);
1500 if (SPEC_USIGN (val->type))
1501 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1502 (TYPE_UWORD) floatFromVal (rval);
1504 SPEC_CVAL (val->type).v_int =
1505 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1511 if (SPEC_LONG (val->type))
1513 if (SPEC_USIGN (val->type))
1514 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1515 (TYPE_UDWORD) floatFromVal (rval);
1517 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1518 (TYPE_DWORD) floatFromVal (rval);
1522 if (SPEC_USIGN (val->type))
1523 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1524 (TYPE_UWORD) floatFromVal (rval);
1526 SPEC_CVAL (val->type).v_int =
1527 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1532 return cheapestVal(val);
1535 /*------------------------------------------------------------------*/
1536 /* valAndOr - Generates code for and / or operation */
1537 /*------------------------------------------------------------------*/
1539 valLogicAndOr (value * lval, value * rval, int op)
1543 /* create a new value */
1545 val->type = val->etype = newCharLink ();
1546 val->type->class = SPECIFIER;
1547 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1548 SPEC_USIGN (val->type) = 1;
1553 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1557 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1565 /*------------------------------------------------------------------*/
1566 /* valCastLiteral - casts a literal value to another type */
1567 /*------------------------------------------------------------------*/
1569 valCastLiteral (sym_link * dtype, double fval)
1572 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1579 val->etype = getSpec (val->type = copyLinkChain (dtype));
1582 val->etype = val->type = newLink (SPECIFIER);
1583 SPEC_NOUN (val->etype) = V_VOID;
1585 SPEC_SCLS (val->etype) = S_LITERAL;
1587 /* if it is not a specifier then we can assume that */
1588 /* it will be an unsigned long */
1589 if (!IS_SPEC (val->type)) {
1590 SPEC_CVAL (val->etype).v_ulong = l;
1594 if (SPEC_NOUN (val->etype) == V_FLOAT)
1595 SPEC_CVAL (val->etype).v_float = fval;
1596 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1597 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1598 else if (SPEC_NOUN (val->etype) == V_BIT ||
1599 SPEC_NOUN (val->etype) == V_SBIT)
1600 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1601 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1602 SPEC_CVAL (val->etype).v_uint = l &
1603 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1604 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1605 if (SPEC_USIGN (val->etype))
1606 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1608 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1610 if (SPEC_LONG (val->etype)) {
1611 if (SPEC_USIGN (val->etype))
1612 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1614 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1616 if (SPEC_USIGN (val->etype))
1617 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1619 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1625 /*------------------------------------------------------------------*/
1626 /* getNelements - determines # of elements from init list */
1627 /*------------------------------------------------------------------*/
1629 getNelements (sym_link * type, initList * ilist)
1636 if (ilist->type == INIT_DEEP)
1637 ilist = ilist->init.deep;
1639 /* if type is a character array and there is only one
1640 (string) initialiser then get the length of the string */
1641 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1643 ast *iast = ilist->init.node;
1644 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1647 werror (E_CONST_EXPECTED);
1651 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1652 // yep, it's a string
1654 return DCL_ELEM (v->type);
1662 ilist = ilist->next;
1667 /*-----------------------------------------------------------------*/
1668 /* valForArray - returns a value with name of array index */
1669 /*-----------------------------------------------------------------*/
1671 valForArray (ast * arrExpr)
1673 value *val, *lval = NULL;
1675 int size = getSize (arrExpr->left->ftype->next);
1676 /* if the right or left is an array
1678 if (IS_AST_OP (arrExpr->left))
1680 if (arrExpr->left->opval.op == '[')
1681 lval = valForArray (arrExpr->left);
1682 else if (arrExpr->left->opval.op == '.')
1683 lval = valForStructElem (arrExpr->left->left,
1684 arrExpr->left->right);
1685 else if (arrExpr->left->opval.op == PTR_OP &&
1686 IS_ADDRESS_OF_OP (arrExpr->left->left))
1687 lval = valForStructElem (arrExpr->left->left->left,
1688 arrExpr->left->right);
1693 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1696 if (!IS_AST_LIT_VALUE (arrExpr->right))
1702 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1706 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1709 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1710 (int) AST_LIT_VALUE (arrExpr->right) * size);
1712 val->type = newLink (DECLARATOR);
1713 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1714 DCL_TYPE (val->type) = CPOINTER;
1715 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1716 DCL_TYPE (val->type) = FPOINTER;
1717 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1718 DCL_TYPE (val->type) = PPOINTER;
1719 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1720 DCL_TYPE (val->type) = IPOINTER;
1721 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1722 DCL_TYPE (val->type) = EEPPOINTER;
1724 DCL_TYPE (val->type) = POINTER;
1725 val->type->next = arrExpr->left->ftype->next;
1726 val->etype = getSpec (val->type);
1730 /*-----------------------------------------------------------------*/
1731 /* valForStructElem - returns value with name of struct element */
1732 /*-----------------------------------------------------------------*/
1734 valForStructElem (ast * structT, ast * elemT)
1736 value *val, *lval = NULL;
1740 /* left could be furthur derefed */
1741 if (IS_AST_OP (structT))
1743 if (structT->opval.op == '[')
1744 lval = valForArray (structT);
1745 else if (structT->opval.op == '.')
1746 lval = valForStructElem (structT->left, structT->right);
1747 else if (structT->opval.op == PTR_OP &&
1748 IS_ADDRESS_OF_OP (structT->left))
1749 lval = valForStructElem (structT->left->left,
1755 if (!IS_AST_SYM_VALUE (elemT))
1758 if (!IS_STRUCT (structT->etype))
1761 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1762 AST_SYMBOL (elemT))) == NULL)
1770 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1774 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1777 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1780 val->type = newLink (DECLARATOR);
1781 if (SPEC_SCLS (structT->etype) == S_CODE)
1782 DCL_TYPE (val->type) = CPOINTER;
1783 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1784 DCL_TYPE (val->type) = FPOINTER;
1785 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1786 DCL_TYPE (val->type) = PPOINTER;
1787 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1788 DCL_TYPE (val->type) = IPOINTER;
1789 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1790 DCL_TYPE (val->type) = EEPPOINTER;
1792 DCL_TYPE (val->type) = POINTER;
1793 val->type->next = sym->type;
1794 val->etype = getSpec (val->type);
1798 /*-----------------------------------------------------------------*/
1799 /* valForCastAggr - will return value for a cast of an aggregate */
1800 /* plus minus a constant */
1801 /*-----------------------------------------------------------------*/
1803 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1807 if (!IS_AST_SYM_VALUE (aexpr))
1809 if (!IS_AST_LIT_VALUE (cnst))
1814 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1815 AST_SYMBOL (aexpr)->rname, op,
1816 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1819 val->etype = getSpec (val->type);
1823 /*-----------------------------------------------------------------*/
1824 /* valForCastAggr - will return value for a cast of an aggregate */
1825 /* with no constant */
1826 /*-----------------------------------------------------------------*/
1828 valForCastArr (ast * aexpr, sym_link * type)
1832 if (!IS_AST_SYM_VALUE (aexpr))
1837 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1838 AST_SYMBOL (aexpr)->rname);
1841 val->etype = getSpec (val->type);