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 - try to reduce 'signed int' to 'char' */
331 /*--------------------------------------------------------------------*/
333 cheapestVal (value *val)
335 /* only int can be reduced */
336 if (!IS_INT(val->type))
339 /* long must not be changed */
340 if (SPEC_LONG(val->type))
343 /* unsigned must not be changed */
344 if (SPEC_USIGN(val->type))
347 /* the only possible reduction is from signed int to (un)signed char,
348 because it's automatically promoted back to signed int.
350 a reduction from unsigned int to unsigned char is a bug,
351 because an _unsigned_ char is promoted to _signed_ int! */
352 if (SPEC_CVAL(val->type).v_int < -128 ||
353 SPEC_CVAL(val->type).v_int > 255)
355 /* not in the range of (un)signed char */
359 SPEC_NOUN(val->type) = V_CHAR;
361 /* 'unsigned char' promotes to 'signed int', so that we can
362 reduce it the other way */
363 if (SPEC_CVAL(val->type).v_int >= 0)
365 SPEC_USIGN(val->type) = 1;
370 /*-----------------------------------------------------------------*/
371 /* valueFromLit - creates a value from a literal */
372 /*-----------------------------------------------------------------*/
374 valueFromLit (double lit)
378 if ((((TYPE_DWORD) lit) - lit) == 0)
380 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
381 return constVal (buffer);
384 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
385 return constFloatVal (buffer);
388 /*-----------------------------------------------------------------*/
389 /* constFloatVal - converts a FLOAT constant to value */
390 /*-----------------------------------------------------------------*/
392 constFloatVal (char *s)
394 value *val = newValue ();
397 if (sscanf (s, "%lf", &sval) != 1)
399 werror (E_INVALID_FLOAT_CONST, s);
400 return constVal ("0");
403 val->type = val->etype = newLink (SPECIFIER);
404 SPEC_NOUN (val->type) = V_FLOAT;
405 SPEC_SCLS (val->type) = S_LITERAL;
406 SPEC_CVAL (val->type).v_float = sval;
411 /*-----------------------------------------------------------------*/
412 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
413 /*-----------------------------------------------------------------*/
415 constFixed16x16Val (char *s)
417 value *val = newValue ();
420 if (sscanf (s, "%lf", &sval) != 1)
422 werror (E_INVALID_FLOAT_CONST, s);
423 return constVal ("0");
426 val->type = val->etype = newLink (SPECIFIER);
427 SPEC_NOUN (val->type) = V_FLOAT;
428 SPEC_SCLS (val->type) = S_LITERAL;
429 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
434 /*-----------------------------------------------------------------*/
435 /* constVal - converts an INTEGER constant into a cheapest value */
436 /*-----------------------------------------------------------------*/
437 value *constVal (char *s)
440 short hex = 0, octal = 0;
443 val = newValue (); /* alloc space for value */
445 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
446 SPEC_SCLS (val->type) = S_LITERAL;
447 // let's start with a signed char
448 SPEC_NOUN (val->type) = V_CHAR;
449 SPEC_USIGN (val->type) = 0;
451 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
453 /* set the octal flag */
454 if (!hex && *s == '0' && *(s + 1))
460 sval = strtoul (s, NULL, 0);
464 werror (W_INVALID_INT_CONST, s, dval);
467 sscanf (s, "%lf", &dval);
470 /* Setup the flags first */
471 /* set the unsigned flag if 'uU' is found */
472 if (strchr (s, 'u') || strchr (s, 'U')) {
473 SPEC_USIGN (val->type) = 1;
476 /* set the b_long flag if 'lL' is found */
477 if (strchr (s, 'l') || strchr (s, 'L')) {
478 SPEC_NOUN (val->type) = V_INT;
479 SPEC_LONG (val->type) = 1;
481 if (dval<0) { // "-28u" will still be signed and negative
482 if (dval<-128) { // check if we have to promote to int
483 SPEC_NOUN (val->type) = V_INT;
485 if (dval<-32768) { // check if we have to promote to long int
486 SPEC_LONG (val->type) = 1;
489 if (dval>0xff || /* check if we have to promote to int */
490 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
491 char. After an integral promotion it will
492 be a signed int; this certainly isn't what
493 the programer wants */
494 SPEC_NOUN (val->type) = V_INT;
496 else { /* store char's always as unsigned; this helps other optimizations */
497 SPEC_USIGN (val->type) = 1;
499 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
500 SPEC_LONG (val->type) = 1;
502 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
503 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
505 SPEC_USIGN (val->type) = 1;
507 SPEC_LONG (val->type) = 1;
508 if (dval>0x7fffffff) {
509 SPEC_USIGN (val->type) = 1;
516 /* check for out of range */
517 if (dval<-2147483648.0) {
518 dval = -2147483648.0;
519 werror (W_INVALID_INT_CONST, s, dval);
521 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
523 werror (W_INVALID_INT_CONST, s, dval);
525 if (dval>4294967295.0) {
527 werror (W_INVALID_INT_CONST, s, dval);
530 if (SPEC_LONG (val->type))
532 if (SPEC_USIGN (val->type))
534 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
538 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
543 if (SPEC_USIGN (val->type))
545 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
549 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
556 /*! /fn char hexEscape(char **src)
558 /param src Pointer to 'x' from start of hex character value
561 unsigned char hexEscape(char **src)
564 unsigned long value ;
566 (*src)++ ; /* Skip over the 'x' */
567 s = *src ; /* Save for error detection */
569 value = strtol (*src, src, 16);
572 // no valid hex found
573 werror(E_INVALID_HEX);
576 werror(W_ESC_SEQ_OOR_FOR_CHAR);
582 /*------------------------------------------------------------------*/
583 /* octalEscape - process an octal constant of max three digits */
584 /* return the octal value, throw a warning for illegal octal */
585 /* adjust src to point at the last proccesed char */
586 /*------------------------------------------------------------------*/
588 unsigned char octalEscape (char **str) {
592 for (digits=0; digits<3; digits++) {
593 if (**str>='0' && **str<='7') {
594 value = value*8 + (**str-'0');
601 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
602 werror (W_ESC_SEQ_OOR_FOR_CHAR);
609 /fn int copyStr (char *dest, char *src)
611 Copies a source string to a dest buffer interpreting escape sequences
612 and special characters
614 /param dest Buffer to receive the resultant string
615 /param src Buffer containing the source string with escape sequecnes
616 /return Number of characters in output string
621 copyStr (char *dest, char *src)
624 char *OriginalDest = dest ;
630 else if (*src == '\\')
665 *dest++ = octalEscape(&src);
670 *dest++ = hexEscape(&src) ;
697 return dest - OriginalDest ;
700 /*------------------------------------------------------------------*/
701 /* strVal - converts a string constant to a value */
702 /*------------------------------------------------------------------*/
708 val = newValue (); /* get a new one */
710 /* get a declarator */
711 val->type = newLink (DECLARATOR);
712 DCL_TYPE (val->type) = ARRAY;
713 val->type->next = val->etype = newLink (SPECIFIER);
714 SPEC_NOUN (val->etype) = V_CHAR;
715 SPEC_SCLS (val->etype) = S_LITERAL;
717 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
718 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
724 /*------------------------------------------------------------------*/
725 /* reverseValWithType - reverses value chain with type & etype */
726 /*------------------------------------------------------------------*/
728 reverseValWithType (value * val)
736 /* save the type * etype chains */
740 /* set the current one 2b null */
741 val->type = val->etype = NULL;
742 val = reverseVal (val);
744 /* restore type & etype */
751 /*------------------------------------------------------------------*/
752 /* reverseVal - reverses the values for a value chain */
753 /*------------------------------------------------------------------*/
755 reverseVal (value * val)
757 value *prev, *curr, *next;
772 val->next = (void *) NULL;
776 /*------------------------------------------------------------------*/
777 /* copyValueChain - will copy a chain of values */
778 /*------------------------------------------------------------------*/
780 copyValueChain (value * src)
787 dest = copyValue (src);
788 dest->next = copyValueChain (src->next);
793 /*------------------------------------------------------------------*/
794 /* copyValue - copies contents of a value to a fresh one */
795 /*------------------------------------------------------------------*/
797 copyValue (value * src)
802 dest->sym = copySymbol (src->sym);
803 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
804 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
805 dest->etype = (src->type ? getSpec (dest->type) : NULL);
810 /*------------------------------------------------------------------*/
811 /* charVal - converts a character constant to a value */
812 /*------------------------------------------------------------------*/
820 val->type = val->etype = newLink (SPECIFIER);
821 SPEC_NOUN (val->type) = V_CHAR;
822 SPEC_USIGN(val->type) = 1;
823 SPEC_SCLS (val->type) = S_LITERAL;
825 s++; /* get rid of quotation */
826 /* if \ then special processing */
829 s++; /* go beyond the backslash */
833 SPEC_CVAL (val->type).v_uint = '\n';
836 SPEC_CVAL (val->type).v_uint = '\t';
839 SPEC_CVAL (val->type).v_uint = '\v';
842 SPEC_CVAL (val->type).v_uint = '\b';
845 SPEC_CVAL (val->type).v_uint = '\r';
848 SPEC_CVAL (val->type).v_uint = '\f';
851 SPEC_CVAL (val->type).v_uint = '\a';
854 SPEC_CVAL (val->type).v_uint = '\\';
857 SPEC_CVAL (val->type).v_uint = '\?';
860 SPEC_CVAL (val->type).v_uint = '\'';
863 SPEC_CVAL (val->type).v_uint = '\"';
874 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
878 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
882 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
886 else /* not a backslash */
887 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
892 /*------------------------------------------------------------------*/
893 /* valFromType - creates a value from type given */
894 /*------------------------------------------------------------------*/
896 valFromType (sym_link * type)
898 value *val = newValue ();
899 val->type = copyLinkChain (type);
900 val->etype = getSpec (val->type);
904 /*------------------------------------------------------------------*/
905 /* floatFromVal - value to double float conversion */
906 /*------------------------------------------------------------------*/
908 floatFromVal (value * val)
913 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
915 werror (E_CONST_EXPECTED, val->name);
919 /* if it is not a specifier then we can assume that */
920 /* it will be an unsigned long */
921 if (!IS_SPEC (val->type))
922 return (double) SPEC_CVAL (val->etype).v_ulong;
924 if (SPEC_NOUN (val->etype) == V_FLOAT)
925 return (double) SPEC_CVAL (val->etype).v_float;
927 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
928 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
930 if (SPEC_LONG (val->etype))
932 if (SPEC_USIGN (val->etype))
933 return (double) SPEC_CVAL (val->etype).v_ulong;
935 return (double) SPEC_CVAL (val->etype).v_long;
938 if (SPEC_NOUN (val->etype) == V_INT) {
939 if (SPEC_USIGN (val->etype))
940 return (double) SPEC_CVAL (val->etype).v_uint;
942 return (double) SPEC_CVAL (val->etype).v_int;
945 if (SPEC_NOUN (val->etype) == V_CHAR) {
946 if (SPEC_USIGN (val->etype))
947 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
949 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
952 if (IS_BITVAR(val->etype)) {
953 return (double) SPEC_CVAL (val->etype).v_uint;
956 if (SPEC_NOUN (val->etype) == V_VOID) {
957 return (double) SPEC_CVAL (val->etype).v_ulong;
961 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
962 "floatFromVal: unknown value");
966 /*------------------------------------------------------------------*/
967 /* valUnaryPM - does the unary +/- operation on a constant */
968 /*------------------------------------------------------------------*/
970 valUnaryPM (value * val)
972 /* depending on type */
973 if (SPEC_NOUN (val->etype) == V_FLOAT)
974 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
975 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
976 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
979 if (SPEC_LONG (val->etype))
981 if (SPEC_USIGN (val->etype))
982 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
984 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
988 if (SPEC_USIGN (val->etype))
989 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
991 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
993 if (SPEC_NOUN(val->etype) == V_CHAR)
995 /* promote to 'signed int', cheapestVal() might reduce it again */
996 SPEC_USIGN(val->etype) = 0;
997 SPEC_NOUN(val->etype) = V_INT;
999 return cheapestVal (val);
1005 /*------------------------------------------------------------------*/
1006 /* valueComplement - complements a constant */
1007 /*------------------------------------------------------------------*/
1009 valComplement (value * val)
1011 /* depending on type */
1012 if (SPEC_LONG (val->etype))
1014 if (SPEC_USIGN (val->etype))
1015 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1017 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1021 if (SPEC_USIGN (val->etype))
1022 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1024 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1026 if (SPEC_NOUN(val->etype) == V_CHAR)
1028 /* promote to 'signed int', cheapestVal() might reduce it again */
1029 SPEC_USIGN(val->etype) = 0;
1030 SPEC_NOUN(val->etype) = V_INT;
1032 return cheapestVal (val);
1037 /*------------------------------------------------------------------*/
1038 /* valueNot - complements a constant */
1039 /*------------------------------------------------------------------*/
1041 valNot (value * val)
1043 /* depending on type */
1044 if (SPEC_LONG (val->etype))
1046 if (SPEC_USIGN (val->etype))
1047 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1049 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1053 if (SPEC_USIGN (val->etype))
1054 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1056 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1059 /* ANSI: result type is int, value is 0 or 1 */
1060 /* sdcc will hold this in an 'unsigned char' */
1061 SPEC_USIGN(val->etype) = 1;
1062 SPEC_LONG (val->etype) = 0;
1063 SPEC_NOUN(val->etype) = V_CHAR;
1067 /*------------------------------------------------------------------*/
1068 /* valMult - multiply constants */
1069 /*------------------------------------------------------------------*/
1071 valMult (value * lval, value * rval)
1075 /* create a new value */
1077 val->type = val->etype = computeType (lval->etype,
1081 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1083 if (IS_FLOAT (val->type))
1084 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1086 if (IS_FIXED16X16 (val->type))
1087 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1088 /* signed and unsigned mul are the same, as long as the precision of the
1089 result isn't bigger than the precision of the operands. */
1090 else if (SPEC_LONG (val->type))
1091 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1092 (TYPE_UDWORD) floatFromVal (rval);
1093 else if (SPEC_USIGN (val->type)) /* unsigned int */
1095 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1096 (TYPE_UWORD) floatFromVal (rval);
1098 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1099 if (ul != (TYPE_UWORD) ul)
1102 else /* signed int */
1104 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1105 (TYPE_WORD) floatFromVal (rval);
1107 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1108 if (l != (TYPE_WORD) l)
1111 return cheapestVal (val);
1114 /*------------------------------------------------------------------*/
1115 /* valDiv - Divide constants */
1116 /*------------------------------------------------------------------*/
1118 valDiv (value * lval, value * rval)
1122 if (floatFromVal (rval) == 0)
1124 werror (E_DIVIDE_BY_ZERO);
1128 /* create a new value */
1130 val->type = val->etype = computeType (lval->etype,
1134 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1136 if (IS_FLOAT (val->type))
1137 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1139 if (IS_FIXED16X16 (val->type))
1140 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1141 else if (SPEC_LONG (val->type))
1143 if (SPEC_USIGN (val->type))
1144 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1145 (TYPE_UDWORD) floatFromVal (rval);
1147 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1148 (TYPE_DWORD) floatFromVal (rval);
1152 if (SPEC_USIGN (val->type))
1153 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1154 (TYPE_UWORD) floatFromVal (rval);
1156 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1157 (TYPE_WORD) floatFromVal (rval);
1159 return cheapestVal (val);
1162 /*------------------------------------------------------------------*/
1163 /* valMod - Modulus constants */
1164 /*------------------------------------------------------------------*/
1166 valMod (value * lval, value * rval)
1170 /* create a new value */
1172 val->type = val->etype = computeType (lval->etype,
1176 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1178 if (SPEC_LONG (val->type))
1180 if (SPEC_USIGN (val->type))
1181 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1182 (TYPE_UDWORD) floatFromVal (rval);
1184 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1185 (TYPE_DWORD) floatFromVal (rval);
1189 if (SPEC_USIGN (val->type))
1190 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1191 (TYPE_UWORD) floatFromVal (rval);
1193 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1194 (TYPE_WORD) floatFromVal (rval);
1196 return cheapestVal (val);
1199 /*------------------------------------------------------------------*/
1200 /* valPlus - Addition constants */
1201 /*------------------------------------------------------------------*/
1203 valPlus (value * lval, value * rval)
1207 /* create a new value */
1209 val->type = val->etype = computeType (lval->etype,
1213 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1215 if (IS_FLOAT (val->type))
1216 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1218 if (IS_FIXED16X16 (val->type))
1219 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1220 else if (SPEC_LONG (val->type))
1222 if (SPEC_USIGN (val->type))
1223 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1224 (TYPE_UDWORD) floatFromVal (rval);
1226 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1227 (TYPE_DWORD) floatFromVal (rval);
1231 if (SPEC_USIGN (val->type))
1232 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1233 (TYPE_UWORD) floatFromVal (rval);
1235 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1236 (TYPE_WORD) floatFromVal (rval);
1238 return cheapestVal (val);
1241 /*------------------------------------------------------------------*/
1242 /* valMinus - Addition constants */
1243 /*------------------------------------------------------------------*/
1245 valMinus (value * lval, value * rval)
1249 /* create a new value */
1251 val->type = val->etype = computeType (lval->etype,
1255 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1257 if (IS_FLOAT (val->type))
1258 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1260 if (IS_FIXED16X16 (val->type))
1261 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1262 else if (SPEC_LONG (val->type))
1264 if (SPEC_USIGN (val->type))
1265 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1266 (TYPE_UDWORD) floatFromVal (rval);
1268 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1269 (TYPE_DWORD) floatFromVal (rval);
1273 if (SPEC_USIGN (val->type))
1274 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1275 (TYPE_UWORD) floatFromVal (rval);
1277 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1278 (TYPE_WORD) floatFromVal (rval);
1280 return cheapestVal (val);
1283 /*------------------------------------------------------------------*/
1284 /* valShift - Shift left or right */
1285 /*------------------------------------------------------------------*/
1287 valShift (value * lval, value * rval, int lr)
1291 /* create a new value */
1293 val->type = val->etype = computeType (lval->etype,
1297 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1299 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1302 /* right shift and unsigned */
1303 (!lr && SPEC_USIGN (rval->type))))
1305 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1308 if (SPEC_LONG (val->type))
1310 if (SPEC_USIGN (val->type))
1312 SPEC_CVAL (val->type).v_ulong = lr ?
1313 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1314 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1318 SPEC_CVAL (val->type).v_long = lr ?
1319 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1320 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1325 if (SPEC_USIGN (val->type))
1327 SPEC_CVAL (val->type).v_uint = lr ?
1328 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1329 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1333 SPEC_CVAL (val->type).v_int = lr ?
1334 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1335 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1338 return cheapestVal (val);
1341 /*------------------------------------------------------------------*/
1342 /* valCompare- Compares two literal */
1343 /*------------------------------------------------------------------*/
1345 valCompare (value * lval, value * rval, int ctype)
1349 /* create a new value */
1351 val->type = val->etype = newCharLink ();
1352 val->type->class = SPECIFIER;
1353 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1354 SPEC_USIGN (val->type) = 1;
1355 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1360 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1364 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1368 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1372 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1376 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1377 SPEC_NOUN(rval->type) == V_FLOAT)
1379 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1382 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1383 SPEC_NOUN(rval->type) == V_FIXED16X16)
1385 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1389 /* integrals: ignore signedness */
1392 l = (TYPE_UDWORD) floatFromVal (lval);
1393 r = (TYPE_UDWORD) floatFromVal (rval);
1394 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1395 neccessary to strip them to 16 bit.
1396 Literals are reduced to their cheapest type, therefore left and
1397 right might have different types. It's neccessary to find a
1398 common type: int (used for char too) or long */
1399 if (!IS_LONG (lval->etype) &&
1400 !IS_LONG (rval->etype))
1405 SPEC_CVAL (val->type).v_int = l == r;
1409 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1410 SPEC_NOUN(rval->type) == V_FLOAT)
1412 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1415 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1416 SPEC_NOUN(rval->type) == V_FIXED16X16)
1418 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1422 /* integrals: ignore signedness */
1425 l = (TYPE_UDWORD) floatFromVal (lval);
1426 r = (TYPE_UDWORD) floatFromVal (rval);
1427 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1428 neccessary to strip them to 16 bit.
1429 Literals are reduced to their cheapest type, therefore left and
1430 right might have different types. It's neccessary to find a
1431 common type: int (used for char too) or long */
1432 if (!IS_LONG (lval->etype) &&
1433 !IS_LONG (rval->etype))
1438 SPEC_CVAL (val->type).v_int = l != r;
1447 /*------------------------------------------------------------------*/
1448 /* valBitwise - Bitwise operation */
1449 /*------------------------------------------------------------------*/
1451 valBitwise (value * lval, value * rval, int op)
1455 /* create a new value */
1457 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1458 val->etype = getSpec (val->type);
1459 SPEC_SCLS (val->etype) = S_LITERAL;
1464 if (SPEC_LONG (val->type))
1466 if (SPEC_USIGN (val->type))
1467 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1468 (TYPE_UDWORD) floatFromVal (rval);
1470 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1471 (TYPE_DWORD) floatFromVal (rval);
1475 if (SPEC_USIGN (val->type))
1476 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1477 (TYPE_UWORD) floatFromVal (rval);
1479 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1484 if (SPEC_LONG (val->type))
1486 if (SPEC_USIGN (val->type))
1487 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1488 (TYPE_UDWORD) floatFromVal (rval);
1490 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1491 (TYPE_DWORD) floatFromVal (rval);
1495 if (SPEC_USIGN (val->type))
1496 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1497 (TYPE_UWORD) floatFromVal (rval);
1499 SPEC_CVAL (val->type).v_int =
1500 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1506 if (SPEC_LONG (val->type))
1508 if (SPEC_USIGN (val->type))
1509 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1510 (TYPE_UDWORD) floatFromVal (rval);
1512 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1513 (TYPE_DWORD) floatFromVal (rval);
1517 if (SPEC_USIGN (val->type))
1518 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1519 (TYPE_UWORD) floatFromVal (rval);
1521 SPEC_CVAL (val->type).v_int =
1522 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1527 return cheapestVal(val);
1530 /*------------------------------------------------------------------*/
1531 /* valAndOr - Generates code for and / or operation */
1532 /*------------------------------------------------------------------*/
1534 valLogicAndOr (value * lval, value * rval, int op)
1538 /* create a new value */
1540 val->type = val->etype = newCharLink ();
1541 val->type->class = SPECIFIER;
1542 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1543 SPEC_USIGN (val->type) = 1;
1548 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1552 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1560 /*------------------------------------------------------------------*/
1561 /* valCastLiteral - casts a literal value to another type */
1562 /*------------------------------------------------------------------*/
1564 valCastLiteral (sym_link * dtype, double fval)
1567 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1574 val->etype = getSpec (val->type = copyLinkChain (dtype));
1577 val->etype = val->type = newLink (SPECIFIER);
1578 SPEC_NOUN (val->etype) = V_VOID;
1580 SPEC_SCLS (val->etype) = S_LITERAL;
1582 /* if it is not a specifier then we can assume that */
1583 /* it will be an unsigned long */
1584 if (!IS_SPEC (val->type)) {
1585 SPEC_CVAL (val->etype).v_ulong = l;
1589 if (SPEC_NOUN (val->etype) == V_FLOAT)
1590 SPEC_CVAL (val->etype).v_float = fval;
1591 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1592 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1593 else if (SPEC_NOUN (val->etype) == V_BIT ||
1594 SPEC_NOUN (val->etype) == V_SBIT)
1595 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1596 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1597 SPEC_CVAL (val->etype).v_uint = l &
1598 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1599 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1600 if (SPEC_USIGN (val->etype))
1601 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1603 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1605 if (SPEC_LONG (val->etype)) {
1606 if (SPEC_USIGN (val->etype))
1607 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1609 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1611 if (SPEC_USIGN (val->etype))
1612 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1614 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1620 /*------------------------------------------------------------------*/
1621 /* getNelements - determines # of elements from init list */
1622 /*------------------------------------------------------------------*/
1624 getNelements (sym_link * type, initList * ilist)
1631 if (ilist->type == INIT_DEEP)
1632 ilist = ilist->init.deep;
1634 /* if type is a character array and there is only one
1635 (string) initialiser then get the length of the string */
1636 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1638 ast *iast = ilist->init.node;
1639 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1642 werror (E_CONST_EXPECTED);
1646 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1647 // yep, it's a string
1649 return DCL_ELEM (v->type);
1657 ilist = ilist->next;
1662 /*-----------------------------------------------------------------*/
1663 /* valForArray - returns a value with name of array index */
1664 /*-----------------------------------------------------------------*/
1666 valForArray (ast * arrExpr)
1668 value *val, *lval = NULL;
1670 int size = getSize (arrExpr->left->ftype->next);
1671 /* if the right or left is an array
1673 if (IS_AST_OP (arrExpr->left))
1675 if (arrExpr->left->opval.op == '[')
1676 lval = valForArray (arrExpr->left);
1677 else if (arrExpr->left->opval.op == '.')
1678 lval = valForStructElem (arrExpr->left->left,
1679 arrExpr->left->right);
1680 else if (arrExpr->left->opval.op == PTR_OP &&
1681 IS_ADDRESS_OF_OP (arrExpr->left->left))
1682 lval = valForStructElem (arrExpr->left->left->left,
1683 arrExpr->left->right);
1688 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1691 if (!IS_AST_LIT_VALUE (arrExpr->right))
1697 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1701 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1704 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1705 (int) AST_LIT_VALUE (arrExpr->right) * size);
1707 val->type = newLink (DECLARATOR);
1708 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1709 DCL_TYPE (val->type) = CPOINTER;
1710 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1711 DCL_TYPE (val->type) = FPOINTER;
1712 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1713 DCL_TYPE (val->type) = PPOINTER;
1714 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1715 DCL_TYPE (val->type) = IPOINTER;
1716 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1717 DCL_TYPE (val->type) = EEPPOINTER;
1719 DCL_TYPE (val->type) = POINTER;
1720 val->type->next = arrExpr->left->ftype->next;
1721 val->etype = getSpec (val->type);
1725 /*-----------------------------------------------------------------*/
1726 /* valForStructElem - returns value with name of struct element */
1727 /*-----------------------------------------------------------------*/
1729 valForStructElem (ast * structT, ast * elemT)
1731 value *val, *lval = NULL;
1735 /* left could be furthur derefed */
1736 if (IS_AST_OP (structT))
1738 if (structT->opval.op == '[')
1739 lval = valForArray (structT);
1740 else if (structT->opval.op == '.')
1741 lval = valForStructElem (structT->left, structT->right);
1742 else if (structT->opval.op == PTR_OP &&
1743 IS_ADDRESS_OF_OP (structT->left))
1744 lval = valForStructElem (structT->left->left,
1750 if (!IS_AST_SYM_VALUE (elemT))
1753 if (!IS_STRUCT (structT->etype))
1756 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1757 AST_SYMBOL (elemT))) == NULL)
1765 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1769 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1772 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1775 val->type = newLink (DECLARATOR);
1776 if (SPEC_SCLS (structT->etype) == S_CODE)
1777 DCL_TYPE (val->type) = CPOINTER;
1778 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1779 DCL_TYPE (val->type) = FPOINTER;
1780 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1781 DCL_TYPE (val->type) = PPOINTER;
1782 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1783 DCL_TYPE (val->type) = IPOINTER;
1784 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1785 DCL_TYPE (val->type) = EEPPOINTER;
1787 DCL_TYPE (val->type) = POINTER;
1788 val->type->next = sym->type;
1789 val->etype = getSpec (val->type);
1793 /*-----------------------------------------------------------------*/
1794 /* valForCastAggr - will return value for a cast of an aggregate */
1795 /* plus minus a constant */
1796 /*-----------------------------------------------------------------*/
1798 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1802 if (!IS_AST_SYM_VALUE (aexpr))
1804 if (!IS_AST_LIT_VALUE (cnst))
1809 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1810 AST_SYMBOL (aexpr)->rname, op,
1811 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1814 val->etype = getSpec (val->type);
1818 /*-----------------------------------------------------------------*/
1819 /* valForCastAggr - will return value for a cast of an aggregate */
1820 /* with no constant */
1821 /*-----------------------------------------------------------------*/
1823 valForCastArr (ast * aexpr, sym_link * type)
1827 if (!IS_AST_SYM_VALUE (aexpr))
1832 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1833 AST_SYMBOL (aexpr)->rname);
1836 val->etype = getSpec (val->type);