1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_alloc (sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->lineno = mylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_alloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_alloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
308 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
312 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
318 #if defined(REDUCE_LITERALS)
319 /*--------------------------------------------------------------------*/
320 /* cheapestVal - convert a val to the cheapest as possible value */
321 /*--------------------------------------------------------------------*/
322 static value *cheapestVal (value *val) {
326 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
329 if (SPEC_LONG(val->type)) {
330 if (SPEC_USIGN(val->type)) {
331 uval=SPEC_CVAL(val->type).v_ulong;
333 sval=SPEC_CVAL(val->type).v_long;
336 if (SPEC_USIGN(val->type)) {
337 uval=SPEC_CVAL(val->type).v_uint;
339 sval=SPEC_CVAL(val->type).v_int;
343 if (SPEC_USIGN(val->type)) {
345 SPEC_LONG(val->type)=0;
346 SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
348 SPEC_NOUN(val->type)=V_CHAR;
351 } else { // not unsigned
354 SPEC_LONG(val->type)=0;
355 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
357 SPEC_NOUN(val->type)=V_CHAR;
362 SPEC_LONG(val->type)=0;
363 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
365 SPEC_NOUN(val->type)=V_CHAR;
375 static value *cheapestVal (value *val)
377 /* - signed/unsigned must no be changed.
378 - long must not be changed.
380 the only possible reduction is from signed int to signed char,
381 because it's automatically promoted back to signed int.
383 a reduction from unsigned int to unsigned char is a bug,
384 because an _unsigned_ char is promoted to _signed_ int! */
385 if (IS_INT(val->type) &&
386 !SPEC_USIGN(val->type) &&
387 !SPEC_LONG(val->type) &&
388 SPEC_CVAL(val->type).v_int >= -128 &&
389 SPEC_CVAL(val->type).v_int <= 127)
392 SPEC_NOUN(val->type) = V_CHAR;
394 /* this could be too aggressive:
395 'unsigned char' promotes to 'signed int', so that we can
396 reduce it the other way */
397 if (IS_INT(val->type) &&
398 !SPEC_USIGN(val->type) &&
399 !SPEC_LONG(val->type) &&
400 SPEC_CVAL(val->type).v_int >= 128 &&
401 SPEC_CVAL(val->type).v_int <= 255)
404 SPEC_NOUN(val->type) = V_CHAR;
405 SPEC_USIGN(val->type) = 1;
411 /*-----------------------------------------------------------------*/
412 /* valueFromLit - creates a value from a literal */
413 /*-----------------------------------------------------------------*/
415 valueFromLit (double lit)
419 if ((((TYPE_DWORD) lit) - lit) == 0)
421 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
422 return constVal (buffer);
425 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
426 return constFloatVal (buffer);
429 /*-----------------------------------------------------------------*/
430 /* constFloatVal - converts a FLOAT constant to value */
431 /*-----------------------------------------------------------------*/
433 constFloatVal (char *s)
435 value *val = newValue ();
438 if (sscanf (s, "%lf", &sval) != 1)
440 werror (E_INVALID_FLOAT_CONST, s);
441 return constVal ("0");
444 val->type = val->etype = newLink (SPECIFIER);
445 SPEC_NOUN (val->type) = V_FLOAT;
446 SPEC_SCLS (val->type) = S_LITERAL;
447 SPEC_CVAL (val->type).v_float = sval;
452 /*-----------------------------------------------------------------*/
453 /* constVal - converts an INTEGER constant into a cheapest value */
454 /*-----------------------------------------------------------------*/
455 value *constVal (char *s)
458 short hex = 0, octal = 0;
463 val = newValue (); /* alloc space for value */
465 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
466 SPEC_SCLS (val->type) = S_LITERAL;
467 // let's start with a signed char
468 SPEC_NOUN (val->type) = V_CHAR;
469 SPEC_USIGN (val->type) = 0;
471 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
473 /* set the octal flag */
474 if (!hex && *s == '0' && *(s + 1))
477 /* create the scan string */
478 scanFmt[scI++] = '%';
480 scanFmt[scI++] = 'l';
483 scanFmt[scI++] = 'o';
485 scanFmt[scI++] = 'x';
487 scanFmt[scI++] = 'f';
489 scanFmt[scI++] = '\0';
493 sscanf (s, scanFmt, &sval);
496 sscanf (s, scanFmt, &dval);
499 /* Setup the flags first */
500 /* set the _long flag if 'lL' is found */
501 if (strchr (s, 'l') || strchr (s, 'L')) {
502 SPEC_NOUN (val->type) = V_INT;
503 SPEC_LONG (val->type) = 1;
506 /* set the unsigned flag if 'uU' is found */
507 if (strchr (s, 'u') || strchr (s, 'U')) {
508 SPEC_USIGN (val->type) = 1;
511 if (dval<0) { // "-28u" will still be signed and negative
512 if (dval<-128) { // check if we have to promote to int
513 SPEC_NOUN (val->type) = V_INT;
515 if (dval<-32768) { // check if we have to promote to long int
516 SPEC_LONG (val->type) = 1;
519 if (dval>0xff || /* check if we have to promote to int */
520 SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
521 char. After an integral promotion it will
522 be a signed int; this certainly isn't what
523 the programer wants */
524 SPEC_NOUN (val->type) = V_INT;
526 else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
528 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
530 SPEC_USIGN (val->type) = 1;
532 SPEC_NOUN (val->type) = V_INT;
535 /* this is quite agressive: 'unsigned char' will be promoted to 'signed int',
536 so that the signedness of a char shouldn't matter */
537 SPEC_USIGN (val->type) = 1;
540 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
541 SPEC_LONG (val->type) = 1;
543 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
544 if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
546 SPEC_USIGN (val->type) = 1;
548 SPEC_LONG (val->type) = 1;
549 if (dval>0x7fffffff) {
550 SPEC_USIGN (val->type) = 1;
556 if (SPEC_LONG (val->type))
558 if (SPEC_USIGN (val->type))
560 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
564 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
569 if (SPEC_USIGN (val->type))
571 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
575 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
582 /*! /fn char hexEscape(char **src)
584 /param src Pointer to 'x' from start of hex character value
587 unsigned char hexEscape(char **src)
590 unsigned long value ;
592 (*src)++ ; /* Skip over the 'x' */
593 s = *src ; /* Save for error detection */
595 value = strtol (*src, src, 16);
598 // no valid hex found
599 werror(E_INVALID_HEX);
602 werror(W_ESC_SEQ_OOR_FOR_CHAR);
608 /*------------------------------------------------------------------*/
609 /* octalEscape - process an octal constant of max three digits */
610 /* return the octal value, throw a warning for illegal octal */
611 /* adjust src to point at the last proccesed char */
612 /*------------------------------------------------------------------*/
614 unsigned char octalEscape (char **str) {
618 for (digits=0; digits<3; digits++) {
619 if (**str>='0' && **str<='7') {
620 value = value*8 + (**str-'0');
627 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
628 werror (W_ESC_SEQ_OOR_FOR_CHAR);
635 /fn int copyStr (char *dest, char *src)
637 Copies a source string to a dest buffer interpreting escape sequences
638 and special characters
640 /param dest Buffer to receive the resultant string
641 /param src Buffer containing the source string with escape sequecnes
642 /return Number of characters in output string
647 copyStr (char *dest, char *src)
650 char *OriginalDest = dest ;
656 else if (*src == '\\')
691 *dest++ = octalEscape(&src);
696 *dest++ = hexEscape(&src) ;
723 return dest - OriginalDest ;
726 /*------------------------------------------------------------------*/
727 /* strVal - converts a string constant to a value */
728 /*------------------------------------------------------------------*/
734 val = newValue (); /* get a new one */
736 /* get a declarator */
737 val->type = newLink (DECLARATOR);
738 DCL_TYPE (val->type) = ARRAY;
739 val->type->next = val->etype = newLink (SPECIFIER);
740 SPEC_NOUN (val->etype) = V_CHAR;
741 SPEC_SCLS (val->etype) = S_LITERAL;
743 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
744 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
750 /*------------------------------------------------------------------*/
751 /* reverseValWithType - reverses value chain with type & etype */
752 /*------------------------------------------------------------------*/
754 reverseValWithType (value * val)
762 /* save the type * etype chains */
766 /* set the current one 2b null */
767 val->type = val->etype = NULL;
768 val = reverseVal (val);
770 /* restore type & etype */
777 /*------------------------------------------------------------------*/
778 /* reverseVal - reverses the values for a value chain */
779 /*------------------------------------------------------------------*/
781 reverseVal (value * val)
783 value *prev, *curr, *next;
798 val->next = (void *) NULL;
802 /*------------------------------------------------------------------*/
803 /* copyValueChain - will copy a chain of values */
804 /*------------------------------------------------------------------*/
806 copyValueChain (value * src)
813 dest = copyValue (src);
814 dest->next = copyValueChain (src->next);
819 /*------------------------------------------------------------------*/
820 /* copyValue - copies contents of a value to a fresh one */
821 /*------------------------------------------------------------------*/
823 copyValue (value * src)
828 dest->sym = copySymbol (src->sym);
829 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
830 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
831 dest->etype = (src->type ? getSpec (dest->type) : NULL);
836 /*------------------------------------------------------------------*/
837 /* charVal - converts a character constant to a value */
838 /*------------------------------------------------------------------*/
846 val->type = val->etype = newLink (SPECIFIER);
847 SPEC_NOUN (val->type) = V_CHAR;
848 SPEC_USIGN(val->type) = 1;
849 SPEC_SCLS (val->type) = S_LITERAL;
851 s++; /* get rid of quotation */
852 /* if \ then special processing */
855 s++; /* go beyond the backslash */
859 SPEC_CVAL (val->type).v_uint = '\n';
862 SPEC_CVAL (val->type).v_uint = '\t';
865 SPEC_CVAL (val->type).v_uint = '\v';
868 SPEC_CVAL (val->type).v_uint = '\b';
871 SPEC_CVAL (val->type).v_uint = '\r';
874 SPEC_CVAL (val->type).v_uint = '\f';
877 SPEC_CVAL (val->type).v_uint = '\a';
880 SPEC_CVAL (val->type).v_uint = '\\';
883 SPEC_CVAL (val->type).v_uint = '\?';
886 SPEC_CVAL (val->type).v_uint = '\'';
889 SPEC_CVAL (val->type).v_uint = '\"';
900 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
904 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
908 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
912 else /* not a backslash */
913 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
918 /*------------------------------------------------------------------*/
919 /* valFromType - creates a value from type given */
920 /*------------------------------------------------------------------*/
922 valFromType (sym_link * type)
924 value *val = newValue ();
925 val->type = copyLinkChain (type);
926 val->etype = getSpec (val->type);
930 /*------------------------------------------------------------------*/
931 /* floatFromVal - value to double float conversion */
932 /*------------------------------------------------------------------*/
934 floatFromVal (value * val)
939 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
941 werror (E_CONST_EXPECTED, val->name);
945 /* if it is not a specifier then we can assume that */
946 /* it will be an unsigned long */
947 if (!IS_SPEC (val->type))
948 return (double) SPEC_CVAL (val->etype).v_ulong;
950 if (SPEC_NOUN (val->etype) == V_FLOAT)
951 return (double) SPEC_CVAL (val->etype).v_float;
953 if (SPEC_LONG (val->etype))
955 if (SPEC_USIGN (val->etype))
956 return (double) SPEC_CVAL (val->etype).v_ulong;
958 return (double) SPEC_CVAL (val->etype).v_long;
961 if (SPEC_NOUN (val->etype) == V_INT) {
962 if (SPEC_USIGN (val->etype))
963 return (double) SPEC_CVAL (val->etype).v_uint;
965 return (double) SPEC_CVAL (val->etype).v_int;
968 if (SPEC_NOUN (val->etype) == V_CHAR) {
969 if (SPEC_USIGN (val->etype))
970 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
972 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
975 if (IS_BITVAR(val->etype)) {
976 return (double) SPEC_CVAL (val->etype).v_uint;
979 if (SPEC_NOUN (val->etype) == V_VOID) {
980 return (double) SPEC_CVAL (val->etype).v_ulong;
984 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
985 "floatFromVal: unknown value");
989 /*------------------------------------------------------------------*/
990 /* valUnaryPM - does the unary +/- operation on a constant */
991 /*------------------------------------------------------------------*/
993 valUnaryPM (value * val)
995 /* depending on type */
996 if (SPEC_NOUN (val->etype) == V_FLOAT)
997 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1000 if (SPEC_LONG (val->etype))
1002 if (SPEC_USIGN (val->etype))
1003 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1005 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1009 if (SPEC_USIGN (val->etype))
1010 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1012 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1015 // -(unsigned 3) now really is signed
1016 SPEC_USIGN(val->etype)=0;
1017 // -(unsigned char)135 now really is an int
1018 if (SPEC_NOUN(val->etype) == V_CHAR) {
1019 if (SPEC_CVAL(val->etype).v_int < -128) {
1020 SPEC_NOUN(val->etype) = V_INT;
1026 /*------------------------------------------------------------------*/
1027 /* valueComplement - complements a constant */
1028 /*------------------------------------------------------------------*/
1030 valComplement (value * val)
1032 /* depending on type */
1033 if (SPEC_LONG (val->etype))
1035 if (SPEC_USIGN (val->etype))
1036 SPEC_CVAL (val->etype).v_ulong = ~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 = ~SPEC_CVAL (val->etype).v_uint;
1045 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1047 // ~(unsigned 3) now really is signed
1048 SPEC_USIGN(val->etype)=0;
1052 /*------------------------------------------------------------------*/
1053 /* valueNot - complements a constant */
1054 /*------------------------------------------------------------------*/
1056 valNot (value * val)
1058 /* depending on type */
1059 if (SPEC_LONG (val->etype))
1061 if (SPEC_USIGN (val->etype))
1062 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1064 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1068 if (SPEC_USIGN (val->etype))
1069 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1071 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1076 /*------------------------------------------------------------------*/
1077 /* valMult - multiply constants */
1078 /*------------------------------------------------------------------*/
1080 valMult (value * lval, value * rval)
1084 /* create a new value */
1086 val->type = val->etype = newLink (SPECIFIER);
1087 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1088 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1089 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1090 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1091 /* both signed char and unsigned char are promoted to signed int */
1092 if (IS_CHAR (lval->etype))
1094 SPEC_USIGN (lval->etype) = 0;
1095 SPEC_NOUN (lval->etype) = V_INT;
1097 if (IS_CHAR (rval->etype))
1099 SPEC_USIGN (rval->etype) = 0;
1100 SPEC_NOUN (rval->etype) = V_INT;
1102 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1103 if (IS_FLOAT (val->type))
1104 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1105 /* signed and unsigned mul are the same, as long as the precision of the
1106 result isn't bigger than the precision of the operands. */
1107 else if (SPEC_LONG (val->type))
1108 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1109 (TYPE_UDWORD) floatFromVal (rval);
1110 else if (SPEC_USIGN (val->type)) /* unsigned */
1112 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1113 (TYPE_UWORD) floatFromVal (rval);
1115 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1116 if (ul != (TYPE_UWORD) ul)
1121 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1122 (TYPE_WORD) floatFromVal (rval);
1124 SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1125 if (l != (TYPE_WORD) l)
1128 return cheapestVal(val);
1131 /*------------------------------------------------------------------*/
1132 /* valDiv - Divide constants */
1133 /*------------------------------------------------------------------*/
1135 valDiv (value * lval, value * rval)
1139 if (floatFromVal (rval) == 0)
1141 werror (E_DIVIDE_BY_ZERO);
1145 /* create a new value */
1147 val->type = val->etype = newLink(SPECIFIER);
1148 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1149 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1150 SPEC_SCLS (val->etype) = S_LITERAL;
1151 /* both signed char and unsigned char are promoted to signed int */
1152 if (IS_CHAR (lval->etype))
1154 SPEC_USIGN (lval->etype) = 0;
1155 SPEC_NOUN (lval->etype) = V_INT;
1157 if (IS_CHAR (rval->etype))
1159 SPEC_USIGN (rval->etype) = 0;
1160 SPEC_NOUN (rval->etype) = V_INT;
1162 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1163 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1165 if (IS_FLOAT (val->type))
1166 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1169 if (SPEC_LONG (val->type))
1171 if (SPEC_USIGN (val->type))
1172 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1173 (TYPE_UDWORD) floatFromVal (rval);
1175 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1176 (TYPE_DWORD) floatFromVal (rval);
1180 if (SPEC_USIGN (val->type)) {
1181 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1182 (TYPE_UWORD) floatFromVal (rval);
1184 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1185 (TYPE_WORD) floatFromVal (rval);
1189 return cheapestVal(val);
1192 /*------------------------------------------------------------------*/
1193 /* valMod - Modulus constants */
1194 /*------------------------------------------------------------------*/
1196 valMod (value * lval, value * rval)
1200 /* create a new value */
1202 val->type = val->etype = newLink (SPECIFIER);
1203 SPEC_NOUN (val->type) = V_INT; /* type is int */
1204 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1205 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1206 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1208 if (SPEC_LONG (val->type))
1210 if (SPEC_USIGN (val->type))
1211 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1212 (TYPE_UDWORD) floatFromVal (rval);
1214 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1215 (TYPE_DWORD) floatFromVal (rval);
1219 if (SPEC_USIGN (val->type)) {
1220 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1221 (TYPE_UWORD) floatFromVal (rval);
1223 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1224 (TYPE_WORD) floatFromVal (rval);
1228 return cheapestVal(val);
1231 /*------------------------------------------------------------------*/
1232 /* valPlus - Addition constants */
1233 /*------------------------------------------------------------------*/
1235 valPlus (value * lval, value * rval)
1239 /* create a new value */
1241 val->type = val->etype = newLink (SPECIFIER);
1242 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1243 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1244 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1245 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1246 /* both signed char and unsigned char are promoted to signed int */
1247 if (IS_CHAR (lval->etype))
1249 SPEC_USIGN (lval->etype) = 0;
1250 SPEC_NOUN (lval->etype) = V_INT;
1252 if (IS_CHAR (rval->etype))
1254 SPEC_USIGN (rval->etype) = 0;
1255 SPEC_NOUN (rval->etype) = V_INT;
1257 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1258 if (IS_FLOAT (val->type))
1259 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1262 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);
1282 return cheapestVal(val);
1285 /*------------------------------------------------------------------*/
1286 /* valMinus - Addition constants */
1287 /*------------------------------------------------------------------*/
1289 valMinus (value * lval, value * rval)
1293 /* create a new value */
1295 val->type = val->etype = newLink (SPECIFIER);
1296 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1297 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1298 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1299 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1300 /* both signed char and unsigned char are promoted to signed int */
1301 if (IS_CHAR (lval->etype))
1303 SPEC_USIGN (lval->etype) = 0;
1304 SPEC_NOUN (lval->etype) = V_INT;
1306 if (IS_CHAR (rval->etype))
1308 SPEC_USIGN (rval->etype) = 0;
1309 SPEC_NOUN (rval->etype) = V_INT;
1311 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1312 if (IS_FLOAT (val->type))
1313 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1316 if (SPEC_LONG (val->type))
1318 if (SPEC_USIGN (val->type))
1319 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1320 (TYPE_UDWORD) floatFromVal (rval);
1322 SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1323 (TYPE_DWORD) floatFromVal (rval);
1327 if (SPEC_USIGN (val->type)) {
1328 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1329 (TYPE_UWORD) floatFromVal (rval);
1331 SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1332 (TYPE_WORD) floatFromVal (rval);
1336 return cheapestVal(val);
1339 /*------------------------------------------------------------------*/
1340 /* valShift - Shift left or right */
1341 /*------------------------------------------------------------------*/
1343 valShift (value * lval, value * rval, int lr)
1347 /* create a new value */
1349 val->type = val->etype = newIntLink ();
1350 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1351 SPEC_NOUN (val->etype) = V_INT;
1352 /* 'unsigned char' promotes to 'signed int' */
1353 if (!IS_CHAR (lval->etype))
1354 SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype);
1355 SPEC_LONG (val->type) = SPEC_LONG (lval->etype);
1357 if (SPEC_LONG (val->type))
1359 if (SPEC_USIGN (val->type))
1361 SPEC_CVAL (val->type).v_ulong = lr ?
1362 (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1363 (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1367 SPEC_CVAL (val->type).v_long = lr ?
1368 (TYPE_DWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1369 (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1374 if (SPEC_USIGN (val->type))
1376 SPEC_CVAL (val->type).v_uint = lr ?
1377 (TYPE_UWORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1378 (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1382 SPEC_CVAL (val->type).v_int = lr ?
1383 (TYPE_WORD) floatFromVal (lval) << (TYPE_UWORD) floatFromVal (rval) : \
1384 (TYPE_WORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval);
1387 return cheapestVal(val);
1390 /*------------------------------------------------------------------*/
1391 /* valCompare- Compares two literal */
1392 /*------------------------------------------------------------------*/
1394 valCompare (value * lval, value * rval, int ctype)
1398 /* create a new value */
1400 val->type = val->etype = newCharLink ();
1401 val->type->class = SPECIFIER;
1402 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1403 SPEC_USIGN (val->type) = 1;
1404 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1409 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1413 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1417 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1421 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1425 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1426 SPEC_NOUN(rval->type) == V_FLOAT)
1428 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1432 /* integrals: ignore signedness */
1435 l = (TYPE_UDWORD) floatFromVal (lval);
1436 if (SPEC_NOUN(lval->type) == V_CHAR)
1437 l &= 0xffff; /* promote to int */
1438 else if (!SPEC_LONG (lval->type))
1441 r = (TYPE_UDWORD) floatFromVal (rval);
1442 if (SPEC_NOUN(rval->type) == V_CHAR)
1443 r &= 0xffff; /* promote to int */
1444 else if (!SPEC_LONG (rval->type))
1447 SPEC_CVAL (val->type).v_int = l == r;
1451 if (SPEC_NOUN(lval->type) == V_FLOAT ||
1452 SPEC_NOUN(rval->type) == V_FLOAT)
1454 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1458 /* integrals: ignore signedness */
1461 l = (TYPE_UDWORD) floatFromVal (lval);
1462 if (SPEC_NOUN(lval->type) == V_CHAR)
1463 l &= 0xffff; /* promote to int */
1464 else if (!SPEC_LONG (lval->type))
1467 r = (TYPE_UDWORD) floatFromVal (rval);
1468 if (SPEC_NOUN(rval->type) == V_CHAR)
1469 r &= 0xffff; /* promote to int */
1470 else if (!SPEC_LONG (rval->type))
1473 SPEC_CVAL (val->type).v_int = l != r;
1482 /*------------------------------------------------------------------*/
1483 /* valBitwise - Bitwise operation */
1484 /*------------------------------------------------------------------*/
1486 valBitwise (value * lval, value * rval, int op)
1490 /* create a new value */
1492 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1493 rval->type : lval->type);
1494 val->etype = getSpec (val->type);
1499 if (SPEC_LONG (val->type))
1501 if (SPEC_USIGN (val->type))
1502 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1503 (unsigned long) floatFromVal (rval);
1505 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1506 (long) floatFromVal (rval);
1510 if (SPEC_USIGN (val->type))
1511 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1512 (unsigned) floatFromVal (rval);
1514 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1519 if (SPEC_LONG (val->type))
1521 if (SPEC_USIGN (val->type))
1522 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1523 (unsigned long) floatFromVal (rval);
1525 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1526 (long) floatFromVal (rval);
1530 if (SPEC_USIGN (val->type))
1531 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1532 (unsigned) floatFromVal (rval);
1534 SPEC_CVAL (val->type).v_int =
1535 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1541 if (SPEC_LONG (val->type))
1543 if (SPEC_USIGN (val->type))
1544 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1545 (unsigned long) floatFromVal (rval);
1547 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1548 (long) floatFromVal (rval);
1552 if (SPEC_USIGN (val->type))
1553 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1554 (unsigned) floatFromVal (rval);
1556 SPEC_CVAL (val->type).v_int =
1557 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1562 return cheapestVal(val);
1565 /*------------------------------------------------------------------*/
1566 /* valAndOr - Generates code for and / or operation */
1567 /*------------------------------------------------------------------*/
1569 valLogicAndOr (value * lval, value * rval, int op)
1573 /* create a new value */
1575 val->type = val->etype = newCharLink ();
1576 val->type->class = SPECIFIER;
1577 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1578 SPEC_USIGN (val->type) = 0;
1583 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1587 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1595 /*------------------------------------------------------------------*/
1596 /* valCastLiteral - casts a literal value to another type */
1597 /*------------------------------------------------------------------*/
1599 valCastLiteral (sym_link * dtype, double fval)
1602 TYPE_UDWORD l = (TYPE_UDWORD)fval;
1608 val->etype = getSpec (val->type = copyLinkChain (dtype));
1609 SPEC_SCLS (val->etype) = S_LITERAL;
1611 /* if it is not a specifier then we can assume that */
1612 /* it will be an unsigned long */
1613 if (!IS_SPEC (val->type)) {
1614 SPEC_CVAL (val->etype).v_ulong = l;
1618 if (SPEC_NOUN (val->etype) == V_FLOAT)
1619 SPEC_CVAL (val->etype).v_float = fval;
1620 else if (SPEC_NOUN (val->etype) == V_CHAR) {
1621 if (SPEC_USIGN (val->etype))
1622 SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1624 SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1626 if (SPEC_LONG (val->etype)) {
1627 if (SPEC_USIGN (val->etype))
1628 SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1630 SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1632 if (SPEC_USIGN (val->etype))
1633 SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1635 SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1641 /*------------------------------------------------------------------*/
1642 /* getNelements - determines # of elements from init list */
1643 /*------------------------------------------------------------------*/
1645 getNelements (sym_link * type, initList * ilist)
1652 if (ilist->type == INIT_DEEP)
1653 ilist = ilist->init.deep;
1655 /* if type is a character array and there is only one
1656 (string) initialiser then get the length of the string */
1657 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1659 ast *iast = ilist->init.node;
1660 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1663 werror (E_CONST_EXPECTED);
1667 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1668 // yep, it's a string
1670 return DCL_ELEM (v->type);
1678 ilist = ilist->next;
1683 /*-----------------------------------------------------------------*/
1684 /* valForArray - returns a value with name of array index */
1685 /*-----------------------------------------------------------------*/
1687 valForArray (ast * arrExpr)
1689 value *val, *lval = NULL;
1691 int size = getSize (arrExpr->left->ftype->next);
1692 /* if the right or left is an array
1694 if (IS_AST_OP (arrExpr->left))
1696 if (arrExpr->left->opval.op == '[')
1697 lval = valForArray (arrExpr->left);
1698 else if (arrExpr->left->opval.op == '.')
1699 lval = valForStructElem (arrExpr->left->left,
1700 arrExpr->left->right);
1701 else if (arrExpr->left->opval.op == PTR_OP &&
1702 IS_ADDRESS_OF_OP (arrExpr->left->left))
1703 lval = valForStructElem (arrExpr->left->left->left,
1704 arrExpr->left->right);
1709 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1712 if (!IS_AST_LIT_VALUE (arrExpr->right))
1718 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1722 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1725 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1726 (int) AST_LIT_VALUE (arrExpr->right) * size);
1728 val->type = newLink (DECLARATOR);
1729 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1730 DCL_TYPE (val->type) = CPOINTER;
1731 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1732 DCL_TYPE (val->type) = FPOINTER;
1733 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1734 DCL_TYPE (val->type) = PPOINTER;
1735 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1736 DCL_TYPE (val->type) = IPOINTER;
1737 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1738 DCL_TYPE (val->type) = EEPPOINTER;
1740 DCL_TYPE (val->type) = POINTER;
1741 val->type->next = arrExpr->left->ftype;
1742 val->etype = getSpec (val->type);
1746 /*-----------------------------------------------------------------*/
1747 /* valForStructElem - returns value with name of struct element */
1748 /*-----------------------------------------------------------------*/
1750 valForStructElem (ast * structT, ast * elemT)
1752 value *val, *lval = NULL;
1756 /* left could be furthur derefed */
1757 if (IS_AST_OP (structT))
1759 if (structT->opval.op == '[')
1760 lval = valForArray (structT);
1761 else if (structT->opval.op == '.')
1762 lval = valForStructElem (structT->left, structT->right);
1763 else if (structT->opval.op == PTR_OP &&
1764 IS_ADDRESS_OF_OP (structT->left))
1765 lval = valForStructElem (structT->left->left,
1771 if (!IS_AST_SYM_VALUE (elemT))
1774 if (!IS_STRUCT (structT->etype))
1777 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1778 AST_SYMBOL (elemT))) == NULL)
1786 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1790 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1793 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1796 val->type = newLink (DECLARATOR);
1797 if (SPEC_SCLS (structT->etype) == S_CODE)
1798 DCL_TYPE (val->type) = CPOINTER;
1799 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1800 DCL_TYPE (val->type) = FPOINTER;
1801 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1802 DCL_TYPE (val->type) = PPOINTER;
1803 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1804 DCL_TYPE (val->type) = IPOINTER;
1805 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1806 DCL_TYPE (val->type) = EEPPOINTER;
1808 DCL_TYPE (val->type) = POINTER;
1809 val->type->next = sym->type;
1810 val->etype = getSpec (val->type);
1814 /*-----------------------------------------------------------------*/
1815 /* valForCastAggr - will return value for a cast of an aggregate */
1816 /* plus minus a constant */
1817 /*-----------------------------------------------------------------*/
1819 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1823 if (!IS_AST_SYM_VALUE (aexpr))
1825 if (!IS_AST_LIT_VALUE (cnst))
1830 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1831 AST_SYMBOL (aexpr)->rname, op,
1832 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1835 val->etype = getSpec (val->type);
1839 /*-----------------------------------------------------------------*/
1840 /* valForCastAggr - will return value for a cast of an aggregate */
1841 /* with no constant */
1842 /*-----------------------------------------------------------------*/
1844 valForCastArr (ast * aexpr, sym_link * type)
1848 if (!IS_AST_SYM_VALUE (aexpr))
1853 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1854 AST_SYMBOL (aexpr)->rname);
1857 val->etype = getSpec (val->type);