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_NOUN(val->type)=V_CHAR;
342 SPEC_LONG(val->type)=0;
345 SPEC_LONG(val->type)=0;
351 SPEC_NOUN(val->type)=V_CHAR;
352 SPEC_LONG(val->type)=0;
355 SPEC_LONG(val->type)=0;
360 SPEC_NOUN(val->type)=V_CHAR;
361 SPEC_LONG(val->type)=0;
364 SPEC_LONG(val->type)=0;
372 /*-----------------------------------------------------------------*/
373 /* valueFromLit - creates a value from a literal */
374 /*-----------------------------------------------------------------*/
376 valueFromLit (double lit)
380 if ((((long) lit) - lit) == 0)
382 sprintf (buffer, "%ld", (long) lit);
383 return constVal (buffer);
386 sprintf (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 ();
406 val->type->class = SPECIFIER;
407 SPEC_NOUN (val->type) = V_FLOAT;
408 SPEC_SCLS (val->type) = S_LITERAL;
409 SPEC_CVAL (val->type).v_float = sval;
414 /*-----------------------------------------------------------------*/
415 /* constVal - converts an INTEGER constant into a cheapest value */
416 /*-----------------------------------------------------------------*/
417 value *constVal (char *s)
420 short hex = 0, octal = 0;
425 val = newValue (); /* alloc space for value */
427 val->type = val->etype = newLink (); /* create the spcifier */
428 val->type->class = SPECIFIER;
429 SPEC_SCLS (val->type) = S_LITERAL;
430 // let's start with an unsigned char
431 SPEC_NOUN (val->type) = V_CHAR;
432 SPEC_USIGN (val->type) = 1;
434 /* set the _long flag if 'lL' is found */
435 if (strchr (s, 'l') || strchr (s, 'L'))
436 SPEC_LONG (val->type) = 1;
438 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
440 /* set the octal flag */
441 if (!hex && *s == '0' && *(s + 1))
444 /* create the scan string */
445 scanFmt[scI++] = '%';
448 scanFmt[scI++] = 'o';
450 scanFmt[scI++] = 'x';
452 scanFmt[scI++] = 'd';
454 scanFmt[scI++] = 'L';
455 scanFmt[scI++] = '\0';
457 sscanf (s, scanFmt, &sval);
459 if (sval<0) { // "-28u" will still be signed and negative
460 SPEC_USIGN (val->type) = 0;
461 if (sval<-32768) { // check if we have to promote to long
462 SPEC_NOUN (val->type) = V_INT;
463 SPEC_LONG (val->type) = 1;
464 SPEC_CVAL (val->type).v_long=sval;
466 SPEC_CVAL (val->type).v_int=sval;
467 if (sval<-128) { // check if we have to promote to int
468 SPEC_NOUN (val->type) = V_INT;
472 if (sval>0xffff) { // check if we have to promote to long
473 SPEC_NOUN (val->type) = V_INT;
474 SPEC_LONG (val->type) = 1;
475 SPEC_CVAL (val->type).v_ulong=sval;
477 SPEC_CVAL (val->type).v_uint=sval;
478 if (sval>0xff) { // check if we have to promote to int
479 SPEC_NOUN (val->type) = V_INT;
487 /*! /fn char hexEscape(char **src)
489 /param src Pointer to 'x' from start of hex character value
492 char hexEscape(char **src)
496 unsigned long value ;
498 (*src)++ ; /* Skip over the 'x' */
499 s = *src ; /* Save for error detection */
501 value = strtol (*src, src, 16);
505 // no valid hex found
506 werror(E_INVALID_HEX);
513 werror(W_ESC_SEQ_OOR_FOR_CHAR);
519 /*------------------------------------------------------------------*/
520 /* octalEscape - process an octal constant of max three digits */
521 /* return the octal value, throw a warning for illegal octal */
522 /* adjust src to point at the last proccesed char */
523 /*------------------------------------------------------------------*/
525 char octalEscape (char **str) {
529 for (digits=0; digits<3; digits++) {
530 if (**str>='0' && **str<='7') {
531 value = value*8 + (**str-'0');
538 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
539 werror (W_ESC_SEQ_OOR_FOR_CHAR);
546 /fn int copyStr (char *dest, char *src)
548 Copies a source string to a dest buffer interpreting escape sequences
549 and special characters
551 /param dest Buffer to receive the resultant string
552 /param src Buffer containing the source string with escape sequecnes
553 /return Number of characters in output string
558 copyStr (char *dest, char *src)
561 char *OriginalDest = dest ;
567 else if (*src == '\\')
602 *dest++ = octalEscape(&src);
607 *dest++ = hexEscape(&src) ;
634 return dest - OriginalDest ;
637 /*------------------------------------------------------------------*/
638 /* strVal - converts a string constant to a value */
639 /*------------------------------------------------------------------*/
645 val = newValue (); /* get a new one */
647 /* get a declarator */
648 val->type = newLink ();
649 DCL_TYPE (val->type) = ARRAY;
650 val->type->next = val->etype = newLink ();
651 val->etype->class = SPECIFIER;
652 SPEC_NOUN (val->etype) = V_CHAR;
653 SPEC_SCLS (val->etype) = S_LITERAL;
655 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
656 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
662 /*------------------------------------------------------------------*/
663 /* reverseValWithType - reverses value chain with type & etype */
664 /*------------------------------------------------------------------*/
666 reverseValWithType (value * val)
674 /* save the type * etype chains */
678 /* set the current one 2b null */
679 val->type = val->etype = NULL;
680 val = reverseVal (val);
682 /* restore type & etype */
689 /*------------------------------------------------------------------*/
690 /* reverseVal - reverses the values for a value chain */
691 /*------------------------------------------------------------------*/
693 reverseVal (value * val)
695 value *prev, *curr, *next;
710 val->next = (void *) NULL;
714 /*------------------------------------------------------------------*/
715 /* copyValueChain - will copy a chain of values */
716 /*------------------------------------------------------------------*/
718 copyValueChain (value * src)
725 dest = copyValue (src);
726 dest->next = copyValueChain (src->next);
731 /*------------------------------------------------------------------*/
732 /* copyValue - copies contents of a value to a fresh one */
733 /*------------------------------------------------------------------*/
735 copyValue (value * src)
740 dest->sym = copySymbol (src->sym);
741 strcpy (dest->name, src->name);
742 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
743 dest->etype = (src->type ? getSpec (dest->type) : NULL);
748 /*------------------------------------------------------------------*/
749 /* charVal - converts a character constant to a value */
750 /*------------------------------------------------------------------*/
759 val->type = val->etype = newLink ();
760 val->type->class = SPECIFIER;
761 SPEC_NOUN (val->type) = V_CHAR;
762 SPEC_USIGN(val->type) = 1;
763 SPEC_SCLS (val->type) = S_LITERAL;
765 s++; /* get rid of quotation */
766 /* if \ then special processing */
769 s++; /* go beyond the backslash */
773 SPEC_CVAL (val->type).v_int = '\n';
776 SPEC_CVAL (val->type).v_int = '\t';
779 SPEC_CVAL (val->type).v_int = '\v';
782 SPEC_CVAL (val->type).v_int = '\b';
785 SPEC_CVAL (val->type).v_int = '\r';
788 SPEC_CVAL (val->type).v_int = '\f';
791 SPEC_CVAL (val->type).v_int = '\a';
794 SPEC_CVAL (val->type).v_int = '\\';
797 SPEC_CVAL (val->type).v_int = '\?';
800 SPEC_CVAL (val->type).v_int = '\'';
803 SPEC_CVAL (val->type).v_int = '\"';
814 SPEC_CVAL (val->type).v_int = octalEscape(&s);
818 SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
822 SPEC_CVAL (val->type).v_int = *s;
826 else /* not a backslash */
827 SPEC_CVAL (val->type).v_int = *s;
832 /*------------------------------------------------------------------*/
833 /* valFromType - creates a value from type given */
834 /*------------------------------------------------------------------*/
836 valFromType (sym_link * type)
838 value *val = newValue ();
839 val->type = copyLinkChain (type);
840 val->etype = getSpec (val->type);
844 /*------------------------------------------------------------------*/
845 /* floatFromVal - value to unsinged integer conversion */
846 /*------------------------------------------------------------------*/
848 floatFromVal (value * val)
853 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
855 werror (E_CONST_EXPECTED, val->name);
859 /* if it is not a specifier then we can assume that */
860 /* it will be an unsigned long */
861 if (!IS_SPEC (val->type))
862 return (double) SPEC_CVAL (val->etype).v_ulong;
864 if (SPEC_NOUN (val->etype) == V_FLOAT)
865 return (double) SPEC_CVAL (val->etype).v_float;
868 if (SPEC_LONG (val->etype))
870 if (SPEC_USIGN (val->etype))
871 return (double) SPEC_CVAL (val->etype).v_ulong;
873 return (double) SPEC_CVAL (val->etype).v_long;
877 if (SPEC_USIGN (val->etype))
878 return (double) SPEC_CVAL (val->etype).v_uint;
880 return (double) SPEC_CVAL (val->etype).v_int;
886 /*------------------------------------------------------------------*/
887 /* valUnaryPM - does the unary +/- operation on a constant */
888 /*------------------------------------------------------------------*/
890 valUnaryPM (value * val)
892 /* depending on type */
893 if (SPEC_NOUN (val->etype) == V_FLOAT)
894 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
897 if (SPEC_LONG (val->etype))
899 if (SPEC_USIGN (val->etype))
900 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
902 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
906 if (SPEC_USIGN (val->etype))
907 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
909 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
915 /*------------------------------------------------------------------*/
916 /* valueComplement - complements a constant */
917 /*------------------------------------------------------------------*/
919 valComplement (value * val)
921 /* depending on type */
922 if (SPEC_LONG (val->etype))
924 if (SPEC_USIGN (val->etype))
925 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
927 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
931 if (SPEC_USIGN (val->etype))
932 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
934 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
939 /*------------------------------------------------------------------*/
940 /* valueNot - complements a constant */
941 /*------------------------------------------------------------------*/
945 /* depending on type */
946 if (SPEC_LONG (val->etype))
948 if (SPEC_USIGN (val->etype))
949 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
951 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
955 if (SPEC_USIGN (val->etype))
956 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
958 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
963 /*------------------------------------------------------------------*/
964 /* valMult - multiply constants */
965 /*------------------------------------------------------------------*/
967 valMult (value * lval, value * rval)
971 /* create a new value */
973 val->type = val->etype = newLink ();
974 val->type->class = SPECIFIER;
975 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
976 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
977 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
978 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
979 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
981 if (IS_FLOAT (val->type))
982 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
985 if (SPEC_LONG (val->type))
987 if (SPEC_USIGN (val->type))
988 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
989 (unsigned long) floatFromVal (rval);
991 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
992 (long) floatFromVal (rval);
996 if (SPEC_USIGN (val->type))
997 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
998 (unsigned) floatFromVal (rval);
1000 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
1001 (int) floatFromVal (rval);
1004 return cheapestVal(val);
1007 /*------------------------------------------------------------------*/
1008 /* valDiv - Divide constants */
1009 /*------------------------------------------------------------------*/
1011 valDiv (value * lval, value * rval)
1015 if (floatFromVal (rval) == 0)
1017 werror (E_DIVIDE_BY_ZERO);
1021 /* create a new value */
1023 val->type = val->etype = newLink();
1024 val->type->class = SPECIFIER;
1025 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1026 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1027 SPEC_SCLS (val->etype) = S_LITERAL;
1028 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1029 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1031 if (IS_FLOAT (val->type))
1032 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1035 if (SPEC_LONG (val->type))
1037 if (SPEC_USIGN (val->type))
1038 SPEC_CVAL (val->type).v_ulong =
1039 (unsigned long) floatFromVal (lval) /
1040 (unsigned long) floatFromVal (rval);
1042 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1043 (long) floatFromVal (rval);
1047 if (SPEC_USIGN (val->type)) {
1048 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1049 (unsigned) floatFromVal (rval);
1051 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1052 (int) floatFromVal (rval);
1056 return cheapestVal(val);
1059 /*------------------------------------------------------------------*/
1060 /* valMod - Modulus constants */
1061 /*------------------------------------------------------------------*/
1063 valMod (value * lval, value * rval)
1067 /* create a new value */
1069 val->type = val->etype = newLink ();
1070 val->type->class = SPECIFIER;
1071 SPEC_NOUN (val->type) = V_INT; /* type is int */
1072 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1073 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1074 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1076 if (SPEC_LONG (val->type))
1078 if (SPEC_USIGN (val->type))
1079 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1080 (unsigned long) floatFromVal (rval);
1082 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1083 (unsigned long) floatFromVal (rval);
1087 if (SPEC_USIGN (val->type)) {
1088 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1089 (unsigned) floatFromVal (rval);
1091 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1092 (unsigned) floatFromVal (rval);
1096 return cheapestVal(val);
1099 /*------------------------------------------------------------------*/
1100 /* valPlus - Addition constants */
1101 /*------------------------------------------------------------------*/
1103 valPlus (value * lval, value * rval)
1107 /* create a new value */
1109 val->type = val->etype = newLink ();
1110 val->type->class = SPECIFIER;
1111 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1112 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1113 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1114 SPEC_USIGN (val->type) =
1115 SPEC_USIGN (lval->etype) &&
1116 SPEC_USIGN (rval->etype) &&
1117 (floatFromVal(lval)+floatFromVal(rval))>=0;
1119 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1121 if (IS_FLOAT (val->type))
1122 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1125 if (SPEC_LONG (val->type))
1127 if (SPEC_USIGN (val->type))
1128 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1129 (unsigned long) floatFromVal (rval);
1131 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1132 (long) floatFromVal (rval);
1136 if (SPEC_USIGN (val->type)) {
1137 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1138 (unsigned) floatFromVal (rval);
1140 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1141 (int) floatFromVal (rval);
1145 return cheapestVal(val);
1148 /*------------------------------------------------------------------*/
1149 /* valMinus - Addition constants */
1150 /*------------------------------------------------------------------*/
1152 valMinus (value * lval, value * rval)
1156 /* create a new value */
1158 val->type = val->etype = newLink ();
1159 val->type->class = SPECIFIER;
1160 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1161 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1162 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1163 SPEC_USIGN (val->type) =
1164 SPEC_USIGN (lval->etype) &&
1165 SPEC_USIGN (rval->etype) &&
1166 (floatFromVal(lval)-floatFromVal(rval))>=0;
1168 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1170 if (IS_FLOAT (val->type))
1171 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1174 if (SPEC_LONG (val->type))
1176 if (SPEC_USIGN (val->type)) {
1177 SPEC_CVAL (val->type).v_ulong =
1178 (unsigned long) floatFromVal (lval) -
1179 (unsigned long) floatFromVal (rval);
1181 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1182 (long) floatFromVal (rval);
1187 if (SPEC_USIGN (val->type)) {
1188 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1189 (unsigned) floatFromVal (rval);
1191 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1192 (int) floatFromVal (rval);
1196 return cheapestVal(val);
1199 /*------------------------------------------------------------------*/
1200 /* valShift - Shift left or right */
1201 /*------------------------------------------------------------------*/
1203 valShift (value * lval, value * rval, int lr)
1207 /* create a new value */
1209 val->type = val->etype = newIntLink ();
1210 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1211 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1212 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1214 if (SPEC_LONG (val->type))
1216 if (SPEC_USIGN (val->type))
1217 SPEC_CVAL (val->type).v_ulong = lr ?
1218 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1219 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1221 SPEC_CVAL (val->type).v_long = lr ?
1222 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1223 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1227 if (SPEC_USIGN (val->type)) {
1228 SPEC_CVAL (val->type).v_uint = lr ?
1229 (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1230 (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1232 SPEC_CVAL (val->type).v_int = lr ?
1233 (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1234 (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1238 return cheapestVal(val);
1241 /*------------------------------------------------------------------*/
1242 /* valCompare- Compares two literal */
1243 /*------------------------------------------------------------------*/
1245 valCompare (value * lval, value * rval, int ctype)
1249 /* create a new value */
1251 val->type = val->etype = newCharLink ();
1252 val->type->class = SPECIFIER;
1253 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1254 SPEC_USIGN (val->type) = 1;
1255 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1260 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1264 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1268 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1272 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1276 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1280 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1288 /*------------------------------------------------------------------*/
1289 /* valBitwise - Bitwise operation */
1290 /*------------------------------------------------------------------*/
1292 valBitwise (value * lval, value * rval, int op)
1296 /* create a new value */
1298 val->type = copyLinkChain (lval->type);
1299 val->etype = getSpec (val->type);
1304 if (SPEC_LONG (val->type))
1306 if (SPEC_USIGN (val->type))
1307 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1308 (unsigned long) floatFromVal (rval);
1310 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1311 (long) floatFromVal (rval);
1315 if (SPEC_USIGN (val->type))
1316 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1317 (unsigned) floatFromVal (rval);
1319 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1324 if (SPEC_LONG (val->type))
1326 if (SPEC_USIGN (val->type))
1327 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1328 (unsigned long) floatFromVal (rval);
1330 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1331 (long) floatFromVal (rval);
1335 if (SPEC_USIGN (val->type))
1336 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1337 (unsigned) floatFromVal (rval);
1339 SPEC_CVAL (val->type).v_int =
1340 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1346 if (SPEC_LONG (val->type))
1348 if (SPEC_USIGN (val->type))
1349 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1350 (unsigned long) floatFromVal (rval);
1352 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1353 (long) floatFromVal (rval);
1357 if (SPEC_USIGN (val->type))
1358 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1359 (unsigned) floatFromVal (rval);
1361 SPEC_CVAL (val->type).v_int =
1362 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1367 return cheapestVal(val);
1370 /*------------------------------------------------------------------*/
1371 /* valAndOr - Generates code for and / or operation */
1372 /*------------------------------------------------------------------*/
1374 valLogicAndOr (value * lval, value * rval, int op)
1378 /* create a new value */
1380 val->type = val->etype = newCharLink ();
1381 val->type->class = SPECIFIER;
1382 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1383 SPEC_USIGN (val->type) = 0;
1388 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1392 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1400 /*------------------------------------------------------------------*/
1401 /* valCastLiteral - casts a literal value to another type */
1402 /*------------------------------------------------------------------*/
1404 valCastLiteral (sym_link * dtype, double fval)
1412 val->etype = getSpec (val->type = copyLinkChain (dtype));
1413 SPEC_SCLS (val->etype) = S_LITERAL;
1414 /* if it is not a specifier then we can assume that */
1415 /* it will be an unsigned long */
1416 if (!IS_SPEC (val->type))
1418 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1422 if (SPEC_NOUN (val->etype) == V_FLOAT)
1423 SPEC_CVAL (val->etype).v_float = fval;
1426 if (SPEC_LONG (val->etype))
1428 if (SPEC_USIGN (val->etype))
1429 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1431 SPEC_CVAL (val->etype).v_long = (long) fval;
1435 if (SPEC_USIGN (val->etype))
1436 if (SPEC_NOUN (val->etype)==V_CHAR) {
1437 SPEC_CVAL (val->etype).v_uint = (unsigned char) fval;
1439 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1442 if (SPEC_NOUN (val->etype)==V_CHAR) {
1443 SPEC_CVAL (val->etype).v_int = (char) fval;
1445 SPEC_CVAL (val->etype).v_int = (int) fval;
1452 /*------------------------------------------------------------------*/
1453 /* getNelements - determines # of elements from init list */
1454 /*------------------------------------------------------------------*/
1456 getNelements (sym_link * type, initList * ilist)
1458 sym_link *etype = getSpec (type);
1464 if (ilist->type == INIT_DEEP)
1465 ilist = ilist->init.deep;
1467 /* if type is a character array and there is only one
1468 (string) initialiser then get the length of the string */
1469 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1471 ast *iast = ilist->init.node;
1472 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1475 werror (W_INIT_WRONG);
1479 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1480 // yep, it's a string
1482 return DCL_ELEM (v->type);
1490 ilist = ilist->next;
1496 /*-----------------------------------------------------------------*/
1497 /* valForArray - returns a value with name of array index */
1498 /*-----------------------------------------------------------------*/
1500 valForArray (ast * arrExpr)
1502 value *val, *lval = NULL;
1504 int size = getSize (arrExpr->left->ftype->next);
1505 /* if the right or left is an array
1507 if (IS_AST_OP (arrExpr->left))
1509 if (arrExpr->left->opval.op == '[')
1510 lval = valForArray (arrExpr->left);
1511 else if (arrExpr->left->opval.op == '.')
1512 lval = valForStructElem (arrExpr->left->left,
1513 arrExpr->left->right);
1514 else if (arrExpr->left->opval.op == PTR_OP &&
1515 IS_ADDRESS_OF_OP (arrExpr->left->left))
1516 lval = valForStructElem (arrExpr->left->left->left,
1517 arrExpr->left->right);
1522 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1525 if (!IS_AST_LIT_VALUE (arrExpr->right))
1530 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1532 sprintf (buffer, "%s", lval->name);
1534 sprintf (val->name, "(%s + %d)", buffer,
1535 (int) AST_LIT_VALUE (arrExpr->right) * size);
1537 val->type = newLink ();
1538 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1540 DCL_TYPE (val->type) = CPOINTER;
1541 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1543 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1544 DCL_TYPE (val->type) = FPOINTER;
1545 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1546 DCL_TYPE (val->type) = PPOINTER;
1547 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1548 DCL_TYPE (val->type) = IPOINTER;
1549 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1550 DCL_TYPE (val->type) = EEPPOINTER;
1552 DCL_TYPE (val->type) = POINTER;
1553 val->type->next = arrExpr->left->ftype;
1554 val->etype = getSpec (val->type);
1558 /*-----------------------------------------------------------------*/
1559 /* valForStructElem - returns value with name of struct element */
1560 /*-----------------------------------------------------------------*/
1562 valForStructElem (ast * structT, ast * elemT)
1564 value *val, *lval = NULL;
1568 /* left could be furthur derefed */
1569 if (IS_AST_OP (structT))
1571 if (structT->opval.op == '[')
1572 lval = valForArray (structT);
1573 else if (structT->opval.op == '.')
1574 lval = valForStructElem (structT->left, structT->right);
1575 else if (structT->opval.op == PTR_OP &&
1576 IS_ADDRESS_OF_OP (structT->left))
1577 lval = valForStructElem (structT->left->left,
1583 if (!IS_AST_SYM_VALUE (elemT))
1586 if (!IS_STRUCT (structT->etype))
1589 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1590 AST_SYMBOL (elemT))) == NULL)
1597 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1599 sprintf (buffer, "%s", lval->name);
1601 sprintf (val->name, "(%s + %d)", buffer,
1604 val->type = newLink ();
1605 if (SPEC_SCLS (structT->etype) == S_CODE)
1607 DCL_TYPE (val->type) = CPOINTER;
1608 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1610 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1611 DCL_TYPE (val->type) = FPOINTER;
1612 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1613 DCL_TYPE (val->type) = PPOINTER;
1614 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1615 DCL_TYPE (val->type) = IPOINTER;
1616 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1617 DCL_TYPE (val->type) = EEPPOINTER;
1619 DCL_TYPE (val->type) = POINTER;
1620 val->type->next = sym->type;
1621 val->etype = getSpec (val->type);
1625 /*-----------------------------------------------------------------*/
1626 /* valForCastAggr - will return value for a cast of an aggregate */
1627 /* plus minus a constant */
1628 /*-----------------------------------------------------------------*/
1630 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1634 if (!IS_AST_SYM_VALUE (aexpr))
1636 if (!IS_AST_LIT_VALUE (cnst))
1641 sprintf (val->name, "(%s %c %d)",
1642 AST_SYMBOL (aexpr)->rname, op,
1643 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1646 val->etype = getSpec (val->type);
1650 /*-----------------------------------------------------------------*/
1651 /* valForCastAggr - will return value for a cast of an aggregate */
1652 /* with no constant */
1653 /*-----------------------------------------------------------------*/
1655 valForCastArr (ast * aexpr, sym_link * type)
1659 if (!IS_AST_SYM_VALUE (aexpr))
1664 sprintf (val->name, "(%s)",
1665 AST_SYMBOL (aexpr)->rname);
1668 val->etype = getSpec (val->type);