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 #if defined(REDUCE_LITERALS)
330 /*--------------------------------------------------------------------*/
331 /* cheapestVal - convert a val to the cheapest as possible value */
332 /*--------------------------------------------------------------------*/
333 static value *cheapestVal (value *val) {
337 if (IS_FLOAT(val->type) || IS_FIXED(val->type) || IS_CHAR(val->type))
340 if (SPEC_LONG(val->type)) {
341 if (SPEC_USIGN(val->type)) {
342 uval=SPEC_CVAL(val->type).v_ulong;
344 sval=SPEC_CVAL(val->type).v_long;
347 if (SPEC_USIGN(val->type)) {
348 uval=SPEC_CVAL(val->type).v_uint;
350 sval=SPEC_CVAL(val->type).v_int;
354 if (SPEC_USIGN(val->type)) {
356 SPEC_LONG(val->type)=0;
357 SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
359 SPEC_NOUN(val->type)=V_CHAR;
362 } else { // not unsigned
365 SPEC_LONG(val->type)=0;
366 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
368 SPEC_NOUN(val->type)=V_CHAR;
373 SPEC_LONG(val->type)=0;
374 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
376 SPEC_NOUN(val->type)=V_CHAR;
386 static value *cheapestVal (value *val)
388 if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type))
391 /* - signed/unsigned must not be changed.
392 - long must not be changed.
394 the only possible reduction is from signed int to signed char,
395 because it's automatically promoted back to signed int.
397 a reduction from unsigned int to unsigned char is a bug,
398 because an _unsigned_ char is promoted to _signed_ int! */
399 if (IS_INT(val->type) &&
400 !SPEC_USIGN(val->type) &&
401 !SPEC_LONG(val->type) &&
402 SPEC_CVAL(val->type).v_int >= -128 &&
403 SPEC_CVAL(val->type).v_int < 0)
406 SPEC_NOUN(val->type) = V_CHAR;
408 /* 'unsigned char' promotes to 'signed int', so that we can
409 reduce it the other way */
410 if (IS_INT(val->type) &&
411 !SPEC_USIGN(val->type) &&
412 !SPEC_LONG(val->type) &&
413 SPEC_CVAL(val->type).v_int >= 0 &&
414 SPEC_CVAL(val->type).v_int <= 255)
417 SPEC_NOUN(val->type) = V_CHAR;
418 SPEC_USIGN(val->type) = 1;
424 /*-----------------------------------------------------------------*/
425 /* valueFromLit - creates a value from a literal */
426 /*-----------------------------------------------------------------*/
428 valueFromLit (double lit)
432 if ((((TYPE_DWORD) lit) - lit) == 0)
434 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
435 return constVal (buffer);
438 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
439 return constFloatVal (buffer);
442 /*-----------------------------------------------------------------*/
443 /* constFloatVal - converts a FLOAT constant to value */
444 /*-----------------------------------------------------------------*/
446 constFloatVal (char *s)
448 value *val = newValue ();
451 if (sscanf (s, "%lf", &sval) != 1)
453 werror (E_INVALID_FLOAT_CONST, s);
454 return constVal ("0");
457 val->type = val->etype = newLink (SPECIFIER);
458 SPEC_NOUN (val->type) = V_FLOAT;
459 SPEC_SCLS (val->type) = S_LITERAL;
460 SPEC_CVAL (val->type).v_float = sval;
465 /*-----------------------------------------------------------------*/
466 /* constFixed16x16Val - converts a FIXED16X16 constant to value */
467 /*-----------------------------------------------------------------*/
469 constFixed16x16Val (char *s)
471 value *val = newValue ();
474 if (sscanf (s, "%lf", &sval) != 1)
476 werror (E_INVALID_FLOAT_CONST, s);
477 return constVal ("0");
480 val->type = val->etype = newLink (SPECIFIER);
481 SPEC_NOUN (val->type) = V_FLOAT;
482 SPEC_SCLS (val->type) = S_LITERAL;
483 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
488 /*-----------------------------------------------------------------*/
489 /* constVal - converts an INTEGER constant into a cheapest value */
490 /*-----------------------------------------------------------------*/
491 value *constVal (char *s)
494 short hex = 0, octal = 0;
497 val = newValue (); /* alloc space for value */
499 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
500 SPEC_SCLS (val->type) = S_LITERAL;
501 // let's start with a signed char
502 SPEC_NOUN (val->type) = V_CHAR;
503 SPEC_USIGN (val->type) = 0;
505 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
507 /* set the octal flag */
508 if (!hex && *s == '0' && *(s + 1))
514 sval = strtoul (s, NULL, 0);
518 werror (W_INVALID_INT_CONST, s, dval);
521 sscanf (s, "%lf", &dval);
524 /* Setup the flags first */
525 /* set the unsigned flag if 'uU' is found */
526 if (strchr (s, 'u') || strchr (s, 'U')) {
527 SPEC_USIGN (val->type) = 1;
530 /* set the b_long flag if 'lL' is found */
531 if (strchr (s, 'l') || strchr (s, 'L')) {
532 SPEC_NOUN (val->type) = V_INT;
533 SPEC_LONG (val->type) = 1;
535 if (dval<0) { // "-28u" will still be signed and negative
536 if (dval<-128) { // check if we have to promote to int
537 SPEC_NOUN (val->type) = V_INT;
539 if (dval<-32768) { // check if we have to promote to long int
540 SPEC_LONG (val->type) = 1;
543 if (dval>0xff || /* check if we have to promote to int */
544 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
545 char. After an integral promotion it will
546 be a signed int; this certainly isn't what
547 the programer wants */
548 SPEC_NOUN (val->type) = V_INT;
550 else { /* store char's always as unsigned; this helps other optimizations */
551 SPEC_USIGN (val->type) = 1;
553 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
554 SPEC_LONG (val->type) = 1;
556 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
557 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
559 SPEC_USIGN (val->type) = 1;
561 SPEC_LONG (val->type) = 1;
562 if (dval>0x7fffffff) {
563 SPEC_USIGN (val->type) = 1;
570 /* check for out of range */
571 if (dval<-2147483648.0) {
572 dval = -2147483648.0;
573 werror (W_INVALID_INT_CONST, s, dval);
575 if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
577 werror (W_INVALID_INT_CONST, s, dval);
579 if (dval>4294967295.0) {
581 werror (W_INVALID_INT_CONST, s, dval);
584 if (SPEC_LONG (val->type))
586 if (SPEC_USIGN (val->type))
588 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
592 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
597 if (SPEC_USIGN (val->type))
599 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
603 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
610 /*! /fn char hexEscape(char **src)
612 /param src Pointer to 'x' from start of hex character value
615 unsigned char hexEscape(char **src)
618 unsigned long value ;
620 (*src)++ ; /* Skip over the 'x' */
621 s = *src ; /* Save for error detection */
623 value = strtol (*src, src, 16);
626 // no valid hex found
627 werror(E_INVALID_HEX);
630 werror(W_ESC_SEQ_OOR_FOR_CHAR);
636 /*------------------------------------------------------------------*/
637 /* octalEscape - process an octal constant of max three digits */
638 /* return the octal value, throw a warning for illegal octal */
639 /* adjust src to point at the last proccesed char */
640 /*------------------------------------------------------------------*/
642 unsigned char octalEscape (char **str) {
646 for (digits=0; digits<3; digits++) {
647 if (**str>='0' && **str<='7') {
648 value = value*8 + (**str-'0');
655 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
656 werror (W_ESC_SEQ_OOR_FOR_CHAR);
663 /fn int copyStr (char *dest, char *src)
665 Copies a source string to a dest buffer interpreting escape sequences
666 and special characters
668 /param dest Buffer to receive the resultant string
669 /param src Buffer containing the source string with escape sequecnes
670 /return Number of characters in output string
675 copyStr (char *dest, char *src)
678 char *OriginalDest = dest ;
684 else if (*src == '\\')
719 *dest++ = octalEscape(&src);
724 *dest++ = hexEscape(&src) ;
751 return dest - OriginalDest ;
754 /*------------------------------------------------------------------*/
755 /* strVal - converts a string constant to a value */
756 /*------------------------------------------------------------------*/
762 val = newValue (); /* get a new one */
764 /* get a declarator */
765 val->type = newLink (DECLARATOR);
766 DCL_TYPE (val->type) = ARRAY;
767 val->type->next = val->etype = newLink (SPECIFIER);
768 SPEC_NOUN (val->etype) = V_CHAR;
769 SPEC_SCLS (val->etype) = S_LITERAL;
771 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
772 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
778 /*------------------------------------------------------------------*/
779 /* reverseValWithType - reverses value chain with type & etype */
780 /*------------------------------------------------------------------*/
782 reverseValWithType (value * val)
790 /* save the type * etype chains */
794 /* set the current one 2b null */
795 val->type = val->etype = NULL;
796 val = reverseVal (val);
798 /* restore type & etype */
805 /*------------------------------------------------------------------*/
806 /* reverseVal - reverses the values for a value chain */
807 /*------------------------------------------------------------------*/
809 reverseVal (value * val)
811 value *prev, *curr, *next;
826 val->next = (void *) NULL;
830 /*------------------------------------------------------------------*/
831 /* copyValueChain - will copy a chain of values */
832 /*------------------------------------------------------------------*/
834 copyValueChain (value * src)
841 dest = copyValue (src);
842 dest->next = copyValueChain (src->next);
847 /*------------------------------------------------------------------*/
848 /* copyValue - copies contents of a value to a fresh one */
849 /*------------------------------------------------------------------*/
851 copyValue (value * src)
856 dest->sym = copySymbol (src->sym);
857 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
858 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
859 dest->etype = (src->type ? getSpec (dest->type) : NULL);
864 /*------------------------------------------------------------------*/
865 /* charVal - converts a character constant to a value */
866 /*------------------------------------------------------------------*/
874 val->type = val->etype = newLink (SPECIFIER);
875 SPEC_NOUN (val->type) = V_CHAR;
876 SPEC_USIGN(val->type) = 1;
877 SPEC_SCLS (val->type) = S_LITERAL;
879 s++; /* get rid of quotation */
880 /* if \ then special processing */
883 s++; /* go beyond the backslash */
887 SPEC_CVAL (val->type).v_uint = '\n';
890 SPEC_CVAL (val->type).v_uint = '\t';
893 SPEC_CVAL (val->type).v_uint = '\v';
896 SPEC_CVAL (val->type).v_uint = '\b';
899 SPEC_CVAL (val->type).v_uint = '\r';
902 SPEC_CVAL (val->type).v_uint = '\f';
905 SPEC_CVAL (val->type).v_uint = '\a';
908 SPEC_CVAL (val->type).v_uint = '\\';
911 SPEC_CVAL (val->type).v_uint = '\?';
914 SPEC_CVAL (val->type).v_uint = '\'';
917 SPEC_CVAL (val->type).v_uint = '\"';
928 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
932 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
936 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
940 else /* not a backslash */
941 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
946 /*------------------------------------------------------------------*/
947 /* valFromType - creates a value from type given */
948 /*------------------------------------------------------------------*/
950 valFromType (sym_link * type)
952 value *val = newValue ();
953 val->type = copyLinkChain (type);
954 val->etype = getSpec (val->type);
958 /*------------------------------------------------------------------*/
959 /* floatFromVal - value to double float conversion */
960 /*------------------------------------------------------------------*/
962 floatFromVal (value * val)
967 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
969 werror (E_CONST_EXPECTED, val->name);
973 /* if it is not a specifier then we can assume that */
974 /* it will be an unsigned long */
975 if (!IS_SPEC (val->type))
976 return (double) SPEC_CVAL (val->etype).v_ulong;
978 if (SPEC_NOUN (val->etype) == V_FLOAT)
979 return (double) SPEC_CVAL (val->etype).v_float;
981 if (SPEC_NOUN (val->etype) == V_FIXED16X16)
982 return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
984 if (SPEC_LONG (val->etype))
986 if (SPEC_USIGN (val->etype))
987 return (double) SPEC_CVAL (val->etype).v_ulong;
989 return (double) SPEC_CVAL (val->etype).v_long;
992 if (SPEC_NOUN (val->etype) == V_INT) {
993 if (SPEC_USIGN (val->etype))
994 return (double) SPEC_CVAL (val->etype).v_uint;
996 return (double) SPEC_CVAL (val->etype).v_int;
999 if (SPEC_NOUN (val->etype) == V_CHAR) {
1000 if (SPEC_USIGN (val->etype))
1001 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1003 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
1006 if (IS_BITVAR(val->etype)) {
1007 return (double) SPEC_CVAL (val->etype).v_uint;
1010 if (SPEC_NOUN (val->etype) == V_VOID) {
1011 return (double) SPEC_CVAL (val->etype).v_ulong;
1015 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1016 "floatFromVal: unknown value");
1020 /*------------------------------------------------------------------*/
1021 /* valUnaryPM - does the unary +/- operation on a constant */
1022 /*------------------------------------------------------------------*/
1024 valUnaryPM (value * val)
1026 /* depending on type */
1027 if (SPEC_NOUN (val->etype) == V_FLOAT)
1028 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1029 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1030 SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1033 if (SPEC_LONG (val->etype))
1035 if (SPEC_USIGN (val->etype))
1036 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1038 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1042 if (SPEC_USIGN (val->etype))
1043 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1045 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1048 // -(unsigned 3) now really is signed
1049 SPEC_USIGN(val->etype)=0;
1050 // -(unsigned char)135 now really is an int
1051 if (SPEC_NOUN(val->etype) == V_CHAR) {
1052 if (SPEC_CVAL(val->etype).v_int < -128) {
1053 SPEC_NOUN(val->etype) = V_INT;
1059 /*------------------------------------------------------------------*/
1060 /* valueComplement - complements a constant */
1061 /*------------------------------------------------------------------*/
1063 valComplement (value * val)
1065 /* depending on type */
1066 if (SPEC_LONG (val->etype))
1068 if (SPEC_USIGN (val->etype))
1069 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1071 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1075 if (SPEC_USIGN (val->etype))
1076 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1078 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1079 if (SPEC_NOUN(val->etype) == V_CHAR)
1080 if ( SPEC_CVAL(val->etype).v_int < -128
1081 || SPEC_CVAL(val->etype).v_int > 127)
1082 SPEC_NOUN(val->etype) = V_INT;
1084 // ~(unsigned 3) now really is signed
1085 SPEC_USIGN(val->etype)=0;
1089 /*------------------------------------------------------------------*/
1090 /* valueNot - complements a constant */
1091 /*------------------------------------------------------------------*/
1093 valNot (value * val)
1095 /* depending on type */
1096 if (SPEC_LONG (val->etype))
1098 if (SPEC_USIGN (val->etype))
1099 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1101 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1105 if (SPEC_USIGN (val->etype))
1106 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1108 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1113 /*------------------------------------------------------------------*/
1114 /* valMult - multiply constants */
1115 /*------------------------------------------------------------------*/
1117 valMult (value * lval, value * rval)
1121 /* create a new value */
1123 val->type = val->etype = computeType (lval->etype,
1127 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1129 if (IS_FLOAT (val->type))
1130 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1132 if (IS_FIXED16X16 (val->type))
1133 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1134 /* signed and unsigned mul are the same, as long as the precision of the
1135 result isn't bigger than the precision of the operands. */
1136 else if (SPEC_LONG (val->type))
1137 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1138 (TYPE_UDWORD) floatFromVal (rval);
1139 else if (SPEC_USIGN (val->type)) /* unsigned int */
1141 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1142 (TYPE_UWORD) floatFromVal (rval);
1144 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1145 if (ul != (TYPE_UWORD) ul)
1148 else /* signed int */
1150 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1151 (TYPE_WORD) floatFromVal (rval);
1153 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1154 if (l != (TYPE_WORD) l)
1157 return cheapestVal (val);
1160 /*------------------------------------------------------------------*/
1161 /* valDiv - Divide constants */
1162 /*------------------------------------------------------------------*/
1164 valDiv (value * lval, value * rval)
1168 if (floatFromVal (rval) == 0)
1170 werror (E_DIVIDE_BY_ZERO);
1174 /* create a new value */
1176 val->type = val->etype = computeType (lval->etype,
1180 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1182 if (IS_FLOAT (val->type))
1183 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1185 if (IS_FIXED16X16 (val->type))
1186 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1187 else if (SPEC_LONG (val->type))
1189 if (SPEC_USIGN (val->type))
1190 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1191 (TYPE_UDWORD) floatFromVal (rval);
1193 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1194 (TYPE_DWORD) floatFromVal (rval);
1198 if (SPEC_USIGN (val->type))
1199 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1200 (TYPE_UWORD) floatFromVal (rval);
1202 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1203 (TYPE_WORD) floatFromVal (rval);
1205 return cheapestVal (val);
1208 /*------------------------------------------------------------------*/
1209 /* valMod - Modulus constants */
1210 /*------------------------------------------------------------------*/
1212 valMod (value * lval, value * rval)
1216 /* create a new value */
1218 val->type = val->etype = computeType (lval->etype,
1222 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1224 if (SPEC_LONG (val->type))
1226 if (SPEC_USIGN (val->type))
1227 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1228 (TYPE_UDWORD) floatFromVal (rval);
1230 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1231 (TYPE_DWORD) floatFromVal (rval);
1235 if (SPEC_USIGN (val->type))
1236 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1237 (TYPE_UWORD) floatFromVal (rval);
1239 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1240 (TYPE_WORD) floatFromVal (rval);
1242 return cheapestVal (val);
1245 /*------------------------------------------------------------------*/
1246 /* valPlus - Addition constants */
1247 /*------------------------------------------------------------------*/
1249 valPlus (value * lval, value * rval)
1253 /* create a new value */
1255 val->type = val->etype = computeType (lval->etype,
1259 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1261 if (IS_FLOAT (val->type))
1262 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1264 if (IS_FIXED16X16 (val->type))
1265 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1266 else if (SPEC_LONG (val->type))
1268 if (SPEC_USIGN (val->type))
1269 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1270 (TYPE_UDWORD) floatFromVal (rval);
1272 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1273 (TYPE_DWORD) floatFromVal (rval);
1277 if (SPEC_USIGN (val->type))
1278 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1279 (TYPE_UWORD) floatFromVal (rval);
1281 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1282 (TYPE_WORD) floatFromVal (rval);
1284 return cheapestVal (val);
1287 /*------------------------------------------------------------------*/
1288 /* valMinus - Addition constants */
1289 /*------------------------------------------------------------------*/
1291 valMinus (value * lval, value * rval)
1295 /* create a new value */
1297 val->type = val->etype = computeType (lval->etype,
1301 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1303 if (IS_FLOAT (val->type))
1304 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1306 if (IS_FIXED16X16 (val->type))
1307 SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1308 else if (SPEC_LONG (val->type))
1310 if (SPEC_USIGN (val->type))
1311 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1312 (TYPE_UDWORD) floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1315 (TYPE_DWORD) floatFromVal (rval);
1319 if (SPEC_USIGN (val->type))
1320 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1321 (TYPE_UWORD) floatFromVal (rval);
1323 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1324 (TYPE_WORD) floatFromVal (rval);
1326 return cheapestVal (val);
1329 /*------------------------------------------------------------------*/
1330 /* valShift - Shift left or right */
1331 /*------------------------------------------------------------------*/
1333 valShift (value * lval, value * rval, int lr)
1337 /* create a new value */
1339 val->type = val->etype = computeType (lval->etype,
1343 SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1345 if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1348 /* right shift and unsigned */
1349 (!lr && SPEC_USIGN (rval->type))))
1351 werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1354 if (SPEC_LONG (val->type))
1356 if (SPEC_USIGN (val->type))
1358 SPEC_CVAL (val->type).v_ulong = lr ?
1359 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1360 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1364 SPEC_CVAL (val->type).v_long = lr ?
1365 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1366 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1371 if (SPEC_USIGN (val->type))
1373 SPEC_CVAL (val->type).v_uint = lr ?
1374 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1375 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1379 SPEC_CVAL (val->type).v_int = lr ?
1380 (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1381 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1384 return cheapestVal (val);
1387 /*------------------------------------------------------------------*/
1388 /* valCompare- Compares two literal */
1389 /*------------------------------------------------------------------*/
1391 valCompare (value * lval, value * rval, int ctype)
1395 /* create a new value */
1397 val->type = val->etype = newCharLink ();
1398 val->type->class = SPECIFIER;
1399 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1400 SPEC_USIGN (val->type) = 1;
1401 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1406 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1410 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1414 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1418 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1422 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1423 SPEC_NOUN(rval->type) == V_FLOAT)
1425 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1428 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1429 SPEC_NOUN(rval->type) == V_FIXED16X16)
1431 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1435 /* integrals: ignore signedness */
1438 l = (TYPE_UDWORD) floatFromVal (lval);
1439 r = (TYPE_UDWORD) floatFromVal (rval);
1440 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1441 neccessary to strip them to 16 bit.
1442 Literals are reduced to their cheapest type, therefore left and
1443 right might have different types. It's neccessary to find a
1444 common type: int (used for char too) or long */
1445 if (!IS_LONG (lval->etype) &&
1446 !IS_LONG (rval->etype))
1451 SPEC_CVAL (val->type).v_int = l == r;
1455 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1456 SPEC_NOUN(rval->type) == V_FLOAT)
1458 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1461 if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1462 SPEC_NOUN(rval->type) == V_FIXED16X16)
1464 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1468 /* integrals: ignore signedness */
1471 l = (TYPE_UDWORD) floatFromVal (lval);
1472 r = (TYPE_UDWORD) floatFromVal (rval);
1473 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1474 neccessary to strip them to 16 bit.
1475 Literals are reduced to their cheapest type, therefore left and
1476 right might have different types. It's neccessary to find a
1477 common type: int (used for char too) or long */
1478 if (!IS_LONG (lval->etype) &&
1479 !IS_LONG (rval->etype))
1484 SPEC_CVAL (val->type).v_int = l != r;
1493 /*------------------------------------------------------------------*/
1494 /* valBitwise - Bitwise operation */
1495 /*------------------------------------------------------------------*/
1497 valBitwise (value * lval, value * rval, int op)
1501 /* create a new value */
1503 val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1504 val->etype = getSpec (val->type);
1505 SPEC_SCLS (val->etype) = S_LITERAL;
1510 if (SPEC_LONG (val->type))
1512 if (SPEC_USIGN (val->type))
1513 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1514 (TYPE_UDWORD) floatFromVal (rval);
1516 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1517 (TYPE_DWORD) floatFromVal (rval);
1521 if (SPEC_USIGN (val->type))
1522 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1523 (TYPE_UWORD) floatFromVal (rval);
1525 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1530 if (SPEC_LONG (val->type))
1532 if (SPEC_USIGN (val->type))
1533 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1534 (TYPE_UDWORD) floatFromVal (rval);
1536 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1537 (TYPE_DWORD) floatFromVal (rval);
1541 if (SPEC_USIGN (val->type))
1542 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1543 (TYPE_UWORD) floatFromVal (rval);
1545 SPEC_CVAL (val->type).v_int =
1546 (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1552 if (SPEC_LONG (val->type))
1554 if (SPEC_USIGN (val->type))
1555 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1556 (TYPE_UDWORD) floatFromVal (rval);
1558 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1559 (TYPE_DWORD) floatFromVal (rval);
1563 if (SPEC_USIGN (val->type))
1564 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1565 (TYPE_UWORD) floatFromVal (rval);
1567 SPEC_CVAL (val->type).v_int =
1568 (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1573 return cheapestVal(val);
1576 /*------------------------------------------------------------------*/
1577 /* valAndOr - Generates code for and / or operation */
1578 /*------------------------------------------------------------------*/
1580 valLogicAndOr (value * lval, value * rval, int op)
1584 /* create a new value */
1586 val->type = val->etype = newCharLink ();
1587 val->type->class = SPECIFIER;
1588 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1589 SPEC_USIGN (val->type) = 1;
1594 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1598 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1606 /*------------------------------------------------------------------*/
1607 /* valCastLiteral - casts a literal value to another type */
1608 /*------------------------------------------------------------------*/
1610 valCastLiteral (sym_link * dtype, double fval)
1613 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1620 val->etype = getSpec (val->type = copyLinkChain (dtype));
1623 val->etype = val->type = newLink (SPECIFIER);
1624 SPEC_NOUN (val->etype) = V_VOID;
1626 SPEC_SCLS (val->etype) = S_LITERAL;
1628 /* if it is not a specifier then we can assume that */
1629 /* it will be an unsigned long */
1630 if (!IS_SPEC (val->type)) {
1631 SPEC_CVAL (val->etype).v_ulong = l;
1635 if (SPEC_NOUN (val->etype) == V_FLOAT)
1636 SPEC_CVAL (val->etype).v_float = fval;
1637 else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1638 SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1639 else if (SPEC_NOUN (val->etype) == V_BIT ||
1640 SPEC_NOUN (val->etype) == V_SBIT)
1641 SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1642 else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1643 SPEC_CVAL (val->etype).v_uint = l &
1644 (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1645 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1646 if (SPEC_USIGN (val->etype))
1647 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1649 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1651 if (SPEC_LONG (val->etype)) {
1652 if (SPEC_USIGN (val->etype))
1653 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1655 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1657 if (SPEC_USIGN (val->etype))
1658 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1660 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1666 /*------------------------------------------------------------------*/
1667 /* getNelements - determines # of elements from init list */
1668 /*------------------------------------------------------------------*/
1670 getNelements (sym_link * type, initList * ilist)
1677 if (ilist->type == INIT_DEEP)
1678 ilist = ilist->init.deep;
1680 /* if type is a character array and there is only one
1681 (string) initialiser then get the length of the string */
1682 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1684 ast *iast = ilist->init.node;
1685 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1688 werror (E_CONST_EXPECTED);
1692 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1693 // yep, it's a string
1695 return DCL_ELEM (v->type);
1703 ilist = ilist->next;
1708 /*-----------------------------------------------------------------*/
1709 /* valForArray - returns a value with name of array index */
1710 /*-----------------------------------------------------------------*/
1712 valForArray (ast * arrExpr)
1714 value *val, *lval = NULL;
1716 int size = getSize (arrExpr->left->ftype->next);
1717 /* if the right or left is an array
1719 if (IS_AST_OP (arrExpr->left))
1721 if (arrExpr->left->opval.op == '[')
1722 lval = valForArray (arrExpr->left);
1723 else if (arrExpr->left->opval.op == '.')
1724 lval = valForStructElem (arrExpr->left->left,
1725 arrExpr->left->right);
1726 else if (arrExpr->left->opval.op == PTR_OP &&
1727 IS_ADDRESS_OF_OP (arrExpr->left->left))
1728 lval = valForStructElem (arrExpr->left->left->left,
1729 arrExpr->left->right);
1734 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1737 if (!IS_AST_LIT_VALUE (arrExpr->right))
1743 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1747 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1750 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1751 (int) AST_LIT_VALUE (arrExpr->right) * size);
1753 val->type = newLink (DECLARATOR);
1754 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1755 DCL_TYPE (val->type) = CPOINTER;
1756 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1757 DCL_TYPE (val->type) = FPOINTER;
1758 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1759 DCL_TYPE (val->type) = PPOINTER;
1760 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1761 DCL_TYPE (val->type) = IPOINTER;
1762 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1763 DCL_TYPE (val->type) = EEPPOINTER;
1765 DCL_TYPE (val->type) = POINTER;
1766 val->type->next = arrExpr->left->ftype->next;
1767 val->etype = getSpec (val->type);
1771 /*-----------------------------------------------------------------*/
1772 /* valForStructElem - returns value with name of struct element */
1773 /*-----------------------------------------------------------------*/
1775 valForStructElem (ast * structT, ast * elemT)
1777 value *val, *lval = NULL;
1781 /* left could be furthur derefed */
1782 if (IS_AST_OP (structT))
1784 if (structT->opval.op == '[')
1785 lval = valForArray (structT);
1786 else if (structT->opval.op == '.')
1787 lval = valForStructElem (structT->left, structT->right);
1788 else if (structT->opval.op == PTR_OP &&
1789 IS_ADDRESS_OF_OP (structT->left))
1790 lval = valForStructElem (structT->left->left,
1796 if (!IS_AST_SYM_VALUE (elemT))
1799 if (!IS_STRUCT (structT->etype))
1802 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1803 AST_SYMBOL (elemT))) == NULL)
1811 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1815 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1818 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1821 val->type = newLink (DECLARATOR);
1822 if (SPEC_SCLS (structT->etype) == S_CODE)
1823 DCL_TYPE (val->type) = CPOINTER;
1824 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1825 DCL_TYPE (val->type) = FPOINTER;
1826 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1827 DCL_TYPE (val->type) = PPOINTER;
1828 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1829 DCL_TYPE (val->type) = IPOINTER;
1830 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1831 DCL_TYPE (val->type) = EEPPOINTER;
1833 DCL_TYPE (val->type) = POINTER;
1834 val->type->next = sym->type;
1835 val->etype = getSpec (val->type);
1839 /*-----------------------------------------------------------------*/
1840 /* valForCastAggr - will return value for a cast of an aggregate */
1841 /* plus minus a constant */
1842 /*-----------------------------------------------------------------*/
1844 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1848 if (!IS_AST_SYM_VALUE (aexpr))
1850 if (!IS_AST_LIT_VALUE (cnst))
1855 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1856 AST_SYMBOL (aexpr)->rname, op,
1857 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1860 val->etype = getSpec (val->type);
1864 /*-----------------------------------------------------------------*/
1865 /* valForCastAggr - will return value for a cast of an aggregate */
1866 /* with no constant */
1867 /*-----------------------------------------------------------------*/
1869 valForCastArr (ast * aexpr, sym_link * type)
1873 if (!IS_AST_SYM_VALUE (aexpr))
1878 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1879 AST_SYMBOL (aexpr)->rname);
1882 val->etype = getSpec (val->type);