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;
344 SPEC_NOUN(val->type)=V_CHAR;
347 } else { // not unsigned
350 SPEC_LONG(val->type)=0;
351 SPEC_CVAL(val->type).v_int = sval;
353 SPEC_NOUN(val->type)=V_CHAR;
357 SPEC_USIGN(val->type)=1;
359 SPEC_LONG(val->type)=0;
360 SPEC_CVAL(val->type).v_int = sval;
362 SPEC_NOUN(val->type)=V_CHAR;
370 /*-----------------------------------------------------------------*/
371 /* valueFromLit - creates a value from a literal */
372 /*-----------------------------------------------------------------*/
374 valueFromLit (double lit)
378 if ((((long) lit) - lit) == 0)
380 sprintf (buffer, "%ld", (long) lit);
381 return constVal (buffer);
384 sprintf (buffer, "%f", lit);
385 return constFloatVal (buffer);
388 /*-----------------------------------------------------------------*/
389 /* constFloatVal - converts a FLOAT constant to value */
390 /*-----------------------------------------------------------------*/
392 constFloatVal (char *s)
394 value *val = newValue ();
397 if (sscanf (s, "%lf", &sval) != 1)
399 werror (E_INVALID_FLOAT_CONST, s);
400 return constVal ("0");
403 val->type = val->etype = newLink ();
404 val->type->class = SPECIFIER;
405 SPEC_NOUN (val->type) = V_FLOAT;
406 SPEC_SCLS (val->type) = S_LITERAL;
407 SPEC_CVAL (val->type).v_float = sval;
412 /*-----------------------------------------------------------------*/
413 /* constVal - converts an INTEGER constant into a cheapest value */
414 /*-----------------------------------------------------------------*/
415 value *constVal (char *s)
418 short hex = 0, octal = 0;
423 val = newValue (); /* alloc space for value */
425 val->type = val->etype = newLink (); /* create the spcifier */
426 val->type->class = SPECIFIER;
427 SPEC_SCLS (val->type) = S_LITERAL;
428 // let's start with an unsigned char
429 SPEC_NOUN (val->type) = V_CHAR;
430 SPEC_USIGN (val->type) = 1;
432 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
434 /* set the octal flag */
435 if (!hex && *s == '0' && *(s + 1))
438 /* create the scan string */
439 scanFmt[scI++] = '%';
441 scanFmt[scI++] = 'l';
444 scanFmt[scI++] = 'o';
446 scanFmt[scI++] = 'x';
448 scanFmt[scI++] = 'f';
450 scanFmt[scI++] = '\0';
454 sscanf (s, scanFmt, &sval);
457 sscanf (s, scanFmt, &dval);
460 /* Setup the flags first */
461 /* set the _long flag if 'lL' is found */
462 if (strchr (s, 'l') || strchr (s, 'L')) {
463 SPEC_NOUN (val->type) = V_INT;
464 SPEC_LONG (val->type) = 1;
467 if (dval<0) { // "-28u" will still be signed and negative
468 SPEC_USIGN (val->type) = 0;
469 if (dval<-128) { // check if we have to promote to int
470 SPEC_NOUN (val->type) = V_INT;
472 if (dval<-32768) { // check if we have to promote to long int
473 SPEC_LONG (val->type) = 1;
476 if (dval>0xff) { // check if we have to promote to int
477 SPEC_NOUN (val->type) = V_INT;
479 if (dval>0xffff) { // check if we have to promote to long int
480 SPEC_LONG (val->type) = 1;
484 if (SPEC_LONG (val->type))
486 if (SPEC_USIGN (val->type))
488 SPEC_CVAL (val->type).v_ulong = dval;
492 SPEC_CVAL (val->type).v_long = dval;
497 if (SPEC_USIGN (val->type))
499 SPEC_CVAL (val->type).v_uint = dval;
503 SPEC_CVAL (val->type).v_int = dval;
510 /*! /fn char hexEscape(char **src)
512 /param src Pointer to 'x' from start of hex character value
515 unsigned char hexEscape(char **src)
518 unsigned long value ;
520 (*src)++ ; /* Skip over the 'x' */
521 s = *src ; /* Save for error detection */
523 value = strtol (*src, src, 16);
526 // no valid hex found
527 werror(E_INVALID_HEX);
530 werror(W_ESC_SEQ_OOR_FOR_CHAR);
536 /*------------------------------------------------------------------*/
537 /* octalEscape - process an octal constant of max three digits */
538 /* return the octal value, throw a warning for illegal octal */
539 /* adjust src to point at the last proccesed char */
540 /*------------------------------------------------------------------*/
542 unsigned char octalEscape (char **str) {
546 for (digits=0; digits<3; digits++) {
547 if (**str>='0' && **str<='7') {
548 value = value*8 + (**str-'0');
555 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
556 werror (W_ESC_SEQ_OOR_FOR_CHAR);
563 /fn int copyStr (char *dest, char *src)
565 Copies a source string to a dest buffer interpreting escape sequences
566 and special characters
568 /param dest Buffer to receive the resultant string
569 /param src Buffer containing the source string with escape sequecnes
570 /return Number of characters in output string
575 copyStr (char *dest, char *src)
578 char *OriginalDest = dest ;
584 else if (*src == '\\')
619 *dest++ = octalEscape(&src);
624 *dest++ = hexEscape(&src) ;
651 return dest - OriginalDest ;
654 /*------------------------------------------------------------------*/
655 /* strVal - converts a string constant to a value */
656 /*------------------------------------------------------------------*/
662 val = newValue (); /* get a new one */
664 /* get a declarator */
665 val->type = newLink ();
666 DCL_TYPE (val->type) = ARRAY;
667 val->type->next = val->etype = newLink ();
668 val->etype->class = SPECIFIER;
669 SPEC_NOUN (val->etype) = V_CHAR;
670 SPEC_SCLS (val->etype) = S_LITERAL;
672 SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
673 DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
679 /*------------------------------------------------------------------*/
680 /* reverseValWithType - reverses value chain with type & etype */
681 /*------------------------------------------------------------------*/
683 reverseValWithType (value * val)
691 /* save the type * etype chains */
695 /* set the current one 2b null */
696 val->type = val->etype = NULL;
697 val = reverseVal (val);
699 /* restore type & etype */
706 /*------------------------------------------------------------------*/
707 /* reverseVal - reverses the values for a value chain */
708 /*------------------------------------------------------------------*/
710 reverseVal (value * val)
712 value *prev, *curr, *next;
727 val->next = (void *) NULL;
731 /*------------------------------------------------------------------*/
732 /* copyValueChain - will copy a chain of values */
733 /*------------------------------------------------------------------*/
735 copyValueChain (value * src)
742 dest = copyValue (src);
743 dest->next = copyValueChain (src->next);
748 /*------------------------------------------------------------------*/
749 /* copyValue - copies contents of a value to a fresh one */
750 /*------------------------------------------------------------------*/
752 copyValue (value * src)
757 dest->sym = copySymbol (src->sym);
758 strcpy (dest->name, src->name);
759 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
760 dest->etype = (src->type ? getSpec (dest->type) : NULL);
765 /*------------------------------------------------------------------*/
766 /* charVal - converts a character constant to a value */
767 /*------------------------------------------------------------------*/
776 val->type = val->etype = newLink ();
777 val->type->class = SPECIFIER;
778 SPEC_NOUN (val->type) = V_CHAR;
779 SPEC_USIGN(val->type) = 1;
780 SPEC_SCLS (val->type) = S_LITERAL;
782 s++; /* get rid of quotation */
783 /* if \ then special processing */
786 s++; /* go beyond the backslash */
790 SPEC_CVAL (val->type).v_int = '\n';
793 SPEC_CVAL (val->type).v_int = '\t';
796 SPEC_CVAL (val->type).v_int = '\v';
799 SPEC_CVAL (val->type).v_int = '\b';
802 SPEC_CVAL (val->type).v_int = '\r';
805 SPEC_CVAL (val->type).v_int = '\f';
808 SPEC_CVAL (val->type).v_int = '\a';
811 SPEC_CVAL (val->type).v_int = '\\';
814 SPEC_CVAL (val->type).v_int = '\?';
817 SPEC_CVAL (val->type).v_int = '\'';
820 SPEC_CVAL (val->type).v_int = '\"';
831 SPEC_CVAL (val->type).v_uint = octalEscape(&s);
835 SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
839 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
843 else /* not a backslash */
844 SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
849 /*------------------------------------------------------------------*/
850 /* valFromType - creates a value from type given */
851 /*------------------------------------------------------------------*/
853 valFromType (sym_link * type)
855 value *val = newValue ();
856 val->type = copyLinkChain (type);
857 val->etype = getSpec (val->type);
861 /*------------------------------------------------------------------*/
862 /* floatFromVal - value to double float conversion */
863 /*------------------------------------------------------------------*/
865 floatFromVal (value * val)
870 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
872 werror (E_CONST_EXPECTED, val->name);
876 /* if it is not a specifier then we can assume that */
877 /* it will be an unsigned long */
878 if (!IS_SPEC (val->type))
879 return (double) SPEC_CVAL (val->etype).v_ulong;
881 if (SPEC_NOUN (val->etype) == V_FLOAT)
882 return (double) SPEC_CVAL (val->etype).v_float;
884 if (SPEC_LONG (val->etype))
886 if (SPEC_USIGN (val->etype))
887 return (double) SPEC_CVAL (val->etype).v_ulong;
889 return (double) SPEC_CVAL (val->etype).v_long;
892 if (SPEC_NOUN (val->etype) == V_INT) {
893 if (SPEC_USIGN (val->etype))
894 return (double) SPEC_CVAL (val->etype).v_uint;
896 return (double) SPEC_CVAL (val->etype).v_int;
899 if (SPEC_NOUN (val->etype) == V_CHAR) {
900 if (SPEC_USIGN (val->etype))
901 return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
903 return (double) (signed char)SPEC_CVAL (val->etype).v_int;
906 if (IS_BITVAR(val->etype)) {
907 return (double) SPEC_CVAL (val->etype).v_ulong;
910 if (SPEC_NOUN (val->etype) == V_VOID) {
911 return (double) SPEC_CVAL (val->etype).v_ulong;
915 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
916 "floatFromVal: unknown value");
921 /*------------------------------------------------------------------*/
922 /* valUnaryPM - does the unary +/- operation on a constant */
923 /*------------------------------------------------------------------*/
925 valUnaryPM (value * val)
927 /* depending on type */
928 if (SPEC_NOUN (val->etype) == V_FLOAT)
929 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
932 if (SPEC_LONG (val->etype))
934 if (SPEC_USIGN (val->etype))
935 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
937 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
941 if (SPEC_USIGN (val->etype))
942 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
944 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
947 // -(unsigned 3) now really is signed
948 SPEC_USIGN(val->etype)=0;
949 // -(unsigned char)135 now really is an int
950 if (SPEC_NOUN(val->etype) == V_CHAR) {
951 if (SPEC_CVAL(val->etype).v_int < -128) {
952 SPEC_NOUN(val->etype) = V_INT;
958 /*------------------------------------------------------------------*/
959 /* valueComplement - complements a constant */
960 /*------------------------------------------------------------------*/
962 valComplement (value * val)
964 /* depending on type */
965 if (SPEC_LONG (val->etype))
967 if (SPEC_USIGN (val->etype))
968 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
970 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
974 if (SPEC_USIGN (val->etype))
975 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
977 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
979 // ~(unsigned 3) now really is signed
980 SPEC_USIGN(val->etype)=0;
984 /*------------------------------------------------------------------*/
985 /* valueNot - complements a constant */
986 /*------------------------------------------------------------------*/
990 /* depending on type */
991 if (SPEC_LONG (val->etype))
993 if (SPEC_USIGN (val->etype))
994 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
996 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1000 if (SPEC_USIGN (val->etype))
1001 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1003 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1008 /*------------------------------------------------------------------*/
1009 /* valMult - multiply constants */
1010 /*------------------------------------------------------------------*/
1012 valMult (value * lval, value * rval)
1016 /* create a new value */
1018 val->type = val->etype = newLink ();
1019 val->type->class = SPECIFIER;
1020 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1021 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1022 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1023 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1024 SPEC_LONG (val->type) = 1;
1026 if (IS_FLOAT (val->type))
1027 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1030 if (SPEC_LONG (val->type))
1032 if (SPEC_USIGN (val->type))
1033 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1034 (unsigned long) floatFromVal (rval);
1036 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1037 (long) floatFromVal (rval);
1040 return cheapestVal(val);
1043 /*------------------------------------------------------------------*/
1044 /* valDiv - Divide constants */
1045 /*------------------------------------------------------------------*/
1047 valDiv (value * lval, value * rval)
1051 if (floatFromVal (rval) == 0)
1053 werror (E_DIVIDE_BY_ZERO);
1057 /* create a new value */
1059 val->type = val->etype = newLink();
1060 val->type->class = SPECIFIER;
1061 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1062 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1063 SPEC_SCLS (val->etype) = S_LITERAL;
1064 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1065 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1067 if (IS_FLOAT (val->type))
1068 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1071 if (SPEC_LONG (val->type))
1073 if (SPEC_USIGN (val->type))
1074 SPEC_CVAL (val->type).v_ulong =
1075 (unsigned long) floatFromVal (lval) /
1076 (unsigned long) floatFromVal (rval);
1078 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1079 (long) floatFromVal (rval);
1083 if (SPEC_USIGN (val->type)) {
1084 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1085 (unsigned) floatFromVal (rval);
1087 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1088 (int) floatFromVal (rval);
1092 return cheapestVal(val);
1095 /*------------------------------------------------------------------*/
1096 /* valMod - Modulus constants */
1097 /*------------------------------------------------------------------*/
1099 valMod (value * lval, value * rval)
1103 /* create a new value */
1105 val->type = val->etype = newLink ();
1106 val->type->class = SPECIFIER;
1107 SPEC_NOUN (val->type) = V_INT; /* type is int */
1108 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1109 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1110 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1112 if (SPEC_LONG (val->type))
1114 if (SPEC_USIGN (val->type))
1115 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1116 (unsigned long) floatFromVal (rval);
1118 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1119 (unsigned long) floatFromVal (rval);
1123 if (SPEC_USIGN (val->type)) {
1124 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1125 (unsigned) floatFromVal (rval);
1127 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1128 (unsigned) floatFromVal (rval);
1132 return cheapestVal(val);
1135 /*------------------------------------------------------------------*/
1136 /* valPlus - Addition constants */
1137 /*------------------------------------------------------------------*/
1139 valPlus (value * lval, value * rval)
1143 /* create a new value */
1145 val->type = val->etype = newLink ();
1146 val->type->class = SPECIFIER;
1147 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1148 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1149 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1150 SPEC_USIGN (val->type) =
1151 SPEC_USIGN (lval->etype) &&
1152 SPEC_USIGN (rval->etype) &&
1153 (floatFromVal(lval)+floatFromVal(rval))>=0;
1155 SPEC_LONG (val->type) = 1;
1157 if (IS_FLOAT (val->type))
1158 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1161 if (SPEC_LONG (val->type))
1163 if (SPEC_USIGN (val->type))
1164 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1165 (unsigned long) floatFromVal (rval);
1167 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1168 (long) floatFromVal (rval);
1171 return cheapestVal(val);
1174 /*------------------------------------------------------------------*/
1175 /* valMinus - Addition constants */
1176 /*------------------------------------------------------------------*/
1178 valMinus (value * lval, value * rval)
1182 /* create a new value */
1184 val->type = val->etype = newLink ();
1185 val->type->class = SPECIFIER;
1186 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1187 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1188 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1189 SPEC_USIGN (val->type) =
1190 SPEC_USIGN (lval->etype) &&
1191 SPEC_USIGN (rval->etype) &&
1192 (floatFromVal(lval)-floatFromVal(rval))>=0;
1194 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1196 if (IS_FLOAT (val->type))
1197 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1200 if (SPEC_LONG (val->type))
1202 if (SPEC_USIGN (val->type)) {
1203 SPEC_CVAL (val->type).v_ulong =
1204 (unsigned long) floatFromVal (lval) -
1205 (unsigned long) floatFromVal (rval);
1207 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1208 (long) floatFromVal (rval);
1213 if (SPEC_USIGN (val->type)) {
1214 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1215 (unsigned) floatFromVal (rval);
1217 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1218 (int) floatFromVal (rval);
1222 return cheapestVal(val);
1225 /*------------------------------------------------------------------*/
1226 /* valShift - Shift left or right */
1227 /*------------------------------------------------------------------*/
1229 valShift (value * lval, value * rval, int lr)
1233 /* create a new value */
1235 val->type = val->etype = newIntLink ();
1236 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1237 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1238 SPEC_LONG (val->type) = 1;
1240 if (SPEC_LONG (val->type))
1242 if (SPEC_USIGN (val->type))
1243 SPEC_CVAL (val->type).v_ulong = lr ?
1244 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1245 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1247 SPEC_CVAL (val->type).v_long = lr ?
1248 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1249 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1252 return cheapestVal(val);
1255 /*------------------------------------------------------------------*/
1256 /* valCompare- Compares two literal */
1257 /*------------------------------------------------------------------*/
1259 valCompare (value * lval, value * rval, int ctype)
1263 /* create a new value */
1265 val->type = val->etype = newCharLink ();
1266 val->type->class = SPECIFIER;
1267 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1268 SPEC_USIGN (val->type) = 1;
1269 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1274 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1278 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1282 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1286 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1290 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1294 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1302 /*------------------------------------------------------------------*/
1303 /* valBitwise - Bitwise operation */
1304 /*------------------------------------------------------------------*/
1306 valBitwise (value * lval, value * rval, int op)
1310 /* create a new value */
1312 val->type = copyLinkChain (getSize(rval->type) > getSize(lval->type) ?
1313 rval->type : lval->type);
1314 val->etype = getSpec (val->type);
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 = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1339 if (SPEC_LONG (val->type))
1341 if (SPEC_USIGN (val->type))
1342 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1343 (unsigned long) floatFromVal (rval);
1345 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1346 (long) floatFromVal (rval);
1350 if (SPEC_USIGN (val->type))
1351 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1352 (unsigned) floatFromVal (rval);
1354 SPEC_CVAL (val->type).v_int =
1355 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1361 if (SPEC_LONG (val->type))
1363 if (SPEC_USIGN (val->type))
1364 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1365 (unsigned long) floatFromVal (rval);
1367 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1368 (long) floatFromVal (rval);
1372 if (SPEC_USIGN (val->type))
1373 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1374 (unsigned) floatFromVal (rval);
1376 SPEC_CVAL (val->type).v_int =
1377 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1382 return cheapestVal(val);
1385 /*------------------------------------------------------------------*/
1386 /* valAndOr - Generates code for and / or operation */
1387 /*------------------------------------------------------------------*/
1389 valLogicAndOr (value * lval, value * rval, int op)
1393 /* create a new value */
1395 val->type = val->etype = newCharLink ();
1396 val->type->class = SPECIFIER;
1397 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1398 SPEC_USIGN (val->type) = 0;
1403 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1407 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1415 /*------------------------------------------------------------------*/
1416 /* valCastLiteral - casts a literal value to another type */
1417 /*------------------------------------------------------------------*/
1419 valCastLiteral (sym_link * dtype, double fval)
1427 val->etype = getSpec (val->type = copyLinkChain (dtype));
1428 SPEC_SCLS (val->etype) = S_LITERAL;
1429 /* if it is not a specifier then we can assume that */
1430 /* it will be an unsigned long */
1431 if (!IS_SPEC (val->type)) {
1432 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1436 if (SPEC_NOUN (val->etype) == V_FLOAT)
1437 SPEC_CVAL (val->etype).v_float = fval;
1439 unsigned long l = fval;
1440 if (SPEC_LONG (val->etype)) {
1441 if (SPEC_USIGN (val->etype))
1442 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1444 SPEC_CVAL (val->etype).v_long = (long) l;
1446 if (SPEC_USIGN (val->etype))
1447 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1449 SPEC_CVAL (val->etype).v_int = (short)l;
1455 /*------------------------------------------------------------------*/
1456 /* getNelements - determines # of elements from init list */
1457 /*------------------------------------------------------------------*/
1459 getNelements (sym_link * type, initList * ilist)
1466 if (ilist->type == INIT_DEEP)
1467 ilist = ilist->init.deep;
1469 /* if type is a character array and there is only one
1470 (string) initialiser then get the length of the string */
1471 if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1473 ast *iast = ilist->init.node;
1474 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1477 werror (E_CONST_EXPECTED);
1481 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1482 // yep, it's a string
1484 return DCL_ELEM (v->type);
1492 ilist = ilist->next;
1497 /*-----------------------------------------------------------------*/
1498 /* valForArray - returns a value with name of array index */
1499 /*-----------------------------------------------------------------*/
1501 valForArray (ast * arrExpr)
1503 value *val, *lval = NULL;
1505 int size = getSize (arrExpr->left->ftype->next);
1506 /* if the right or left is an array
1508 if (IS_AST_OP (arrExpr->left))
1510 if (arrExpr->left->opval.op == '[')
1511 lval = valForArray (arrExpr->left);
1512 else if (arrExpr->left->opval.op == '.')
1513 lval = valForStructElem (arrExpr->left->left,
1514 arrExpr->left->right);
1515 else if (arrExpr->left->opval.op == PTR_OP &&
1516 IS_ADDRESS_OF_OP (arrExpr->left->left))
1517 lval = valForStructElem (arrExpr->left->left->left,
1518 arrExpr->left->right);
1523 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1526 if (!IS_AST_LIT_VALUE (arrExpr->right))
1531 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1533 sprintf (buffer, "%s", lval->name);
1535 sprintf (val->name, "(%s + %d)", buffer,
1536 (int) AST_LIT_VALUE (arrExpr->right) * size);
1538 val->type = newLink ();
1539 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1541 DCL_TYPE (val->type) = CPOINTER;
1542 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1544 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1545 DCL_TYPE (val->type) = FPOINTER;
1546 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1547 DCL_TYPE (val->type) = PPOINTER;
1548 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1549 DCL_TYPE (val->type) = IPOINTER;
1550 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1551 DCL_TYPE (val->type) = EEPPOINTER;
1553 DCL_TYPE (val->type) = POINTER;
1554 val->type->next = arrExpr->left->ftype;
1555 val->etype = getSpec (val->type);
1559 /*-----------------------------------------------------------------*/
1560 /* valForStructElem - returns value with name of struct element */
1561 /*-----------------------------------------------------------------*/
1563 valForStructElem (ast * structT, ast * elemT)
1565 value *val, *lval = NULL;
1569 /* left could be furthur derefed */
1570 if (IS_AST_OP (structT))
1572 if (structT->opval.op == '[')
1573 lval = valForArray (structT);
1574 else if (structT->opval.op == '.')
1575 lval = valForStructElem (structT->left, structT->right);
1576 else if (structT->opval.op == PTR_OP &&
1577 IS_ADDRESS_OF_OP (structT->left))
1578 lval = valForStructElem (structT->left->left,
1584 if (!IS_AST_SYM_VALUE (elemT))
1587 if (!IS_STRUCT (structT->etype))
1590 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1591 AST_SYMBOL (elemT))) == NULL)
1598 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1600 sprintf (buffer, "%s", lval->name);
1602 sprintf (val->name, "(%s + %d)", buffer,
1605 val->type = newLink ();
1606 if (SPEC_SCLS (structT->etype) == S_CODE)
1608 DCL_TYPE (val->type) = CPOINTER;
1609 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1611 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1612 DCL_TYPE (val->type) = FPOINTER;
1613 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1614 DCL_TYPE (val->type) = PPOINTER;
1615 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1616 DCL_TYPE (val->type) = IPOINTER;
1617 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1618 DCL_TYPE (val->type) = EEPPOINTER;
1620 DCL_TYPE (val->type) = POINTER;
1621 val->type->next = sym->type;
1622 val->etype = getSpec (val->type);
1626 /*-----------------------------------------------------------------*/
1627 /* valForCastAggr - will return value for a cast of an aggregate */
1628 /* plus minus a constant */
1629 /*-----------------------------------------------------------------*/
1631 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1635 if (!IS_AST_SYM_VALUE (aexpr))
1637 if (!IS_AST_LIT_VALUE (cnst))
1642 sprintf (val->name, "(%s %c %d)",
1643 AST_SYMBOL (aexpr)->rname, op,
1644 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1647 val->etype = getSpec (val->type);
1651 /*-----------------------------------------------------------------*/
1652 /* valForCastAggr - will return value for a cast of an aggregate */
1653 /* with no constant */
1654 /*-----------------------------------------------------------------*/
1656 valForCastArr (ast * aexpr, sym_link * type)
1660 if (!IS_AST_SYM_VALUE (aexpr))
1665 sprintf (val->name, "(%s)",
1666 AST_SYMBOL (aexpr)->rname);
1669 val->etype = getSpec (val->type);