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;
911 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
912 "floatFromVal: unknown value");
917 /*------------------------------------------------------------------*/
918 /* valUnaryPM - does the unary +/- operation on a constant */
919 /*------------------------------------------------------------------*/
921 valUnaryPM (value * val)
923 /* depending on type */
924 if (SPEC_NOUN (val->etype) == V_FLOAT)
925 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
928 if (SPEC_LONG (val->etype))
930 if (SPEC_USIGN (val->etype))
931 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
933 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
937 if (SPEC_USIGN (val->etype))
938 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
940 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
943 // -(unsigned 3) now really is signed
944 SPEC_USIGN(val->etype)=0;
948 /*------------------------------------------------------------------*/
949 /* valueComplement - complements a constant */
950 /*------------------------------------------------------------------*/
952 valComplement (value * val)
954 /* depending on type */
955 if (SPEC_LONG (val->etype))
957 if (SPEC_USIGN (val->etype))
958 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
960 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
964 if (SPEC_USIGN (val->etype))
965 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
967 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
969 // ~(unsigned 3) now really is signed
970 SPEC_USIGN(val->etype)=0;
974 /*------------------------------------------------------------------*/
975 /* valueNot - complements a constant */
976 /*------------------------------------------------------------------*/
980 /* depending on type */
981 if (SPEC_LONG (val->etype))
983 if (SPEC_USIGN (val->etype))
984 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
986 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
990 if (SPEC_USIGN (val->etype))
991 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
993 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
998 /*------------------------------------------------------------------*/
999 /* valMult - multiply constants */
1000 /*------------------------------------------------------------------*/
1002 valMult (value * lval, value * rval)
1006 /* create a new value */
1008 val->type = val->etype = newLink ();
1009 val->type->class = SPECIFIER;
1010 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1011 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1012 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1013 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1014 SPEC_LONG (val->type) = 1;
1016 if (IS_FLOAT (val->type))
1017 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1020 if (SPEC_LONG (val->type))
1022 if (SPEC_USIGN (val->type))
1023 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
1024 (unsigned long) floatFromVal (rval);
1026 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
1027 (long) floatFromVal (rval);
1030 return cheapestVal(val);
1033 /*------------------------------------------------------------------*/
1034 /* valDiv - Divide constants */
1035 /*------------------------------------------------------------------*/
1037 valDiv (value * lval, value * rval)
1041 if (floatFromVal (rval) == 0)
1043 werror (E_DIVIDE_BY_ZERO);
1047 /* create a new value */
1049 val->type = val->etype = newLink();
1050 val->type->class = SPECIFIER;
1051 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1052 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1053 SPEC_SCLS (val->etype) = S_LITERAL;
1054 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1055 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1057 if (IS_FLOAT (val->type))
1058 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1061 if (SPEC_LONG (val->type))
1063 if (SPEC_USIGN (val->type))
1064 SPEC_CVAL (val->type).v_ulong =
1065 (unsigned long) floatFromVal (lval) /
1066 (unsigned long) floatFromVal (rval);
1068 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
1069 (long) floatFromVal (rval);
1073 if (SPEC_USIGN (val->type)) {
1074 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1075 (unsigned) floatFromVal (rval);
1077 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1078 (int) floatFromVal (rval);
1082 return cheapestVal(val);
1085 /*------------------------------------------------------------------*/
1086 /* valMod - Modulus constants */
1087 /*------------------------------------------------------------------*/
1089 valMod (value * lval, value * rval)
1093 /* create a new value */
1095 val->type = val->etype = newLink ();
1096 val->type->class = SPECIFIER;
1097 SPEC_NOUN (val->type) = V_INT; /* type is int */
1098 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1099 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1100 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1102 if (SPEC_LONG (val->type))
1104 if (SPEC_USIGN (val->type))
1105 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1106 (unsigned long) floatFromVal (rval);
1108 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1109 (unsigned long) floatFromVal (rval);
1113 if (SPEC_USIGN (val->type)) {
1114 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1115 (unsigned) floatFromVal (rval);
1117 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1118 (unsigned) floatFromVal (rval);
1122 return cheapestVal(val);
1125 /*------------------------------------------------------------------*/
1126 /* valPlus - Addition constants */
1127 /*------------------------------------------------------------------*/
1129 valPlus (value * lval, value * rval)
1133 /* create a new value */
1135 val->type = val->etype = newLink ();
1136 val->type->class = SPECIFIER;
1137 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1138 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1139 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1140 SPEC_USIGN (val->type) =
1141 SPEC_USIGN (lval->etype) &&
1142 SPEC_USIGN (rval->etype) &&
1143 (floatFromVal(lval)+floatFromVal(rval))>=0;
1145 SPEC_LONG (val->type) = 1;
1147 if (IS_FLOAT (val->type))
1148 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1151 if (SPEC_LONG (val->type))
1153 if (SPEC_USIGN (val->type))
1154 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1155 (unsigned long) floatFromVal (rval);
1157 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1158 (long) floatFromVal (rval);
1161 return cheapestVal(val);
1164 /*------------------------------------------------------------------*/
1165 /* valMinus - Addition constants */
1166 /*------------------------------------------------------------------*/
1168 valMinus (value * lval, value * rval)
1172 /* create a new value */
1174 val->type = val->etype = newLink ();
1175 val->type->class = SPECIFIER;
1176 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1177 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1178 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1179 SPEC_USIGN (val->type) =
1180 SPEC_USIGN (lval->etype) &&
1181 SPEC_USIGN (rval->etype) &&
1182 (floatFromVal(lval)-floatFromVal(rval))>=0;
1184 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1186 if (IS_FLOAT (val->type))
1187 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1190 if (SPEC_LONG (val->type))
1192 if (SPEC_USIGN (val->type)) {
1193 SPEC_CVAL (val->type).v_ulong =
1194 (unsigned long) floatFromVal (lval) -
1195 (unsigned long) floatFromVal (rval);
1197 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1198 (long) floatFromVal (rval);
1203 if (SPEC_USIGN (val->type)) {
1204 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1205 (unsigned) floatFromVal (rval);
1207 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) -
1208 (int) floatFromVal (rval);
1212 return cheapestVal(val);
1215 /*------------------------------------------------------------------*/
1216 /* valShift - Shift left or right */
1217 /*------------------------------------------------------------------*/
1219 valShift (value * lval, value * rval, int lr)
1223 /* create a new value */
1225 val->type = val->etype = newIntLink ();
1226 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1227 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) & SPEC_USIGN (rval->etype));
1228 SPEC_LONG (val->type) = 1;
1230 if (SPEC_LONG (val->type))
1232 if (SPEC_USIGN (val->type))
1233 SPEC_CVAL (val->type).v_ulong = lr ?
1234 (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1235 (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1237 SPEC_CVAL (val->type).v_long = lr ?
1238 (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1239 (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1242 return cheapestVal(val);
1245 /*------------------------------------------------------------------*/
1246 /* valCompare- Compares two literal */
1247 /*------------------------------------------------------------------*/
1249 valCompare (value * lval, value * rval, int ctype)
1253 /* create a new value */
1255 val->type = val->etype = newCharLink ();
1256 val->type->class = SPECIFIER;
1257 SPEC_NOUN (val->type) = V_CHAR; /* type is char */
1258 SPEC_USIGN (val->type) = 1;
1259 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
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);
1284 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1292 /*------------------------------------------------------------------*/
1293 /* valBitwise - Bitwise operation */
1294 /*------------------------------------------------------------------*/
1296 valBitwise (value * lval, value * rval, int op)
1300 /* create a new value */
1302 val->type = copyLinkChain (lval->type);
1303 val->etype = getSpec (val->type);
1308 if (SPEC_LONG (val->type))
1310 if (SPEC_USIGN (val->type))
1311 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1312 (unsigned long) floatFromVal (rval);
1314 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1315 (long) floatFromVal (rval);
1319 if (SPEC_USIGN (val->type))
1320 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1321 (unsigned) floatFromVal (rval);
1323 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1328 if (SPEC_LONG (val->type))
1330 if (SPEC_USIGN (val->type))
1331 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1332 (unsigned long) floatFromVal (rval);
1334 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1335 (long) floatFromVal (rval);
1339 if (SPEC_USIGN (val->type))
1340 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1341 (unsigned) floatFromVal (rval);
1343 SPEC_CVAL (val->type).v_int =
1344 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1350 if (SPEC_LONG (val->type))
1352 if (SPEC_USIGN (val->type))
1353 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1354 (unsigned long) floatFromVal (rval);
1356 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1357 (long) floatFromVal (rval);
1361 if (SPEC_USIGN (val->type))
1362 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1363 (unsigned) floatFromVal (rval);
1365 SPEC_CVAL (val->type).v_int =
1366 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1371 return cheapestVal(val);
1374 /*------------------------------------------------------------------*/
1375 /* valAndOr - Generates code for and / or operation */
1376 /*------------------------------------------------------------------*/
1378 valLogicAndOr (value * lval, value * rval, int op)
1382 /* create a new value */
1384 val->type = val->etype = newCharLink ();
1385 val->type->class = SPECIFIER;
1386 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1387 SPEC_USIGN (val->type) = 0;
1392 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1396 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1404 /*------------------------------------------------------------------*/
1405 /* valCastLiteral - casts a literal value to another type */
1406 /*------------------------------------------------------------------*/
1408 valCastLiteral (sym_link * dtype, double fval)
1416 val->etype = getSpec (val->type = copyLinkChain (dtype));
1417 SPEC_SCLS (val->etype) = S_LITERAL;
1418 /* if it is not a specifier then we can assume that */
1419 /* it will be an unsigned long */
1420 if (!IS_SPEC (val->type)) {
1421 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1425 if (SPEC_NOUN (val->etype) == V_FLOAT)
1426 SPEC_CVAL (val->etype).v_float = fval;
1428 unsigned long l = fval;
1429 if (SPEC_LONG (val->etype)) {
1430 if (SPEC_USIGN (val->etype))
1431 SPEC_CVAL (val->etype).v_ulong = (unsigned long) l;
1433 SPEC_CVAL (val->etype).v_long = (long) l;
1435 if (SPEC_USIGN (val->etype))
1436 SPEC_CVAL (val->etype).v_uint = (unsigned short)l;
1438 SPEC_CVAL (val->etype).v_int = (short)l;
1444 /*------------------------------------------------------------------*/
1445 /* getNelements - determines # of elements from init list */
1446 /*------------------------------------------------------------------*/
1448 getNelements (sym_link * type, initList * ilist)
1450 sym_link *etype = getSpec (type);
1456 if (ilist->type == INIT_DEEP)
1457 ilist = ilist->init.deep;
1459 /* if type is a character array and there is only one
1460 (string) initialiser then get the length of the string */
1461 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1463 ast *iast = ilist->init.node;
1464 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1467 werror (W_INIT_WRONG);
1471 if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1472 // yep, it's a string
1474 return DCL_ELEM (v->type);
1482 ilist = ilist->next;
1488 /*-----------------------------------------------------------------*/
1489 /* valForArray - returns a value with name of array index */
1490 /*-----------------------------------------------------------------*/
1492 valForArray (ast * arrExpr)
1494 value *val, *lval = NULL;
1496 int size = getSize (arrExpr->left->ftype->next);
1497 /* if the right or left is an array
1499 if (IS_AST_OP (arrExpr->left))
1501 if (arrExpr->left->opval.op == '[')
1502 lval = valForArray (arrExpr->left);
1503 else if (arrExpr->left->opval.op == '.')
1504 lval = valForStructElem (arrExpr->left->left,
1505 arrExpr->left->right);
1506 else if (arrExpr->left->opval.op == PTR_OP &&
1507 IS_ADDRESS_OF_OP (arrExpr->left->left))
1508 lval = valForStructElem (arrExpr->left->left->left,
1509 arrExpr->left->right);
1514 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1517 if (!IS_AST_LIT_VALUE (arrExpr->right))
1522 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1524 sprintf (buffer, "%s", lval->name);
1526 sprintf (val->name, "(%s + %d)", buffer,
1527 (int) AST_LIT_VALUE (arrExpr->right) * size);
1529 val->type = newLink ();
1530 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1532 DCL_TYPE (val->type) = CPOINTER;
1533 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1535 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1536 DCL_TYPE (val->type) = FPOINTER;
1537 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1538 DCL_TYPE (val->type) = PPOINTER;
1539 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1540 DCL_TYPE (val->type) = IPOINTER;
1541 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1542 DCL_TYPE (val->type) = EEPPOINTER;
1544 DCL_TYPE (val->type) = POINTER;
1545 val->type->next = arrExpr->left->ftype;
1546 val->etype = getSpec (val->type);
1550 /*-----------------------------------------------------------------*/
1551 /* valForStructElem - returns value with name of struct element */
1552 /*-----------------------------------------------------------------*/
1554 valForStructElem (ast * structT, ast * elemT)
1556 value *val, *lval = NULL;
1560 /* left could be furthur derefed */
1561 if (IS_AST_OP (structT))
1563 if (structT->opval.op == '[')
1564 lval = valForArray (structT);
1565 else if (structT->opval.op == '.')
1566 lval = valForStructElem (structT->left, structT->right);
1567 else if (structT->opval.op == PTR_OP &&
1568 IS_ADDRESS_OF_OP (structT->left))
1569 lval = valForStructElem (structT->left->left,
1575 if (!IS_AST_SYM_VALUE (elemT))
1578 if (!IS_STRUCT (structT->etype))
1581 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1582 AST_SYMBOL (elemT))) == NULL)
1589 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1591 sprintf (buffer, "%s", lval->name);
1593 sprintf (val->name, "(%s + %d)", buffer,
1596 val->type = newLink ();
1597 if (SPEC_SCLS (structT->etype) == S_CODE)
1599 DCL_TYPE (val->type) = CPOINTER;
1600 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1602 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1603 DCL_TYPE (val->type) = FPOINTER;
1604 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1605 DCL_TYPE (val->type) = PPOINTER;
1606 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1607 DCL_TYPE (val->type) = IPOINTER;
1608 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1609 DCL_TYPE (val->type) = EEPPOINTER;
1611 DCL_TYPE (val->type) = POINTER;
1612 val->type->next = sym->type;
1613 val->etype = getSpec (val->type);
1617 /*-----------------------------------------------------------------*/
1618 /* valForCastAggr - will return value for a cast of an aggregate */
1619 /* plus minus a constant */
1620 /*-----------------------------------------------------------------*/
1622 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1626 if (!IS_AST_SYM_VALUE (aexpr))
1628 if (!IS_AST_LIT_VALUE (cnst))
1633 sprintf (val->name, "(%s %c %d)",
1634 AST_SYMBOL (aexpr)->rname, op,
1635 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1638 val->etype = getSpec (val->type);
1642 /*-----------------------------------------------------------------*/
1643 /* valForCastAggr - will return value for a cast of an aggregate */
1644 /* with no constant */
1645 /*-----------------------------------------------------------------*/
1647 valForCastArr (ast * aexpr, sym_link * type)
1651 if (!IS_AST_SYM_VALUE (aexpr))
1656 sprintf (val->name, "(%s)",
1657 AST_SYMBOL (aexpr)->rname);
1660 val->etype = getSpec (val->type);