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 = yylineno;
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);
307 sprintf (val->name, "%s", sym->rname);
309 sprintf (val->name, "_%s", sym->name);
315 /*--------------------------------------------------------------------*/
316 /* cheapestVal - convert a val to the cheapest as possible value */
317 /*--------------------------------------------------------------------*/
318 value *cheapestVal (value *val) {
320 unsigned long uval=0;
322 if (IS_FLOAT(val->type) || IS_CHAR(val->type))
325 if (SPEC_LONG(val->type)) {
326 if (SPEC_USIGN(val->type)) {
327 uval=SPEC_CVAL(val->type).v_ulong;
329 sval=SPEC_CVAL(val->type).v_long;
332 if (SPEC_USIGN(val->type)) {
333 uval=SPEC_CVAL(val->type).v_uint;
335 sval=SPEC_CVAL(val->type).v_int;
339 if (SPEC_USIGN(val->type)) {
341 SPEC_LONG(val->type)=0;
342 SPEC_CVAL(val->type).v_uint = uval;
345 SPEC_NOUN(val->type)=V_CHAR;
347 } else { // not unsigned
350 SPEC_LONG(val->type)=0;
351 SPEC_CVAL(val->type).v_int = sval & 0xffff;
354 SPEC_NOUN(val->type)=V_CHAR;
355 SPEC_CVAL(val->type).v_int &= 0xff;
358 SPEC_USIGN(val->type)=1;
360 SPEC_LONG(val->type)=0;
361 SPEC_CVAL(val->type).v_int = sval;
364 SPEC_NOUN(val->type)=V_CHAR;
371 /*-----------------------------------------------------------------*/
372 /* valueFromLit - creates a value from a literal */
373 /*-----------------------------------------------------------------*/
375 valueFromLit (double lit)
379 if ((((long) lit) - lit) == 0)
381 sprintf (buffer, "%ld", (long) lit);
382 return constVal (buffer);
385 sprintf (buffer, "%f", lit);
386 return constFloatVal (buffer);
389 /*-----------------------------------------------------------------*/
390 /* constFloatVal - converts a FLOAT constant to value */
391 /*-----------------------------------------------------------------*/
393 constFloatVal (char *s)
395 value *val = newValue ();
398 if (sscanf (s, "%lf", &sval) != 1)
400 werror (E_INVALID_FLOAT_CONST, s);
401 return constVal ("0");
404 val->type = val->etype = newLink ();
405 val->type->class = 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 (); /* create the spcifier */
427 val->type->class = SPECIFIER;
428 SPEC_SCLS (val->type) = S_LITERAL;
429 // let's start with an unsigned char
430 SPEC_NOUN (val->type) = V_CHAR;
431 SPEC_USIGN (val->type) = 1;
433 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
435 /* set the octal flag */
436 if (!hex && *s == '0' && *(s + 1))
439 /* create the scan string */
440 scanFmt[scI++] = '%';
442 scanFmt[scI++] = 'l';
445 scanFmt[scI++] = 'o';
447 scanFmt[scI++] = 'x';
449 scanFmt[scI++] = 'd';
451 scanFmt[scI++] = '\0';
453 sscanf (s, scanFmt, &sval);
455 /* Setup the flags first */
456 /* set the _long flag if 'lL' is found */
457 if (strchr (s, 'l') || strchr (s, 'L'))
458 SPEC_LONG (val->type) = 1;
460 if (sval<0) { // "-28u" will still be signed and negative
461 SPEC_USIGN (val->type) = 0;
462 if (sval<-32768) { // check if we have to promote to long
463 SPEC_NOUN (val->type) = V_INT;
464 SPEC_LONG (val->type) = 1;
466 if (sval<-128) { // check if we have to promote to int
467 SPEC_NOUN (val->type) = V_INT;
471 if (sval>0xffff) { // check if we have to promote to long
472 SPEC_NOUN (val->type) = V_INT;
473 SPEC_LONG (val->type) = 1;
475 if (sval>0xff) { // check if we have to promote to int
476 SPEC_NOUN (val->type) = V_INT;
481 if (SPEC_LONG (val->type))
483 if (SPEC_USIGN (val->type))
485 SPEC_CVAL (val->type).v_ulong = sval;
489 SPEC_CVAL (val->type).v_long = sval;
494 if (SPEC_USIGN (val->type))
496 SPEC_CVAL (val->type).v_uint = sval;
500 SPEC_CVAL (val->type).v_int = sval;
507 /*! /fn char hexEscape(char **src)
509 /param src Pointer to 'x' from start of hex character value
512 unsigned char hexEscape(char **src)
515 unsigned long value ;
517 (*src)++ ; /* Skip over the 'x' */
518 s = *src ; /* Save for error detection */
520 value = strtol (*src, src, 16);
523 // no valid hex found
524 werror(E_INVALID_HEX);
527 werror(W_ESC_SEQ_OOR_FOR_CHAR);
533 /*------------------------------------------------------------------*/
534 /* octalEscape - process an octal constant of max three digits */
535 /* return the octal value, throw a warning for illegal octal */
536 /* adjust src to point at the last proccesed char */
537 /*------------------------------------------------------------------*/
539 unsigned char octalEscape (char **str) {
543 for (digits=0; digits<3; digits++) {
544 if (**str>='0' && **str<='7') {
545 value = value*8 + (**str-'0');
552 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
553 werror (W_ESC_SEQ_OOR_FOR_CHAR);
560 /fn int copyStr (char *dest, char *src)
562 Copies a source string to a dest buffer interpreting escape sequences
563 and special characters
565 /param dest Buffer to receive the resultant string
566 /param src Buffer containing the source string with escape sequecnes
567 /return Number of characters in output string
572 copyStr (char *dest, char *src)
575 char *OriginalDest = dest ;
581 else if (*src == '\\')
616 *dest++ = octalEscape(&src);
621 *dest++ = hexEscape(&src) ;
648 return dest - OriginalDest ;
651 /*------------------------------------------------------------------*/
652 /* strVal - converts a string constant to a value */
653 /*------------------------------------------------------------------*/
659 val = newValue (); /* get a new one */
661 /* get a declarator */
662 val->type = newLink ();
663 DCL_TYPE (val->type) = ARRAY;
664 val->type->next = val->etype = newLink ();
665 val->etype->class = SPECIFIER;
666 SPEC_NOUN (val->etype) = V_CHAR;
667 SPEC_SCLS (val->etype) = S_LITERAL;
669 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
670 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
676 /*------------------------------------------------------------------*/
677 /* reverseValWithType - reverses value chain with type & etype */
678 /*------------------------------------------------------------------*/
680 reverseValWithType (value * val)
688 /* save the type * etype chains */
692 /* set the current one 2b null */
693 val->type = val->etype = NULL;
694 val = reverseVal (val);
696 /* restore type & etype */
703 /*------------------------------------------------------------------*/
704 /* reverseVal - reverses the values for a value chain */
705 /*------------------------------------------------------------------*/
707 reverseVal (value * val)
709 value *prev, *curr, *next;
724 val->next = (void *) NULL;
728 /*------------------------------------------------------------------*/
729 /* copyValueChain - will copy a chain of values */
730 /*------------------------------------------------------------------*/
732 copyValueChain (value * src)
739 dest = copyValue (src);
740 dest->next = copyValueChain (src->next);
745 /*------------------------------------------------------------------*/
746 /* copyValue - copies contents of a value to a fresh one */
747 /*------------------------------------------------------------------*/
749 copyValue (value * src)
754 dest->sym = copySymbol (src->sym);
755 strcpy (dest->name, src->name);
756 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
757 dest->etype = (src->type ? getSpec (dest->type) : NULL);
762 /*------------------------------------------------------------------*/
763 /* charVal - converts a character constant to a value */
764 /*------------------------------------------------------------------*/
773 val->type = val->etype = newLink ();
774 val->type->class = SPECIFIER;
775 SPEC_NOUN (val->type) = V_CHAR;
776 SPEC_USIGN(val->type) = 1;
777 SPEC_SCLS (val->type) = S_LITERAL;
779 s++; /* get rid of quotation */
780 /* if \ then special processing */
783 s++; /* go beyond the backslash */
787 SPEC_CVAL (val->type).v_int = '\n';
790 SPEC_CVAL (val->type).v_int = '\t';
793 SPEC_CVAL (val->type).v_int = '\v';
796 SPEC_CVAL (val->type).v_int = '\b';
799 SPEC_CVAL (val->type).v_int = '\r';
802 SPEC_CVAL (val->type).v_int = '\f';
805 SPEC_CVAL (val->type).v_int = '\a';
808 SPEC_CVAL (val->type).v_int = '\\';
811 SPEC_CVAL (val->type).v_int = '\?';
814 SPEC_CVAL (val->type).v_int = '\'';
817 SPEC_CVAL (val->type).v_int = '\"';
828 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
832 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
836 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
840 else /* not a backslash */
841 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
846 /*------------------------------------------------------------------*/
847 /* valFromType - creates a value from type given */
848 /*------------------------------------------------------------------*/
850 valFromType (sym_link * type)
852 value *val = newValue ();
853 val->type = copyLinkChain (type);
854 val->etype = getSpec (val->type);
858 /*------------------------------------------------------------------*/
859 /* floatFromVal - value to unsinged integer conversion */
860 /*------------------------------------------------------------------*/
862 floatFromVal (value * val)
867 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
869 werror (E_CONST_EXPECTED, val->name);
873 /* if it is not a specifier then we can assume that */
874 /* it will be an unsigned long */
875 if (!IS_SPEC (val->type))
876 return (double) SPEC_CVAL (val->etype).v_ulong;
878 if (SPEC_NOUN (val->etype) == V_FLOAT)
879 return (double) SPEC_CVAL (val->etype).v_float;
881 if (SPEC_LONG (val->etype))
883 if (SPEC_USIGN (val->etype))
884 return (double) SPEC_CVAL (val->etype).v_ulong;
886 return (double) SPEC_CVAL (val->etype).v_long;
889 if (SPEC_NOUN(val->etype)==V_INT) {
890 if (SPEC_USIGN (val->etype))
891 return (double) SPEC_CVAL (val->etype).v_uint;
893 return (double) SPEC_CVAL (val->etype).v_int;
894 } else { // SPEC_NOUN==V_CHAR
895 if (SPEC_USIGN (val->etype))
896 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
898 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
903 /*------------------------------------------------------------------*/
904 /* valUnaryPM - does the unary +/- operation on a constant */
905 /*------------------------------------------------------------------*/
907 valUnaryPM (value * val)
909 /* depending on type */
910 if (SPEC_NOUN (val->etype) == V_FLOAT)
911 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
914 if (SPEC_LONG (val->etype))
916 if (SPEC_USIGN (val->etype))
917 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
919 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
923 if (SPEC_USIGN (val->etype))
924 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
926 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
927 if (SPEC_NOUN (val->etype)==V_CHAR) {
928 SPEC_CVAL (val->etype).v_uint &= 0xff;
932 // -(unsigned 3) now really is signed
933 SPEC_USIGN(val->etype)=0;
937 /*------------------------------------------------------------------*/
938 /* valueComplement - complements a constant */
939 /*------------------------------------------------------------------*/
941 valComplement (value * val)
943 /* depending on type */
944 if (SPEC_LONG (val->etype))
946 if (SPEC_USIGN (val->etype))
947 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
949 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
953 if (SPEC_USIGN (val->etype))
954 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
956 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
957 if (SPEC_NOUN (val->etype)==V_CHAR) {
958 SPEC_CVAL (val->etype).v_uint &= 0xff;
964 /*------------------------------------------------------------------*/
965 /* valueNot - complements a constant */
966 /*------------------------------------------------------------------*/
970 /* depending on type */
971 if (SPEC_LONG (val->etype))
973 if (SPEC_USIGN (val->etype))
974 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
976 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
980 if (SPEC_USIGN (val->etype))
981 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
983 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
984 if (SPEC_NOUN (val->etype)==V_CHAR) {
985 SPEC_CVAL (val->etype).v_uint &= 0xff;
991 /*------------------------------------------------------------------*/
992 /* valMult - multiply constants */
993 /*------------------------------------------------------------------*/
995 valMult (value * lval, value * rval)
999 /* create a new value */
1001 val->type = val->etype = newLink ();
1002 val->type->class = SPECIFIER;
1003 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1004 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1005 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1006 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1007 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1009 if (IS_FLOAT (val->type))
1010 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1013 if (SPEC_LONG (val->type))
1015 if (SPEC_USIGN (val->type))
1016 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1017 (unsigned long) floatFromVal (rval);
1019 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1020 (long) floatFromVal (rval);
1024 if (SPEC_USIGN (val->type))
1025 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
1026 (unsigned) floatFromVal (rval);
1028 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1029 (int) floatFromVal (rval);
1032 return cheapestVal(val);
1035 /*------------------------------------------------------------------*/
1036 /* valDiv - Divide constants */
1037 /*------------------------------------------------------------------*/
1039 valDiv (value * lval, value * rval)
1043 if (floatFromVal (rval) == 0)
1045 werror (E_DIVIDE_BY_ZERO);
1049 /* create a new value */
1051 val->type = val->etype = newLink();
1052 val->type->class = SPECIFIER;
1053 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1054 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1055 SPEC_SCLS (val->etype) = S_LITERAL;
1056 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1057 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1059 if (IS_FLOAT (val->type))
1060 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1063 if (SPEC_LONG (val->type))
1065 if (SPEC_USIGN (val->type))
1066 SPEC_CVAL (val->type).v_ulong =
1067 (unsigned long) floatFromVal (lval) /
1068 (unsigned long) floatFromVal (rval);
1070 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1071 (long) floatFromVal (rval);
1075 if (SPEC_USIGN (val->type)) {
1076 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1077 (unsigned) floatFromVal (rval);
1079 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1080 (int) floatFromVal (rval);
1084 return cheapestVal(val);
1087 /*------------------------------------------------------------------*/
1088 /* valMod - Modulus constants */
1089 /*------------------------------------------------------------------*/
1091 valMod (value * lval, value * rval)
1095 /* create a new value */
1097 val->type = val->etype = newLink ();
1098 val->type->class = SPECIFIER;
1099 SPEC_NOUN (val->type) = V_INT; /* type is int */
1100 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1101 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1102 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1104 if (SPEC_LONG (val->type))
1106 if (SPEC_USIGN (val->type))
1107 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1108 (unsigned long) floatFromVal (rval);
1110 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1111 (unsigned long) floatFromVal (rval);
1115 if (SPEC_USIGN (val->type)) {
1116 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1117 (unsigned) floatFromVal (rval);
1119 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1120 (unsigned) floatFromVal (rval);
1124 return cheapestVal(val);
1127 /*------------------------------------------------------------------*/
1128 /* valPlus - Addition constants */
1129 /*------------------------------------------------------------------*/
1131 valPlus (value * lval, value * rval)
1135 /* create a new value */
1137 val->type = val->etype = newLink ();
1138 val->type->class = SPECIFIER;
1139 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1140 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1141 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1142 SPEC_USIGN (val->type) =
1143 SPEC_USIGN (lval->etype) &&
1144 SPEC_USIGN (rval->etype) &&
1145 (floatFromVal(lval)+floatFromVal(rval))>=0;
1147 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1149 if (IS_FLOAT (val->type))
1150 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1153 if (SPEC_LONG (val->type))
1155 if (SPEC_USIGN (val->type))
1156 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1157 (unsigned long) floatFromVal (rval);
1159 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1160 (long) floatFromVal (rval);
1164 if (SPEC_USIGN (val->type)) {
1165 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1166 (unsigned) floatFromVal (rval);
1168 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1169 (int) floatFromVal (rval);
1173 return cheapestVal(val);
1176 /*------------------------------------------------------------------*/
1177 /* valMinus - Addition constants */
1178 /*------------------------------------------------------------------*/
1180 valMinus (value * lval, value * rval)
1184 /* create a new value */
1186 val->type = val->etype = newLink ();
1187 val->type->class = SPECIFIER;
1188 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1189 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1190 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1191 SPEC_USIGN (val->type) =
1192 SPEC_USIGN (lval->etype) &&
1193 SPEC_USIGN (rval->etype) &&
1194 (floatFromVal(lval)-floatFromVal(rval))>=0;
1196 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1198 if (IS_FLOAT (val->type))
1199 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1202 if (SPEC_LONG (val->type))
1204 if (SPEC_USIGN (val->type)) {
1205 SPEC_CVAL (val->type).v_ulong =
1206 (unsigned long) floatFromVal (lval) -
1207 (unsigned long) floatFromVal (rval);
1209 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1210 (long) floatFromVal (rval);
1215 if (SPEC_USIGN (val->type)) {
1216 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1217 (unsigned) floatFromVal (rval);
1219 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1220 (int) floatFromVal (rval);
1224 return cheapestVal(val);
1227 /*------------------------------------------------------------------*/
1228 /* valShift - Shift left or right */
1229 /*------------------------------------------------------------------*/
1231 valShift (value * lval, value * rval, int lr)
1235 /* create a new value */
1237 val->type = val->etype = newIntLink ();
1238 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1239 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1240 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1242 if (SPEC_LONG (val->type))
1244 if (SPEC_USIGN (val->type))
1245 SPEC_CVAL (val->type).v_ulong = lr ?
1246 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1247 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1249 SPEC_CVAL (val->type).v_long = lr ?
1250 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1251 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1255 if (SPEC_USIGN (val->type)) {
1256 SPEC_CVAL (val->type).v_uint = lr ?
1257 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1258 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1260 SPEC_CVAL (val->type).v_int = lr ?
1261 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1262 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1266 return cheapestVal(val);
1269 /*------------------------------------------------------------------*/
1270 /* valCompare- Compares two literal */
1271 /*------------------------------------------------------------------*/
1273 valCompare (value * lval, value * rval, int ctype)
1277 /* create a new value */
1279 val->type = val->etype = newCharLink ();
1280 val->type->class = SPECIFIER;
1281 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1282 SPEC_USIGN (val->type) = 1;
1283 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1288 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
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);
1316 /*------------------------------------------------------------------*/
1317 /* valBitwise - Bitwise operation */
1318 /*------------------------------------------------------------------*/
1320 valBitwise (value * lval, value * rval, int op)
1324 /* create a new value */
1326 val->type = copyLinkChain (lval->type);
1327 val->etype = getSpec (val->type);
1332 if (SPEC_LONG (val->type))
1334 if (SPEC_USIGN (val->type))
1335 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1336 (unsigned long) floatFromVal (rval);
1338 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1339 (long) floatFromVal (rval);
1343 if (SPEC_USIGN (val->type))
1344 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1345 (unsigned) floatFromVal (rval);
1347 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1352 if (SPEC_LONG (val->type))
1354 if (SPEC_USIGN (val->type))
1355 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1356 (unsigned long) floatFromVal (rval);
1358 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1359 (long) floatFromVal (rval);
1363 if (SPEC_USIGN (val->type))
1364 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1365 (unsigned) floatFromVal (rval);
1367 SPEC_CVAL (val->type).v_int =
1368 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1374 if (SPEC_LONG (val->type))
1376 if (SPEC_USIGN (val->type))
1377 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1378 (unsigned long) floatFromVal (rval);
1380 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1381 (long) floatFromVal (rval);
1385 if (SPEC_USIGN (val->type))
1386 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1387 (unsigned) floatFromVal (rval);
1389 SPEC_CVAL (val->type).v_int =
1390 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1395 return cheapestVal(val);
1398 /*------------------------------------------------------------------*/
1399 /* valAndOr - Generates code for and / or operation */
1400 /*------------------------------------------------------------------*/
1402 valLogicAndOr (value * lval, value * rval, int op)
1406 /* create a new value */
1408 val->type = val->etype = newCharLink ();
1409 val->type->class = SPECIFIER;
1410 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1411 SPEC_USIGN (val->type) = 0;
1416 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1420 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1428 /*------------------------------------------------------------------*/
1429 /* valCastLiteral - casts a literal value to another type */
1430 /*------------------------------------------------------------------*/
1432 valCastLiteral (sym_link * dtype, double fval)
1440 val->etype = getSpec (val->type = copyLinkChain (dtype));
1441 SPEC_SCLS (val->etype) = S_LITERAL;
1442 /* if it is not a specifier then we can assume that */
1443 /* it will be an unsigned long */
1444 if (!IS_SPEC (val->type))
1446 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1450 if (SPEC_NOUN (val->etype) == V_FLOAT)
1451 SPEC_CVAL (val->etype).v_float = fval;
1454 if (SPEC_LONG (val->etype))
1456 if (SPEC_USIGN (val->etype))
1457 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1459 SPEC_CVAL (val->etype).v_long = (long) fval;
1463 if (SPEC_USIGN (val->etype))
1464 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1466 SPEC_CVAL (val->etype).v_int = (short)fval;
1467 if (SPEC_NOUN (val->etype)==V_CHAR) {
1468 SPEC_CVAL (val->etype).v_uint &= 0xff;
1475 /*------------------------------------------------------------------*/
1476 /* getNelements - determines # of elements from init list */
1477 /*------------------------------------------------------------------*/
1479 getNelements (sym_link * type, initList * ilist)
1481 sym_link *etype = getSpec (type);
1487 if (ilist->type == INIT_DEEP)
1488 ilist = ilist->init.deep;
1490 /* if type is a character array and there is only one
1491 (string) initialiser then get the length of the string */
1492 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1494 ast *iast = ilist->init.node;
1495 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1498 werror (W_INIT_WRONG);
1502 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1503 // yep, it's a string
1505 return DCL_ELEM (v->type);
1513 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))
1553 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1555 sprintf (buffer, "%s", lval->name);
1557 sprintf (val->name, "(%s + %d)", buffer,
1558 (int) AST_LIT_VALUE (arrExpr->right) * size);
1560 val->type = newLink ();
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)
1620 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1622 sprintf (buffer, "%s", lval->name);
1624 sprintf (val->name, "(%s + %d)", buffer,
1627 val->type = newLink ();
1628 if (SPEC_SCLS (structT->etype) == S_CODE)
1630 DCL_TYPE (val->type) = CPOINTER;
1631 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1633 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1634 DCL_TYPE (val->type) = FPOINTER;
1635 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1636 DCL_TYPE (val->type) = PPOINTER;
1637 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1638 DCL_TYPE (val->type) = IPOINTER;
1639 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1640 DCL_TYPE (val->type) = EEPPOINTER;
1642 DCL_TYPE (val->type) = POINTER;
1643 val->type->next = sym->type;
1644 val->etype = getSpec (val->type);
1648 /*-----------------------------------------------------------------*/
1649 /* valForCastAggr - will return value for a cast of an aggregate */
1650 /* plus minus a constant */
1651 /*-----------------------------------------------------------------*/
1653 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1657 if (!IS_AST_SYM_VALUE (aexpr))
1659 if (!IS_AST_LIT_VALUE (cnst))
1664 sprintf (val->name, "(%s %c %d)",
1665 AST_SYMBOL (aexpr)->rname, op,
1666 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1669 val->etype = getSpec (val->type);
1673 /*-----------------------------------------------------------------*/
1674 /* valForCastAggr - will return value for a cast of an aggregate */
1675 /* with no constant */
1676 /*-----------------------------------------------------------------*/
1678 valForCastArr (ast * aexpr, sym_link * type)
1682 if (!IS_AST_SYM_VALUE (aexpr))
1687 sprintf (val->name, "(%s)",
1688 AST_SYMBOL (aexpr)->rname);
1691 val->etype = getSpec (val->type);