1 /*----------------------------------------------------------------------
2 SDCCval.c :- has routine to do all kinds of fun stuff with the
3 value wrapper & with initialiser lists.
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value */
36 /*-----------------------------------------------------------------*/
42 val = Safe_alloc (sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_alloc (sizeof (initList));
59 nilist->lineno = mylineno;
64 nilist->init.node = (struct ast *) ilist;
68 nilist->init.deep = (struct initList *) ilist;
75 /*------------------------------------------------------------------*/
76 /* revinit - reverses the initial values for a value chain */
77 /*------------------------------------------------------------------*/
79 revinit (initList * val)
81 initList *prev, *curr, *next;
96 val->next = (void *) NULL;
101 convertIListToConstList(initList *src, literalList **lList)
104 literalList *head, *last, *newL;
108 if (!src || src->type != INIT_DEEP)
113 iLoop = src->init.deep;
117 if (iLoop->type != INIT_NODE)
122 if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
129 // We've now established that the initializer list contains only literal values.
131 iLoop = src->init.deep;
134 double val = AST_LIT_VALUE(iLoop->init.node);
136 if (last && last->literalValue == val)
142 newL = Safe_alloc(sizeof(literalList));
143 newL->literalValue = val;
170 copyLiteralList(literalList *src)
172 literalList *head, *prev, *newL;
178 newL = Safe_alloc(sizeof(literalList));
180 newL->literalValue = src->literalValue;
181 newL->count = src->count;
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list */
203 /*------------------------------------------------------------------*/
205 copyIlist (initList * src)
207 initList *dest = NULL;
215 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218 dest = newiList (INIT_NODE, copyAst (src->init.node));
223 dest->next = copyIlist (src->next);
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value */
230 /*------------------------------------------------------------------*/
232 list2int (initList * val)
236 if (i->type == INIT_DEEP)
237 return list2int (val->init.deep);
239 return floatFromVal (constExprValue (val->init.node, TRUE));
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value */
244 /*------------------------------------------------------------------*/
246 list2val (initList * val)
251 if (val->type == INIT_DEEP)
252 return list2val (val->init.deep);
254 return constExprValue (val->init.node, TRUE);
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
261 list2expr (initList * ilist)
263 if (ilist->type == INIT_DEEP)
264 return list2expr (ilist->init.deep);
265 return ilist->init.node;
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values */
270 /*------------------------------------------------------------------*/
272 resolveIvalSym (initList * ilist)
277 if (ilist->type == INIT_NODE)
278 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
280 if (ilist->type == INIT_DEEP)
281 resolveIvalSym (ilist->init.deep);
283 resolveIvalSym (ilist->next);
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol */
288 /*-----------------------------------------------------------------*/
290 symbolVal (symbol * sym)
302 val->type = sym->type;
303 val->etype = getSpec (val->type);
308 SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
312 SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
318 /*--------------------------------------------------------------------*/
319 /* cheapestVal - convert a val to the cheapest as possible value */
320 /*--------------------------------------------------------------------*/
321 static value *cheapestVal (value *val) {
325 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
328 if (SPEC_LONG(val->type)) {
329 if (SPEC_USIGN(val->type)) {
330 uval=SPEC_CVAL(val->type).v_ulong;
332 sval=SPEC_CVAL(val->type).v_long;
335 if (SPEC_USIGN(val->type)) {
336 uval=SPEC_CVAL(val->type).v_uint;
338 sval=SPEC_CVAL(val->type).v_int;
342 if (SPEC_USIGN(val->type)) {
344 SPEC_LONG(val->type)=0;
345 SPEC_CVAL(val->type).v_uint = (TYPE_UWORD)uval;
347 SPEC_NOUN(val->type)=V_CHAR;
350 } else { // not unsigned
353 SPEC_LONG(val->type)=0;
354 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
356 SPEC_NOUN(val->type)=V_CHAR;
361 SPEC_LONG(val->type)=0;
362 SPEC_CVAL(val->type).v_int = (TYPE_WORD)sval;
364 SPEC_NOUN(val->type)=V_CHAR;
372 /*-----------------------------------------------------------------*/
373 /* valueFromLit - creates a value from a literal */
374 /*-----------------------------------------------------------------*/
376 valueFromLit (double lit)
380 if ((((TYPE_DWORD) lit) - lit) == 0)
382 SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
383 return constVal (buffer);
386 SNPRINTF (buffer, sizeof(buffer), "%f", lit);
387 return constFloatVal (buffer);
390 /*-----------------------------------------------------------------*/
391 /* constFloatVal - converts a FLOAT constant to value */
392 /*-----------------------------------------------------------------*/
394 constFloatVal (char *s)
396 value *val = newValue ();
399 if (sscanf (s, "%lf", &sval) != 1)
401 werror (E_INVALID_FLOAT_CONST, s);
402 return constVal ("0");
405 val->type = val->etype = newLink (SPECIFIER);
406 SPEC_NOUN (val->type) = V_FLOAT;
407 SPEC_SCLS (val->type) = S_LITERAL;
408 SPEC_CVAL (val->type).v_float = sval;
413 /*-----------------------------------------------------------------*/
414 /* constVal - converts an INTEGER constant into a cheapest value */
415 /*-----------------------------------------------------------------*/
416 value *constVal (char *s)
419 short hex = 0, octal = 0;
424 val = newValue (); /* alloc space for value */
426 val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
427 SPEC_SCLS (val->type) = S_LITERAL;
428 // let's start with an unsigned char
429 SPEC_NOUN (val->type) = V_CHAR;
430 SPEC_USIGN (val->type) = 0;
432 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
434 /* set the octal flag */
435 if (!hex && *s == '0' && *(s + 1))
438 /* create the scan string */
439 scanFmt[scI++] = '%';
441 scanFmt[scI++] = 'l';
444 scanFmt[scI++] = 'o';
446 scanFmt[scI++] = 'x';
448 scanFmt[scI++] = 'f';
450 scanFmt[scI++] = '\0';
454 sscanf (s, scanFmt, &sval);
456 SPEC_USIGN (val->type) = 1;
458 sscanf (s, scanFmt, &dval);
461 /* Setup the flags first */
462 /* set the _long flag if 'lL' is found */
463 if (strchr (s, 'l') || strchr (s, 'L')) {
464 SPEC_NOUN (val->type) = V_INT;
465 SPEC_LONG (val->type) = 1;
468 /* set the unsigned flag if 'uU' is found */
469 if (strchr (s, 'u') || strchr (s, 'U')) {
470 SPEC_USIGN (val->type) = 1;
473 if (dval<0) { // "-28u" will still be signed and negative
474 if (dval<-128) { // check if we have to promote to int
475 SPEC_NOUN (val->type) = V_INT;
477 if (dval<-32768) { // check if we have to promote to long int
478 SPEC_LONG (val->type) = 1;
481 if (dval>0xff && SPEC_USIGN (val->type)) { // check if we have to promote to int
482 SPEC_NOUN (val->type) = V_INT;
484 else if (dval>0x7f && !SPEC_USIGN (val->type)) { // check if we have to promote to int
485 SPEC_NOUN (val->type) = V_INT;
487 if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
488 SPEC_LONG (val->type) = 1;
490 else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
491 SPEC_LONG (val->type) = 1;
495 if (SPEC_LONG (val->type))
497 if (SPEC_USIGN (val->type))
499 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
503 SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
508 if (SPEC_USIGN (val->type))
510 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
514 SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
521 /*! /fn char hexEscape(char **src)
523 /param src Pointer to 'x' from start of hex character value
526 unsigned char hexEscape(char **src)
529 unsigned long value ;
531 (*src)++ ; /* Skip over the 'x' */
532 s = *src ; /* Save for error detection */
534 value = strtol (*src, src, 16);
537 // no valid hex found
538 werror(E_INVALID_HEX);
541 werror(W_ESC_SEQ_OOR_FOR_CHAR);
547 /*------------------------------------------------------------------*/
548 /* octalEscape - process an octal constant of max three digits */
549 /* return the octal value, throw a warning for illegal octal */
550 /* adjust src to point at the last proccesed char */
551 /*------------------------------------------------------------------*/
553 unsigned char octalEscape (char **str) {
557 for (digits=0; digits<3; digits++) {
558 if (**str>='0' && **str<='7') {
559 value = value*8 + (**str-'0');
566 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
567 werror (W_ESC_SEQ_OOR_FOR_CHAR);
574 /fn int copyStr (char *dest, char *src)
576 Copies a source string to a dest buffer interpreting escape sequences
577 and special characters
579 /param dest Buffer to receive the resultant string
580 /param src Buffer containing the source string with escape sequecnes
581 /return Number of characters in output string
586 copyStr (char *dest, char *src)
589 char *OriginalDest = dest ;
595 else if (*src == '\\')
630 *dest++ = octalEscape(&src);
635 *dest++ = hexEscape(&src) ;
662 return dest - OriginalDest ;
665 /*------------------------------------------------------------------*/
666 /* strVal - converts a string constant to a value */
667 /*------------------------------------------------------------------*/
673 val = newValue (); /* get a new one */
675 /* get a declarator */
676 val->type = newLink (DECLARATOR);
677 DCL_TYPE (val->type) = ARRAY;
678 val->type->next = val->etype = newLink (SPECIFIER);
679 SPEC_NOUN (val->etype) = V_CHAR;
680 SPEC_SCLS (val->etype) = S_LITERAL;
682 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
683 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
689 /*------------------------------------------------------------------*/
690 /* reverseValWithType - reverses value chain with type & etype */
691 /*------------------------------------------------------------------*/
693 reverseValWithType (value * val)
701 /* save the type * etype chains */
705 /* set the current one 2b null */
706 val->type = val->etype = NULL;
707 val = reverseVal (val);
709 /* restore type & etype */
716 /*------------------------------------------------------------------*/
717 /* reverseVal - reverses the values for a value chain */
718 /*------------------------------------------------------------------*/
720 reverseVal (value * val)
722 value *prev, *curr, *next;
737 val->next = (void *) NULL;
741 /*------------------------------------------------------------------*/
742 /* copyValueChain - will copy a chain of values */
743 /*------------------------------------------------------------------*/
745 copyValueChain (value * src)
752 dest = copyValue (src);
753 dest->next = copyValueChain (src->next);
758 /*------------------------------------------------------------------*/
759 /* copyValue - copies contents of a value to a fresh one */
760 /*------------------------------------------------------------------*/
762 copyValue (value * src)
767 dest->sym = copySymbol (src->sym);
768 strncpyz (dest->name, src->name, SDCC_NAME_MAX);
769 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
770 dest->etype = (src->type ? getSpec (dest->type) : NULL);
775 /*------------------------------------------------------------------*/
776 /* charVal - converts a character constant to a value */
777 /*------------------------------------------------------------------*/
785 val->type = val->etype = newLink (SPECIFIER);
786 SPEC_NOUN (val->type) = V_CHAR;
787 SPEC_USIGN(val->type) = 1;
788 SPEC_SCLS (val->type) = S_LITERAL;
790 s++; /* get rid of quotation */
791 /* if \ then special processing */
794 s++; /* go beyond the backslash */
798 SPEC_CVAL (val->type).v_uint = '\n';
801 SPEC_CVAL (val->type).v_uint = '\t';
804 SPEC_CVAL (val->type).v_uint = '\v';
807 SPEC_CVAL (val->type).v_uint = '\b';
810 SPEC_CVAL (val->type).v_uint = '\r';
813 SPEC_CVAL (val->type).v_uint = '\f';
816 SPEC_CVAL (val->type).v_uint = '\a';
819 SPEC_CVAL (val->type).v_uint = '\\';
822 SPEC_CVAL (val->type).v_uint = '\?';
825 SPEC_CVAL (val->type).v_uint = '\'';
828 SPEC_CVAL (val->type).v_uint = '\"';
839 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
843 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
847 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
851 else /* not a backslash */
852 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
857 /*------------------------------------------------------------------*/
858 /* valFromType - creates a value from type given */
859 /*------------------------------------------------------------------*/
861 valFromType (sym_link * type)
863 value *val = newValue ();
864 val->type = copyLinkChain (type);
865 val->etype = getSpec (val->type);
869 /*------------------------------------------------------------------*/
870 /* floatFromVal - value to double float conversion */
871 /*------------------------------------------------------------------*/
873 floatFromVal (value * val)
878 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
880 werror (E_CONST_EXPECTED, val->name);
884 /* if it is not a specifier then we can assume that */
885 /* it will be an unsigned long */
886 if (!IS_SPEC (val->type))
887 return (double) SPEC_CVAL (val->etype).v_ulong;
889 if (SPEC_NOUN (val->etype) == V_FLOAT)
890 return (double) SPEC_CVAL (val->etype).v_float;
892 if (SPEC_LONG (val->etype))
894 if (SPEC_USIGN (val->etype))
895 return (double) SPEC_CVAL (val->etype).v_ulong;
897 return (double) SPEC_CVAL (val->etype).v_long;
900 if (SPEC_NOUN (val->etype) == V_INT) {
901 if (SPEC_USIGN (val->etype))
902 return (double) SPEC_CVAL (val->etype).v_uint;
904 return (double) SPEC_CVAL (val->etype).v_int;
907 if (SPEC_NOUN (val->etype) == V_CHAR) {
908 if (SPEC_USIGN (val->etype))
909 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
911 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
914 if (IS_BITVAR(val->etype)) {
915 return (double) SPEC_CVAL (val->etype).v_uint;
918 if (SPEC_NOUN (val->etype) == V_VOID) {
919 return (double) SPEC_CVAL (val->etype).v_ulong;
923 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
924 "floatFromVal: unknown value");
929 /*------------------------------------------------------------------*/
930 /* valUnaryPM - does the unary +/- operation on a constant */
931 /*------------------------------------------------------------------*/
933 valUnaryPM (value * val)
935 /* depending on type */
936 if (SPEC_NOUN (val->etype) == V_FLOAT)
937 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
940 if (SPEC_LONG (val->etype))
942 if (SPEC_USIGN (val->etype))
943 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
945 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
949 if (SPEC_USIGN (val->etype))
950 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
952 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
955 // -(unsigned 3) now really is signed
956 SPEC_USIGN(val->etype)=0;
957 // -(unsigned char)135 now really is an int
958 if (SPEC_NOUN(val->etype) == V_CHAR) {
959 if (SPEC_CVAL(val->etype).v_int < -128) {
960 SPEC_NOUN(val->etype) = V_INT;
966 /*------------------------------------------------------------------*/
967 /* valueComplement - complements a constant */
968 /*------------------------------------------------------------------*/
970 valComplement (value * val)
972 /* depending on type */
973 if (SPEC_LONG (val->etype))
975 if (SPEC_USIGN (val->etype))
976 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
978 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
982 if (SPEC_USIGN (val->etype))
983 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
985 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
987 // ~(unsigned 3) now really is signed
988 SPEC_USIGN(val->etype)=0;
992 /*------------------------------------------------------------------*/
993 /* valueNot - complements a constant */
994 /*------------------------------------------------------------------*/
998 /* depending on type */
999 if (SPEC_LONG (val->etype))
1001 if (SPEC_USIGN (val->etype))
1002 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1004 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1008 if (SPEC_USIGN (val->etype))
1009 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1011 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1016 /*------------------------------------------------------------------*/
1017 /* valMult - multiply constants */
1018 /*------------------------------------------------------------------*/
1020 valMult (value * lval, value * rval)
1024 /* create a new value */
1026 val->type = val->etype = newLink (SPECIFIER);
1027 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1028 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1029 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1030 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1031 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1033 if (IS_FLOAT (val->type))
1034 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1037 /* signed and unsigned mul are the same, as long as the precision of the
1038 result isn't bigger than the precision of the operands. */
1039 if (SPEC_LONG (val->type))
1040 SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1041 (TYPE_UDWORD) floatFromVal (rval);
1044 TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1045 (TYPE_UWORD) floatFromVal (rval);
1046 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1047 if (!options.lessPedantic)
1049 if (SPEC_USIGN (val->type))
1051 if (ul != SPEC_CVAL (val->type).v_uint)
1054 else /* signed result */
1056 if ((TYPE_DWORD) ul != SPEC_CVAL (val->type).v_int)
1062 return cheapestVal(val);
1065 /*------------------------------------------------------------------*/
1066 /* valDiv - Divide constants */
1067 /*------------------------------------------------------------------*/
1069 valDiv (value * lval, value * rval)
1073 if (floatFromVal (rval) == 0)
1075 werror (E_DIVIDE_BY_ZERO);
1079 /* create a new value */
1081 val->type = val->etype = newLink(SPECIFIER);
1082 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1083 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1084 SPEC_SCLS (val->etype) = S_LITERAL;
1085 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1086 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1088 if (IS_FLOAT (val->type))
1089 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1092 if (SPEC_LONG (val->type))
1094 if (SPEC_USIGN (val->type))
1095 SPEC_CVAL (val->type).v_ulong =
1096 (unsigned long) floatFromVal (lval) /
1097 (unsigned long) floatFromVal (rval);
1099 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1100 (long) floatFromVal (rval);
1104 if (SPEC_USIGN (val->type)) {
1105 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1106 (unsigned) floatFromVal (rval);
1108 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1109 (int) floatFromVal (rval);
1113 return cheapestVal(val);
1116 /*------------------------------------------------------------------*/
1117 /* valMod - Modulus constants */
1118 /*------------------------------------------------------------------*/
1120 valMod (value * lval, value * rval)
1124 /* create a new value */
1126 val->type = val->etype = newLink (SPECIFIER);
1127 SPEC_NOUN (val->type) = V_INT; /* type is int */
1128 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1129 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1130 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1132 if (SPEC_LONG (val->type))
1134 if (SPEC_USIGN (val->type))
1135 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1136 (unsigned long) floatFromVal (rval);
1138 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1139 (unsigned long) floatFromVal (rval);
1143 if (SPEC_USIGN (val->type)) {
1144 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1145 (unsigned) floatFromVal (rval);
1147 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1148 (unsigned) floatFromVal (rval);
1152 return cheapestVal(val);
1155 /*------------------------------------------------------------------*/
1156 /* valPlus - Addition constants */
1157 /*------------------------------------------------------------------*/
1159 valPlus (value * lval, value * rval)
1163 /* create a new value */
1165 val->type = val->etype = newLink (SPECIFIER);
1166 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1167 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1168 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1169 SPEC_USIGN (val->type) =
1170 SPEC_USIGN (lval->etype) &&
1171 SPEC_USIGN (rval->etype) &&
1172 (floatFromVal(lval)+floatFromVal(rval))>=0;
1174 SPEC_LONG (val->type) = 1;
1176 if (IS_FLOAT (val->type))
1177 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1180 if (SPEC_LONG (val->type))
1182 if (SPEC_USIGN (val->type))
1183 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1184 (unsigned long) floatFromVal (rval);
1186 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1187 (long) floatFromVal (rval);
1190 return cheapestVal(val);
1193 /*------------------------------------------------------------------*/
1194 /* valMinus - Addition constants */
1195 /*------------------------------------------------------------------*/
1197 valMinus (value * lval, value * rval)
1201 /* create a new value */
1203 val->type = val->etype = newLink (SPECIFIER);
1204 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1205 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1206 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1207 SPEC_USIGN (val->type) =
1208 SPEC_USIGN (lval->etype) &&
1209 SPEC_USIGN (rval->etype) &&
1210 (floatFromVal(lval)-floatFromVal(rval))>=0;
1212 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1214 if (IS_FLOAT (val->type))
1215 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1218 if (SPEC_LONG (val->type))
1220 if (SPEC_USIGN (val->type)) {
1221 SPEC_CVAL (val->type).v_ulong =
1222 (unsigned long) floatFromVal (lval) -
1223 (unsigned long) floatFromVal (rval);
1225 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1226 (long) floatFromVal (rval);
1231 if (SPEC_USIGN (val->type)) {
1232 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1233 (unsigned) floatFromVal (rval);
1235 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1236 (int) floatFromVal (rval);
1240 return cheapestVal(val);
1243 /*------------------------------------------------------------------*/
1244 /* valShift - Shift left or right */
1245 /*------------------------------------------------------------------*/
1247 valShift (value * lval, value * rval, int lr)
1251 /* create a new value */
1253 val->type = val->etype = newIntLink ();
1254 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1255 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1256 SPEC_LONG (val->type) = 1;
1258 if (SPEC_LONG (val->type))
1260 if (SPEC_USIGN (val->type))
1261 SPEC_CVAL (val->type).v_ulong = lr ?
1262 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1263 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1265 SPEC_CVAL (val->type).v_long = lr ?
1266 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1267 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1270 return cheapestVal(val);
1273 /*------------------------------------------------------------------*/
1274 /* valCompare- Compares two literal */
1275 /*------------------------------------------------------------------*/
1277 valCompare (value * lval, value * rval, int ctype)
1281 /* create a new value */
1283 val->type = val->etype = newCharLink ();
1284 val->type->class = SPECIFIER;
1285 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1286 SPEC_USIGN (val->type) = 1;
1287 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1292 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1296 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1300 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1304 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1308 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1312 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1320 /*------------------------------------------------------------------*/
1321 /* valBitwise - Bitwise operation */
1322 /*------------------------------------------------------------------*/
1324 valBitwise (value * lval, value * rval, int op)
1328 /* create a new value */
1330 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1331 rval->type : lval->type);
1332 val->etype = getSpec (val->type);
1337 if (SPEC_LONG (val->type))
1339 if (SPEC_USIGN (val->type))
1340 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1341 (unsigned long) floatFromVal (rval);
1343 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1344 (long) floatFromVal (rval);
1348 if (SPEC_USIGN (val->type))
1349 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1350 (unsigned) floatFromVal (rval);
1352 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1357 if (SPEC_LONG (val->type))
1359 if (SPEC_USIGN (val->type))
1360 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1361 (unsigned long) floatFromVal (rval);
1363 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1364 (long) floatFromVal (rval);
1368 if (SPEC_USIGN (val->type))
1369 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1370 (unsigned) floatFromVal (rval);
1372 SPEC_CVAL (val->type).v_int =
1373 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1379 if (SPEC_LONG (val->type))
1381 if (SPEC_USIGN (val->type))
1382 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1383 (unsigned long) floatFromVal (rval);
1385 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1386 (long) floatFromVal (rval);
1390 if (SPEC_USIGN (val->type))
1391 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1392 (unsigned) floatFromVal (rval);
1394 SPEC_CVAL (val->type).v_int =
1395 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1400 return cheapestVal(val);
1403 /*------------------------------------------------------------------*/
1404 /* valAndOr - Generates code for and / or operation */
1405 /*------------------------------------------------------------------*/
1407 valLogicAndOr (value * lval, value * rval, int op)
1411 /* create a new value */
1413 val->type = val->etype = newCharLink ();
1414 val->type->class = SPECIFIER;
1415 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1416 SPEC_USIGN (val->type) = 0;
1421 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1425 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1433 /*------------------------------------------------------------------*/
1434 /* valCastLiteral - casts a literal value to another type */
1435 /*------------------------------------------------------------------*/
1437 valCastLiteral (sym_link * dtype, double fval)
1445 val->etype = getSpec (val->type = copyLinkChain (dtype));
1446 SPEC_SCLS (val->etype) = S_LITERAL;
1447 /* if it is not a specifier then we can assume that */
1448 /* it will be an unsigned long */
1449 if (!IS_SPEC (val->type)) {
1450 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1454 if (SPEC_NOUN (val->etype) == V_FLOAT)
1455 SPEC_CVAL (val->etype).v_float = fval;
1457 unsigned long l = (unsigned long)fval;
1458 if (SPEC_LONG (val->etype)) {
1459 if (SPEC_USIGN (val->etype))
1460 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1462 SPEC_CVAL (val->etype).v_long = (long) l;
1464 if (SPEC_USIGN (val->etype))
1465 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1467 SPEC_CVAL (val->etype).v_int = (short)l;
1473 /*------------------------------------------------------------------*/
1474 /* getNelements - determines # of elements from init list */
1475 /*------------------------------------------------------------------*/
1477 getNelements (sym_link * type, initList * ilist)
1484 if (ilist->type == INIT_DEEP)
1485 ilist = ilist->init.deep;
1487 /* if type is a character array and there is only one
1488 (string) initialiser then get the length of the string */
1489 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1491 ast *iast = ilist->init.node;
1492 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1495 werror (E_CONST_EXPECTED);
1499 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1500 // yep, it's a string
1502 return DCL_ELEM (v->type);
1510 ilist = ilist->next;
1515 /*-----------------------------------------------------------------*/
1516 /* valForArray - returns a value with name of array index */
1517 /*-----------------------------------------------------------------*/
1519 valForArray (ast * arrExpr)
1521 value *val, *lval = NULL;
1523 int size = getSize (arrExpr->left->ftype->next);
1524 /* if the right or left is an array
1526 if (IS_AST_OP (arrExpr->left))
1528 if (arrExpr->left->opval.op == '[')
1529 lval = valForArray (arrExpr->left);
1530 else if (arrExpr->left->opval.op == '.')
1531 lval = valForStructElem (arrExpr->left->left,
1532 arrExpr->left->right);
1533 else if (arrExpr->left->opval.op == PTR_OP &&
1534 IS_ADDRESS_OF_OP (arrExpr->left->left))
1535 lval = valForStructElem (arrExpr->left->left->left,
1536 arrExpr->left->right);
1541 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1544 if (!IS_AST_LIT_VALUE (arrExpr->right))
1550 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1554 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1557 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1558 (int) AST_LIT_VALUE (arrExpr->right) * size);
1560 val->type = newLink (DECLARATOR);
1561 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1563 DCL_TYPE (val->type) = CPOINTER;
1564 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1566 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1567 DCL_TYPE (val->type) = FPOINTER;
1568 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1569 DCL_TYPE (val->type) = PPOINTER;
1570 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1571 DCL_TYPE (val->type) = IPOINTER;
1572 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1573 DCL_TYPE (val->type) = EEPPOINTER;
1575 DCL_TYPE (val->type) = POINTER;
1576 val->type->next = arrExpr->left->ftype;
1577 val->etype = getSpec (val->type);
1581 /*-----------------------------------------------------------------*/
1582 /* valForStructElem - returns value with name of struct element */
1583 /*-----------------------------------------------------------------*/
1585 valForStructElem (ast * structT, ast * elemT)
1587 value *val, *lval = NULL;
1591 /* left could be furthur derefed */
1592 if (IS_AST_OP (structT))
1594 if (structT->opval.op == '[')
1595 lval = valForArray (structT);
1596 else if (structT->opval.op == '.')
1597 lval = valForStructElem (structT->left, structT->right);
1598 else if (structT->opval.op == PTR_OP &&
1599 IS_ADDRESS_OF_OP (structT->left))
1600 lval = valForStructElem (structT->left->left,
1606 if (!IS_AST_SYM_VALUE (elemT))
1609 if (!IS_STRUCT (structT->etype))
1612 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1613 AST_SYMBOL (elemT))) == NULL)
1621 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1625 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1628 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1631 val->type = newLink (DECLARATOR);
1632 if (SPEC_SCLS (structT->etype) == S_CODE)
1634 DCL_TYPE (val->type) = CPOINTER;
1635 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1637 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1638 DCL_TYPE (val->type) = FPOINTER;
1639 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1640 DCL_TYPE (val->type) = PPOINTER;
1641 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1642 DCL_TYPE (val->type) = IPOINTER;
1643 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1644 DCL_TYPE (val->type) = EEPPOINTER;
1646 DCL_TYPE (val->type) = POINTER;
1647 val->type->next = sym->type;
1648 val->etype = getSpec (val->type);
1652 /*-----------------------------------------------------------------*/
1653 /* valForCastAggr - will return value for a cast of an aggregate */
1654 /* plus minus a constant */
1655 /*-----------------------------------------------------------------*/
1657 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1661 if (!IS_AST_SYM_VALUE (aexpr))
1663 if (!IS_AST_LIT_VALUE (cnst))
1668 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1669 AST_SYMBOL (aexpr)->rname, op,
1670 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1673 val->etype = getSpec (val->type);
1677 /*-----------------------------------------------------------------*/
1678 /* valForCastAggr - will return value for a cast of an aggregate */
1679 /* with no constant */
1680 /*-----------------------------------------------------------------*/
1682 valForCastArr (ast * aexpr, sym_link * type)
1686 if (!IS_AST_SYM_VALUE (aexpr))
1691 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1692 AST_SYMBOL (aexpr)->rname);
1695 val->etype = getSpec (val->type);