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_NOUN (val->type) = V_INT;
459 SPEC_LONG (val->type) = 1;
462 if (sval<0) { // "-28u" will still be signed and negative
463 SPEC_USIGN (val->type) = 0;
464 if (sval<-128) { // check if we have to promote to int
465 SPEC_NOUN (val->type) = V_INT;
467 if (sval<-32768) { // check if we have to promote to long int
468 SPEC_LONG (val->type) = 1;
471 if (sval>0xff) { // check if we have to promote to int
472 SPEC_NOUN (val->type) = V_INT;
474 if (sval>0xffff) { // check if we have to promote to long int
475 SPEC_LONG (val->type) = 1;
479 if (SPEC_LONG (val->type))
481 if (SPEC_USIGN (val->type))
483 SPEC_CVAL (val->type).v_ulong = sval;
487 SPEC_CVAL (val->type).v_long = sval;
492 if (SPEC_USIGN (val->type))
494 SPEC_CVAL (val->type).v_uint = sval;
498 SPEC_CVAL (val->type).v_int = sval;
505 /*! /fn char hexEscape(char **src)
507 /param src Pointer to 'x' from start of hex character value
510 unsigned char hexEscape(char **src)
513 unsigned long value ;
515 (*src)++ ; /* Skip over the 'x' */
516 s = *src ; /* Save for error detection */
518 value = strtol (*src, src, 16);
521 // no valid hex found
522 werror(E_INVALID_HEX);
525 werror(W_ESC_SEQ_OOR_FOR_CHAR);
531 /*------------------------------------------------------------------*/
532 /* octalEscape - process an octal constant of max three digits */
533 /* return the octal value, throw a warning for illegal octal */
534 /* adjust src to point at the last proccesed char */
535 /*------------------------------------------------------------------*/
537 unsigned char octalEscape (char **str) {
541 for (digits=0; digits<3; digits++) {
542 if (**str>='0' && **str<='7') {
543 value = value*8 + (**str-'0');
550 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
551 werror (W_ESC_SEQ_OOR_FOR_CHAR);
558 /fn int copyStr (char *dest, char *src)
560 Copies a source string to a dest buffer interpreting escape sequences
561 and special characters
563 /param dest Buffer to receive the resultant string
564 /param src Buffer containing the source string with escape sequecnes
565 /return Number of characters in output string
570 copyStr (char *dest, char *src)
573 char *OriginalDest = dest ;
579 else if (*src == '\\')
614 *dest++ = octalEscape(&src);
619 *dest++ = hexEscape(&src) ;
646 return dest - OriginalDest ;
649 /*------------------------------------------------------------------*/
650 /* strVal - converts a string constant to a value */
651 /*------------------------------------------------------------------*/
657 val = newValue (); /* get a new one */
659 /* get a declarator */
660 val->type = newLink ();
661 DCL_TYPE (val->type) = ARRAY;
662 val->type->next = val->etype = newLink ();
663 val->etype->class = SPECIFIER;
664 SPEC_NOUN (val->etype) = V_CHAR;
665 SPEC_SCLS (val->etype) = S_LITERAL;
667 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
668 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
674 /*------------------------------------------------------------------*/
675 /* reverseValWithType - reverses value chain with type & etype */
676 /*------------------------------------------------------------------*/
678 reverseValWithType (value * val)
686 /* save the type * etype chains */
690 /* set the current one 2b null */
691 val->type = val->etype = NULL;
692 val = reverseVal (val);
694 /* restore type & etype */
701 /*------------------------------------------------------------------*/
702 /* reverseVal - reverses the values for a value chain */
703 /*------------------------------------------------------------------*/
705 reverseVal (value * val)
707 value *prev, *curr, *next;
722 val->next = (void *) NULL;
726 /*------------------------------------------------------------------*/
727 /* copyValueChain - will copy a chain of values */
728 /*------------------------------------------------------------------*/
730 copyValueChain (value * src)
737 dest = copyValue (src);
738 dest->next = copyValueChain (src->next);
743 /*------------------------------------------------------------------*/
744 /* copyValue - copies contents of a value to a fresh one */
745 /*------------------------------------------------------------------*/
747 copyValue (value * src)
752 dest->sym = copySymbol (src->sym);
753 strcpy (dest->name, src->name);
754 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
755 dest->etype = (src->type ? getSpec (dest->type) : NULL);
760 /*------------------------------------------------------------------*/
761 /* charVal - converts a character constant to a value */
762 /*------------------------------------------------------------------*/
771 val->type = val->etype = newLink ();
772 val->type->class = SPECIFIER;
773 SPEC_NOUN (val->type) = V_CHAR;
774 SPEC_USIGN(val->type) = 1;
775 SPEC_SCLS (val->type) = S_LITERAL;
777 s++; /* get rid of quotation */
778 /* if \ then special processing */
781 s++; /* go beyond the backslash */
785 SPEC_CVAL (val->type).v_int = '\n';
788 SPEC_CVAL (val->type).v_int = '\t';
791 SPEC_CVAL (val->type).v_int = '\v';
794 SPEC_CVAL (val->type).v_int = '\b';
797 SPEC_CVAL (val->type).v_int = '\r';
800 SPEC_CVAL (val->type).v_int = '\f';
803 SPEC_CVAL (val->type).v_int = '\a';
806 SPEC_CVAL (val->type).v_int = '\\';
809 SPEC_CVAL (val->type).v_int = '\?';
812 SPEC_CVAL (val->type).v_int = '\'';
815 SPEC_CVAL (val->type).v_int = '\"';
826 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
830 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
834 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
838 else /* not a backslash */
839 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
844 /*------------------------------------------------------------------*/
845 /* valFromType - creates a value from type given */
846 /*------------------------------------------------------------------*/
848 valFromType (sym_link * type)
850 value *val = newValue ();
851 val->type = copyLinkChain (type);
852 val->etype = getSpec (val->type);
856 /*------------------------------------------------------------------*/
857 /* floatFromVal - value to unsinged integer conversion */
858 /*------------------------------------------------------------------*/
860 floatFromVal (value * val)
865 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
867 werror (E_CONST_EXPECTED, val->name);
871 /* if it is not a specifier then we can assume that */
872 /* it will be an unsigned long */
873 if (!IS_SPEC (val->type))
874 return (double) SPEC_CVAL (val->etype).v_ulong;
876 if (SPEC_NOUN (val->etype) == V_FLOAT)
877 return (double) SPEC_CVAL (val->etype).v_float;
879 if (SPEC_LONG (val->etype))
881 if (SPEC_USIGN (val->etype))
882 return (double) SPEC_CVAL (val->etype).v_ulong;
884 return (double) SPEC_CVAL (val->etype).v_long;
887 if (SPEC_NOUN(val->etype)==V_INT) {
888 if (SPEC_USIGN (val->etype))
889 return (double) SPEC_CVAL (val->etype).v_uint;
891 return (double) SPEC_CVAL (val->etype).v_int;
892 } else { // SPEC_NOUN==V_CHAR
893 if (SPEC_USIGN (val->etype))
894 return (double) ((unsigned char)SPEC_CVAL (val->etype).v_uint);
896 return (double) ((signed char)SPEC_CVAL (val->etype).v_int);
901 /*------------------------------------------------------------------*/
902 /* valUnaryPM - does the unary +/- operation on a constant */
903 /*------------------------------------------------------------------*/
905 valUnaryPM (value * val)
907 /* depending on type */
908 if (SPEC_NOUN (val->etype) == V_FLOAT)
909 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
912 if (SPEC_LONG (val->etype))
914 if (SPEC_USIGN (val->etype))
915 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
917 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
921 if (SPEC_USIGN (val->etype))
922 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
924 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
925 if (SPEC_NOUN (val->etype)==V_CHAR) {
926 SPEC_CVAL (val->etype).v_uint &= 0xff;
930 // -(unsigned 3) now really is signed
931 SPEC_USIGN(val->etype)=0;
935 /*------------------------------------------------------------------*/
936 /* valueComplement - complements a constant */
937 /*------------------------------------------------------------------*/
939 valComplement (value * val)
941 /* depending on type */
942 if (SPEC_LONG (val->etype))
944 if (SPEC_USIGN (val->etype))
945 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
947 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
951 if (SPEC_USIGN (val->etype))
952 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
954 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
955 if (SPEC_NOUN (val->etype)==V_CHAR) {
956 SPEC_CVAL (val->etype).v_uint &= 0xff;
962 /*------------------------------------------------------------------*/
963 /* valueNot - complements a constant */
964 /*------------------------------------------------------------------*/
968 /* depending on type */
969 if (SPEC_LONG (val->etype))
971 if (SPEC_USIGN (val->etype))
972 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
974 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
978 if (SPEC_USIGN (val->etype))
979 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
981 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
982 if (SPEC_NOUN (val->etype)==V_CHAR) {
983 SPEC_CVAL (val->etype).v_uint &= 0xff;
989 /*------------------------------------------------------------------*/
990 /* valMult - multiply constants */
991 /*------------------------------------------------------------------*/
993 valMult (value * lval, value * rval)
997 /* create a new value */
999 val->type = val->etype = newLink ();
1000 val->type->class = SPECIFIER;
1001 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1002 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1003 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1004 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1005 SPEC_LONG (val->type) = 1;
1007 if (IS_FLOAT (val->type))
1008 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1011 if (SPEC_LONG (val->type))
1013 if (SPEC_USIGN (val->type))
1014 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1015 (unsigned long) floatFromVal (rval);
1017 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1018 (long) floatFromVal (rval);
1021 return cheapestVal(val);
1024 /*------------------------------------------------------------------*/
1025 /* valDiv - Divide constants */
1026 /*------------------------------------------------------------------*/
1028 valDiv (value * lval, value * rval)
1032 if (floatFromVal (rval) == 0)
1034 werror (E_DIVIDE_BY_ZERO);
1038 /* create a new value */
1040 val->type = val->etype = newLink();
1041 val->type->class = SPECIFIER;
1042 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1043 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1044 SPEC_SCLS (val->etype) = S_LITERAL;
1045 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1046 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1048 if (IS_FLOAT (val->type))
1049 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1052 if (SPEC_LONG (val->type))
1054 if (SPEC_USIGN (val->type))
1055 SPEC_CVAL (val->type).v_ulong =
1056 (unsigned long) floatFromVal (lval) /
1057 (unsigned long) floatFromVal (rval);
1059 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1060 (long) floatFromVal (rval);
1064 if (SPEC_USIGN (val->type)) {
1065 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1066 (unsigned) floatFromVal (rval);
1068 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1069 (int) floatFromVal (rval);
1073 return cheapestVal(val);
1076 /*------------------------------------------------------------------*/
1077 /* valMod - Modulus constants */
1078 /*------------------------------------------------------------------*/
1080 valMod (value * lval, value * rval)
1084 /* create a new value */
1086 val->type = val->etype = newLink ();
1087 val->type->class = SPECIFIER;
1088 SPEC_NOUN (val->type) = V_INT; /* type is int */
1089 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1090 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1091 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1093 if (SPEC_LONG (val->type))
1095 if (SPEC_USIGN (val->type))
1096 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1097 (unsigned long) floatFromVal (rval);
1099 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1100 (unsigned 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 = (unsigned) floatFromVal (lval) %
1109 (unsigned) floatFromVal (rval);
1113 return cheapestVal(val);
1116 /*------------------------------------------------------------------*/
1117 /* valPlus - Addition constants */
1118 /*------------------------------------------------------------------*/
1120 valPlus (value * lval, value * rval)
1124 /* create a new value */
1126 val->type = val->etype = newLink ();
1127 val->type->class = SPECIFIER;
1128 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1129 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1130 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1131 SPEC_USIGN (val->type) =
1132 SPEC_USIGN (lval->etype) &&
1133 SPEC_USIGN (rval->etype) &&
1134 (floatFromVal(lval)+floatFromVal(rval))>=0;
1136 SPEC_LONG (val->type) = 1;
1138 if (IS_FLOAT (val->type))
1139 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1142 if (SPEC_LONG (val->type))
1144 if (SPEC_USIGN (val->type))
1145 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1146 (unsigned long) floatFromVal (rval);
1148 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1149 (long) floatFromVal (rval);
1152 return cheapestVal(val);
1155 /*------------------------------------------------------------------*/
1156 /* valMinus - Addition constants */
1157 /*------------------------------------------------------------------*/
1159 valMinus (value * lval, value * rval)
1163 /* create a new value */
1165 val->type = val->etype = newLink ();
1166 val->type->class = SPECIFIER;
1167 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1168 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1169 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1170 SPEC_USIGN (val->type) =
1171 SPEC_USIGN (lval->etype) &&
1172 SPEC_USIGN (rval->etype) &&
1173 (floatFromVal(lval)-floatFromVal(rval))>=0;
1175 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1177 if (IS_FLOAT (val->type))
1178 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1181 if (SPEC_LONG (val->type))
1183 if (SPEC_USIGN (val->type)) {
1184 SPEC_CVAL (val->type).v_ulong =
1185 (unsigned long) floatFromVal (lval) -
1186 (unsigned long) floatFromVal (rval);
1188 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1189 (long) floatFromVal (rval);
1194 if (SPEC_USIGN (val->type)) {
1195 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1196 (unsigned) floatFromVal (rval);
1198 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1199 (int) floatFromVal (rval);
1203 return cheapestVal(val);
1206 /*------------------------------------------------------------------*/
1207 /* valShift - Shift left or right */
1208 /*------------------------------------------------------------------*/
1210 valShift (value * lval, value * rval, int lr)
1214 /* create a new value */
1216 val->type = val->etype = newIntLink ();
1217 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1218 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1219 SPEC_LONG (val->type) = 1;
1221 if (SPEC_LONG (val->type))
1223 if (SPEC_USIGN (val->type))
1224 SPEC_CVAL (val->type).v_ulong = lr ?
1225 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1226 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1228 SPEC_CVAL (val->type).v_long = lr ?
1229 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1230 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1233 return cheapestVal(val);
1236 /*------------------------------------------------------------------*/
1237 /* valCompare- Compares two literal */
1238 /*------------------------------------------------------------------*/
1240 valCompare (value * lval, value * rval, int ctype)
1244 /* create a new value */
1246 val->type = val->etype = newCharLink ();
1247 val->type->class = SPECIFIER;
1248 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1249 SPEC_USIGN (val->type) = 1;
1250 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1255 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1259 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1263 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1267 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1271 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1275 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1283 /*------------------------------------------------------------------*/
1284 /* valBitwise - Bitwise operation */
1285 /*------------------------------------------------------------------*/
1287 valBitwise (value * lval, value * rval, int op)
1291 /* create a new value */
1293 val->type = copyLinkChain (lval->type);
1294 val->etype = getSpec (val->type);
1299 if (SPEC_LONG (val->type))
1301 if (SPEC_USIGN (val->type))
1302 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1303 (unsigned long) floatFromVal (rval);
1305 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1306 (long) floatFromVal (rval);
1310 if (SPEC_USIGN (val->type))
1311 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1312 (unsigned) floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1319 if (SPEC_LONG (val->type))
1321 if (SPEC_USIGN (val->type))
1322 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1323 (unsigned long) floatFromVal (rval);
1325 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1326 (long) floatFromVal (rval);
1330 if (SPEC_USIGN (val->type))
1331 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1332 (unsigned) floatFromVal (rval);
1334 SPEC_CVAL (val->type).v_int =
1335 (int) floatFromVal (lval) | (int) floatFromVal (rval);
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 =
1357 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1362 return cheapestVal(val);
1365 /*------------------------------------------------------------------*/
1366 /* valAndOr - Generates code for and / or operation */
1367 /*------------------------------------------------------------------*/
1369 valLogicAndOr (value * lval, value * rval, int op)
1373 /* create a new value */
1375 val->type = val->etype = newCharLink ();
1376 val->type->class = SPECIFIER;
1377 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1378 SPEC_USIGN (val->type) = 0;
1383 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1387 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1395 /*------------------------------------------------------------------*/
1396 /* valCastLiteral - casts a literal value to another type */
1397 /*------------------------------------------------------------------*/
1399 valCastLiteral (sym_link * dtype, double fval)
1407 val->etype = getSpec (val->type = copyLinkChain (dtype));
1408 SPEC_SCLS (val->etype) = S_LITERAL;
1409 /* if it is not a specifier then we can assume that */
1410 /* it will be an unsigned long */
1411 if (!IS_SPEC (val->type))
1413 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1417 if (SPEC_NOUN (val->etype) == V_FLOAT)
1418 SPEC_CVAL (val->etype).v_float = fval;
1421 if (SPEC_LONG (val->etype))
1423 if (SPEC_USIGN (val->etype))
1424 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1426 SPEC_CVAL (val->etype).v_long = (long) fval;
1430 if (SPEC_USIGN (val->etype))
1431 SPEC_CVAL (val->etype).v_uint = (unsigned short)fval;
1433 SPEC_CVAL (val->etype).v_int = (short)fval;
1434 if (SPEC_NOUN (val->etype)==V_CHAR) {
1435 SPEC_CVAL (val->etype).v_uint &= 0xff;
1442 /*------------------------------------------------------------------*/
1443 /* getNelements - determines # of elements from init list */
1444 /*------------------------------------------------------------------*/
1446 getNelements (sym_link * type, initList * ilist)
1448 sym_link *etype = getSpec (type);
1454 if (ilist->type == INIT_DEEP)
1455 ilist = ilist->init.deep;
1457 /* if type is a character array and there is only one
1458 (string) initialiser then get the length of the string */
1459 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1461 ast *iast = ilist->init.node;
1462 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1465 werror (W_INIT_WRONG);
1469 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1470 // yep, it's a string
1472 return DCL_ELEM (v->type);
1480 ilist = ilist->next;
1486 /*-----------------------------------------------------------------*/
1487 /* valForArray - returns a value with name of array index */
1488 /*-----------------------------------------------------------------*/
1490 valForArray (ast * arrExpr)
1492 value *val, *lval = NULL;
1494 int size = getSize (arrExpr->left->ftype->next);
1495 /* if the right or left is an array
1497 if (IS_AST_OP (arrExpr->left))
1499 if (arrExpr->left->opval.op == '[')
1500 lval = valForArray (arrExpr->left);
1501 else if (arrExpr->left->opval.op == '.')
1502 lval = valForStructElem (arrExpr->left->left,
1503 arrExpr->left->right);
1504 else if (arrExpr->left->opval.op == PTR_OP &&
1505 IS_ADDRESS_OF_OP (arrExpr->left->left))
1506 lval = valForStructElem (arrExpr->left->left->left,
1507 arrExpr->left->right);
1512 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1515 if (!IS_AST_LIT_VALUE (arrExpr->right))
1520 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1522 sprintf (buffer, "%s", lval->name);
1524 sprintf (val->name, "(%s + %d)", buffer,
1525 (int) AST_LIT_VALUE (arrExpr->right) * size);
1527 val->type = newLink ();
1528 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1530 DCL_TYPE (val->type) = CPOINTER;
1531 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1533 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1534 DCL_TYPE (val->type) = FPOINTER;
1535 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1536 DCL_TYPE (val->type) = PPOINTER;
1537 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1538 DCL_TYPE (val->type) = IPOINTER;
1539 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1540 DCL_TYPE (val->type) = EEPPOINTER;
1542 DCL_TYPE (val->type) = POINTER;
1543 val->type->next = arrExpr->left->ftype;
1544 val->etype = getSpec (val->type);
1548 /*-----------------------------------------------------------------*/
1549 /* valForStructElem - returns value with name of struct element */
1550 /*-----------------------------------------------------------------*/
1552 valForStructElem (ast * structT, ast * elemT)
1554 value *val, *lval = NULL;
1558 /* left could be furthur derefed */
1559 if (IS_AST_OP (structT))
1561 if (structT->opval.op == '[')
1562 lval = valForArray (structT);
1563 else if (structT->opval.op == '.')
1564 lval = valForStructElem (structT->left, structT->right);
1565 else if (structT->opval.op == PTR_OP &&
1566 IS_ADDRESS_OF_OP (structT->left))
1567 lval = valForStructElem (structT->left->left,
1573 if (!IS_AST_SYM_VALUE (elemT))
1576 if (!IS_STRUCT (structT->etype))
1579 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1580 AST_SYMBOL (elemT))) == NULL)
1587 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1589 sprintf (buffer, "%s", lval->name);
1591 sprintf (val->name, "(%s + %d)", buffer,
1594 val->type = newLink ();
1595 if (SPEC_SCLS (structT->etype) == S_CODE)
1597 DCL_TYPE (val->type) = CPOINTER;
1598 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1600 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1601 DCL_TYPE (val->type) = FPOINTER;
1602 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1603 DCL_TYPE (val->type) = PPOINTER;
1604 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1605 DCL_TYPE (val->type) = IPOINTER;
1606 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1607 DCL_TYPE (val->type) = EEPPOINTER;
1609 DCL_TYPE (val->type) = POINTER;
1610 val->type->next = sym->type;
1611 val->etype = getSpec (val->type);
1615 /*-----------------------------------------------------------------*/
1616 /* valForCastAggr - will return value for a cast of an aggregate */
1617 /* plus minus a constant */
1618 /*-----------------------------------------------------------------*/
1620 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1624 if (!IS_AST_SYM_VALUE (aexpr))
1626 if (!IS_AST_LIT_VALUE (cnst))
1631 sprintf (val->name, "(%s %c %d)",
1632 AST_SYMBOL (aexpr)->rname, op,
1633 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1636 val->etype = getSpec (val->type);
1640 /*-----------------------------------------------------------------*/
1641 /* valForCastAggr - will return value for a cast of an aggregate */
1642 /* with no constant */
1643 /*-----------------------------------------------------------------*/
1645 valForCastArr (ast * aexpr, sym_link * type)
1649 if (!IS_AST_SYM_VALUE (aexpr))
1654 sprintf (val->name, "(%s)",
1655 AST_SYMBOL (aexpr)->rname);
1658 val->etype = getSpec (val->type);