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);
1047 SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1048 if (!options.lessPedantic)
1050 if (SPEC_USIGN (val->type))
1052 if (ul != SPEC_CVAL (val->type).v_uint)
1055 else /* signed result */
1057 TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1058 (TYPE_WORD) floatFromVal (rval);
1060 if (l != SPEC_CVAL (val->type).v_int)
1066 return cheapestVal(val);
1069 /*------------------------------------------------------------------*/
1070 /* valDiv - Divide constants */
1071 /*------------------------------------------------------------------*/
1073 valDiv (value * lval, value * rval)
1077 if (floatFromVal (rval) == 0)
1079 werror (E_DIVIDE_BY_ZERO);
1083 /* create a new value */
1085 val->type = val->etype = newLink(SPECIFIER);
1086 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1087 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1088 SPEC_SCLS (val->etype) = S_LITERAL;
1089 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1090 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1092 if (IS_FLOAT (val->type))
1093 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1096 if (SPEC_LONG (val->type))
1098 if (SPEC_USIGN (val->type))
1099 SPEC_CVAL (val->type).v_ulong =
1100 (unsigned long) floatFromVal (lval) /
1101 (unsigned long) floatFromVal (rval);
1103 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1104 (long) floatFromVal (rval);
1108 if (SPEC_USIGN (val->type)) {
1109 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1110 (unsigned) floatFromVal (rval);
1112 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1113 (int) floatFromVal (rval);
1117 return cheapestVal(val);
1120 /*------------------------------------------------------------------*/
1121 /* valMod - Modulus constants */
1122 /*------------------------------------------------------------------*/
1124 valMod (value * lval, value * rval)
1128 /* create a new value */
1130 val->type = val->etype = newLink (SPECIFIER);
1131 SPEC_NOUN (val->type) = V_INT; /* type is int */
1132 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1133 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1134 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1136 if (SPEC_LONG (val->type))
1138 if (SPEC_USIGN (val->type))
1139 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1140 (unsigned long) floatFromVal (rval);
1142 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1143 (unsigned long) floatFromVal (rval);
1147 if (SPEC_USIGN (val->type)) {
1148 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1149 (unsigned) floatFromVal (rval);
1151 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1152 (unsigned) floatFromVal (rval);
1156 return cheapestVal(val);
1159 /*------------------------------------------------------------------*/
1160 /* valPlus - Addition constants */
1161 /*------------------------------------------------------------------*/
1163 valPlus (value * lval, value * rval)
1167 /* create a new value */
1169 val->type = val->etype = newLink (SPECIFIER);
1170 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1171 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1172 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1173 SPEC_USIGN (val->type) =
1174 SPEC_USIGN (lval->etype) &&
1175 SPEC_USIGN (rval->etype) &&
1176 (floatFromVal(lval)+floatFromVal(rval))>=0;
1178 SPEC_LONG (val->type) = 1;
1180 if (IS_FLOAT (val->type))
1181 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1184 if (SPEC_LONG (val->type))
1186 if (SPEC_USIGN (val->type))
1187 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1188 (unsigned long) floatFromVal (rval);
1190 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1191 (long) floatFromVal (rval);
1194 return cheapestVal(val);
1197 /*------------------------------------------------------------------*/
1198 /* valMinus - Addition constants */
1199 /*------------------------------------------------------------------*/
1201 valMinus (value * lval, value * rval)
1205 /* create a new value */
1207 val->type = val->etype = newLink (SPECIFIER);
1208 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1209 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1210 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1211 SPEC_USIGN (val->type) =
1212 SPEC_USIGN (lval->etype) &&
1213 SPEC_USIGN (rval->etype) &&
1214 (floatFromVal(lval)-floatFromVal(rval))>=0;
1216 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1218 if (IS_FLOAT (val->type))
1219 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1222 if (SPEC_LONG (val->type))
1224 if (SPEC_USIGN (val->type)) {
1225 SPEC_CVAL (val->type).v_ulong =
1226 (unsigned long) floatFromVal (lval) -
1227 (unsigned long) floatFromVal (rval);
1229 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1230 (long) floatFromVal (rval);
1235 if (SPEC_USIGN (val->type)) {
1236 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1237 (unsigned) floatFromVal (rval);
1239 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1240 (int) floatFromVal (rval);
1244 return cheapestVal(val);
1247 /*------------------------------------------------------------------*/
1248 /* valShift - Shift left or right */
1249 /*------------------------------------------------------------------*/
1251 valShift (value * lval, value * rval, int lr)
1255 /* create a new value */
1257 val->type = val->etype = newIntLink ();
1258 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1259 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1260 SPEC_LONG (val->type) = 1;
1262 if (SPEC_LONG (val->type))
1264 if (SPEC_USIGN (val->type))
1265 SPEC_CVAL (val->type).v_ulong = lr ?
1266 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1267 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1269 SPEC_CVAL (val->type).v_long = lr ?
1270 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1271 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1274 return cheapestVal(val);
1277 /*------------------------------------------------------------------*/
1278 /* valCompare- Compares two literal */
1279 /*------------------------------------------------------------------*/
1281 valCompare (value * lval, value * rval, int ctype)
1285 /* create a new value */
1287 val->type = val->etype = newCharLink ();
1288 val->type->class = SPECIFIER;
1289 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1290 SPEC_USIGN (val->type) = 1;
1291 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
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);
1316 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1324 /*------------------------------------------------------------------*/
1325 /* valBitwise - Bitwise operation */
1326 /*------------------------------------------------------------------*/
1328 valBitwise (value * lval, value * rval, int op)
1332 /* create a new value */
1334 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1335 rval->type : lval->type);
1336 val->etype = getSpec (val->type);
1341 if (SPEC_LONG (val->type))
1343 if (SPEC_USIGN (val->type))
1344 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1345 (unsigned long) floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1348 (long) floatFromVal (rval);
1352 if (SPEC_USIGN (val->type))
1353 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1354 (unsigned) floatFromVal (rval);
1356 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1361 if (SPEC_LONG (val->type))
1363 if (SPEC_USIGN (val->type))
1364 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1365 (unsigned long) floatFromVal (rval);
1367 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1368 (long) floatFromVal (rval);
1372 if (SPEC_USIGN (val->type))
1373 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1374 (unsigned) floatFromVal (rval);
1376 SPEC_CVAL (val->type).v_int =
1377 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1383 if (SPEC_LONG (val->type))
1385 if (SPEC_USIGN (val->type))
1386 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1387 (unsigned long) floatFromVal (rval);
1389 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1390 (long) floatFromVal (rval);
1394 if (SPEC_USIGN (val->type))
1395 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1396 (unsigned) floatFromVal (rval);
1398 SPEC_CVAL (val->type).v_int =
1399 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1404 return cheapestVal(val);
1407 /*------------------------------------------------------------------*/
1408 /* valAndOr - Generates code for and / or operation */
1409 /*------------------------------------------------------------------*/
1411 valLogicAndOr (value * lval, value * rval, int op)
1415 /* create a new value */
1417 val->type = val->etype = newCharLink ();
1418 val->type->class = SPECIFIER;
1419 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1420 SPEC_USIGN (val->type) = 0;
1425 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1429 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1437 /*------------------------------------------------------------------*/
1438 /* valCastLiteral - casts a literal value to another type */
1439 /*------------------------------------------------------------------*/
1441 valCastLiteral (sym_link * dtype, double fval)
1449 val->etype = getSpec (val->type = copyLinkChain (dtype));
1450 SPEC_SCLS (val->etype) = S_LITERAL;
1451 /* if it is not a specifier then we can assume that */
1452 /* it will be an unsigned long */
1453 if (!IS_SPEC (val->type)) {
1454 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1458 if (SPEC_NOUN (val->etype) == V_FLOAT)
1459 SPEC_CVAL (val->etype).v_float = fval;
1461 unsigned long l = (unsigned long)fval;
1462 if (SPEC_LONG (val->etype)) {
1463 if (SPEC_USIGN (val->etype))
1464 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1466 SPEC_CVAL (val->etype).v_long = (long) l;
1468 if (SPEC_USIGN (val->etype))
1469 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1471 SPEC_CVAL (val->etype).v_int = (short)l;
1477 /*------------------------------------------------------------------*/
1478 /* getNelements - determines # of elements from init list */
1479 /*------------------------------------------------------------------*/
1481 getNelements (sym_link * type, initList * ilist)
1488 if (ilist->type == INIT_DEEP)
1489 ilist = ilist->init.deep;
1491 /* if type is a character array and there is only one
1492 (string) initialiser then get the length of the string */
1493 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1495 ast *iast = ilist->init.node;
1496 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1499 werror (E_CONST_EXPECTED);
1503 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1504 // yep, it's a string
1506 return DCL_ELEM (v->type);
1514 ilist = ilist->next;
1519 /*-----------------------------------------------------------------*/
1520 /* valForArray - returns a value with name of array index */
1521 /*-----------------------------------------------------------------*/
1523 valForArray (ast * arrExpr)
1525 value *val, *lval = NULL;
1527 int size = getSize (arrExpr->left->ftype->next);
1528 /* if the right or left is an array
1530 if (IS_AST_OP (arrExpr->left))
1532 if (arrExpr->left->opval.op == '[')
1533 lval = valForArray (arrExpr->left);
1534 else if (arrExpr->left->opval.op == '.')
1535 lval = valForStructElem (arrExpr->left->left,
1536 arrExpr->left->right);
1537 else if (arrExpr->left->opval.op == PTR_OP &&
1538 IS_ADDRESS_OF_OP (arrExpr->left->left))
1539 lval = valForStructElem (arrExpr->left->left->left,
1540 arrExpr->left->right);
1545 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1548 if (!IS_AST_LIT_VALUE (arrExpr->right))
1554 SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1558 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1561 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1562 (int) AST_LIT_VALUE (arrExpr->right) * size);
1564 val->type = newLink (DECLARATOR);
1565 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1567 DCL_TYPE (val->type) = CPOINTER;
1568 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1570 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1571 DCL_TYPE (val->type) = FPOINTER;
1572 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1573 DCL_TYPE (val->type) = PPOINTER;
1574 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1575 DCL_TYPE (val->type) = IPOINTER;
1576 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1577 DCL_TYPE (val->type) = EEPPOINTER;
1579 DCL_TYPE (val->type) = POINTER;
1580 val->type->next = arrExpr->left->ftype;
1581 val->etype = getSpec (val->type);
1585 /*-----------------------------------------------------------------*/
1586 /* valForStructElem - returns value with name of struct element */
1587 /*-----------------------------------------------------------------*/
1589 valForStructElem (ast * structT, ast * elemT)
1591 value *val, *lval = NULL;
1595 /* left could be furthur derefed */
1596 if (IS_AST_OP (structT))
1598 if (structT->opval.op == '[')
1599 lval = valForArray (structT);
1600 else if (structT->opval.op == '.')
1601 lval = valForStructElem (structT->left, structT->right);
1602 else if (structT->opval.op == PTR_OP &&
1603 IS_ADDRESS_OF_OP (structT->left))
1604 lval = valForStructElem (structT->left->left,
1610 if (!IS_AST_SYM_VALUE (elemT))
1613 if (!IS_STRUCT (structT->etype))
1616 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1617 AST_SYMBOL (elemT))) == NULL)
1625 SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1629 SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1632 SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1635 val->type = newLink (DECLARATOR);
1636 if (SPEC_SCLS (structT->etype) == S_CODE)
1638 DCL_TYPE (val->type) = CPOINTER;
1639 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1641 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1642 DCL_TYPE (val->type) = FPOINTER;
1643 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1644 DCL_TYPE (val->type) = PPOINTER;
1645 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1646 DCL_TYPE (val->type) = IPOINTER;
1647 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1648 DCL_TYPE (val->type) = EEPPOINTER;
1650 DCL_TYPE (val->type) = POINTER;
1651 val->type->next = sym->type;
1652 val->etype = getSpec (val->type);
1656 /*-----------------------------------------------------------------*/
1657 /* valForCastAggr - will return value for a cast of an aggregate */
1658 /* plus minus a constant */
1659 /*-----------------------------------------------------------------*/
1661 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1665 if (!IS_AST_SYM_VALUE (aexpr))
1667 if (!IS_AST_LIT_VALUE (cnst))
1672 SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1673 AST_SYMBOL (aexpr)->rname, op,
1674 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1677 val->etype = getSpec (val->type);
1681 /*-----------------------------------------------------------------*/
1682 /* valForCastAggr - will return value for a cast of an aggregate */
1683 /* with no constant */
1684 /*-----------------------------------------------------------------*/
1686 valForCastArr (ast * aexpr, sym_link * type)
1690 if (!IS_AST_SYM_VALUE (aexpr))
1695 SNPRINTF (val->name, sizeof(val->name), "(%s)",
1696 AST_SYMBOL (aexpr)->rname);
1699 val->etype = getSpec (val->type);