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_calloc (1, sizeof (value));
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list */
49 /*-----------------------------------------------------------------*/
51 newiList (int type, void *ilist)
56 nilist = Safe_calloc (1, 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;
100 /*------------------------------------------------------------------*/
101 /* copyIlist - copy initializer list */
102 /*------------------------------------------------------------------*/
104 copyIlist (initList * src)
106 initList *dest = NULL;
114 dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
117 dest = newiList (INIT_NODE, copyAst (src->init.node));
122 dest->next = copyIlist (src->next);
127 /*------------------------------------------------------------------*/
128 /* list2int - converts the first element of the list to value */
129 /*------------------------------------------------------------------*/
131 list2int (initList * val)
135 if (i->type == INIT_DEEP)
136 return list2int (val->init.deep);
138 return floatFromVal (constExprValue (val->init.node, TRUE));
141 /*------------------------------------------------------------------*/
142 /* list2val - converts the first element of the list to value */
143 /*------------------------------------------------------------------*/
145 list2val (initList * val)
150 if (val->type == INIT_DEEP)
151 return list2val (val->init.deep);
153 return constExprValue (val->init.node, TRUE);
156 /*------------------------------------------------------------------*/
157 /* list2expr - returns the first expression in the initializer list */
158 /*------------------------------------------------------------------*/
160 list2expr (initList * ilist)
162 if (ilist->type == INIT_DEEP)
163 return list2expr (ilist->init.deep);
164 return ilist->init.node;
167 /*------------------------------------------------------------------*/
168 /* resolveIvalSym - resolve symbols in initial values */
169 /*------------------------------------------------------------------*/
171 resolveIvalSym (initList * ilist)
176 if (ilist->type == INIT_NODE)
177 ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
179 if (ilist->type == INIT_DEEP)
180 resolveIvalSym (ilist->init.deep);
182 resolveIvalSym (ilist->next);
185 /*-----------------------------------------------------------------*/
186 /* symbolVal - creates a value for a symbol */
187 /*-----------------------------------------------------------------*/
189 symbolVal (symbol * sym)
201 val->type = sym->type;
202 val->etype = getSpec (val->type);
206 sprintf (val->name, "%s", sym->rname);
208 sprintf (val->name, "_%s", sym->name);
214 /*-----------------------------------------------------------------*/
215 /* valueFromLit - creates a value from a literal */
216 /*-----------------------------------------------------------------*/
218 valueFromLit (float lit)
222 if ((((long) lit) - lit) == 0)
224 sprintf (buffer, "%ld", (long) lit);
225 return constVal (buffer);
228 sprintf (buffer, "%f", lit);
229 return constFloatVal (buffer);
232 /*-----------------------------------------------------------------*/
233 /* constFloatVal - converts a FLOAT constant to value */
234 /*-----------------------------------------------------------------*/
236 constFloatVal (char *s)
238 value *val = newValue ();
241 if (sscanf (s, "%f", &sval) != 1)
243 werror (E_INVALID_FLOAT_CONST, s);
244 return constVal ("0");
247 val->type = val->etype = newLink ();
248 val->type->class = SPECIFIER;
249 SPEC_NOUN (val->type) = V_FLOAT;
250 SPEC_SCLS (val->type) = S_LITERAL;
251 SPEC_CVAL (val->type).v_float = sval;
256 /*-----------------------------------------------------------------*/
257 /* constVal - converts a INTEGER constant into a value */
258 /*-----------------------------------------------------------------*/
263 short hex = 0, octal = 0;
268 val = newValue (); /* alloc space for value */
270 val->type = val->etype = newLink (); /* create the spcifier */
271 val->type->class = SPECIFIER;
272 SPEC_NOUN (val->type) = V_INT;
273 SPEC_SCLS (val->type) = S_LITERAL;
275 /* set the _unsigned flag if 'uU' found */
276 if (strchr (s, 'u') || strchr (s, 'U'))
277 SPEC_USIGN (val->type) = 1;
279 /* set the _long flag if 'lL' is found */
280 if (strchr (s, 'l') || strchr (s, 'L'))
281 SPEC_LONG (val->type) = 1;
283 hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
285 /* set the octal flag */
286 if (!hex && *s == '0' && *(s + 1))
289 /* create the scan string */
290 scanFmt[scI++] = '%';
293 scanFmt[scI++] = 'o';
295 scanFmt[scI++] = 'x';
296 else if (SPEC_USIGN (val->type))
297 scanFmt[scI++] = 'u';
299 scanFmt[scI++] = 'd';
301 scanFmt[scI++] = '\0';
303 /* if hex or octal then set the unsigned flag */
306 SPEC_USIGN (val->type) = 1;
307 sscanf (s, scanFmt, &sval);
313 if (SPEC_LONG (val->type) || sval > 32768)
315 if (SPEC_USIGN (val->type))
316 SPEC_CVAL (val->type).v_ulong = sval;
318 SPEC_CVAL (val->type).v_long = sval;
319 SPEC_LONG (val->type) = 1;
323 if (SPEC_USIGN (val->type))
324 SPEC_CVAL (val->type).v_uint = sval;
326 SPEC_CVAL (val->type).v_int = sval;
329 // check the size and make it a short if required
331 SPEC_SHORT (val->etype) = 1;
337 /*------------------------------------------------------------------*/
338 /* octalEscape - process an octal constant of max three digits */
339 /* return the octal value, throw a warning for illegal octal */
340 /* adjust src to point at the last proccesed char */
341 /*------------------------------------------------------------------*/
343 char octalEscape (char **str) {
347 for (digits=0; digits<3; digits++) {
348 if (**str>='0' && **str<='7') {
349 value = value*8 + (**str-'0');
356 if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
357 werror (W_ESC_SEQ_OOR_FOR_CHAR);
364 /*------------------------------------------------------------------*/
365 /* copyStr - copies src to dest ignoring leading & trailing \"s */
366 /*------------------------------------------------------------------*/
368 copyStr (char *dest, char *src)
374 else if (*src == '\\')
409 *dest++ = octalEscape(&src);
414 unsigned long value=strtol (src, &src, 16);
417 // no valid hex found
418 werror(E_INVALID_HEX);
421 werror(W_ESC_SEQ_OOR_FOR_CHAR);
453 /*------------------------------------------------------------------*/
454 /* strVal - converts a string constant to a value */
455 /*------------------------------------------------------------------*/
461 val = newValue (); /* get a new one */
463 /* get a declarator */
464 val->type = newLink ();
465 DCL_TYPE (val->type) = ARRAY;
466 DCL_ELEM (val->type) = strlen (s) - 1;
467 val->type->next = val->etype = newLink ();
468 val->etype->class = SPECIFIER;
469 SPEC_NOUN (val->etype) = V_CHAR;
470 SPEC_SCLS (val->etype) = S_LITERAL;
472 SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
473 copyStr (SPEC_CVAL (val->etype).v_char, s);
478 /*------------------------------------------------------------------*/
479 /* reverseValWithType - reverses value chain with type & etype */
480 /*------------------------------------------------------------------*/
482 reverseValWithType (value * val)
490 /* save the type * etype chains */
494 /* set the current one 2b null */
495 val->type = val->etype = NULL;
496 val = reverseVal (val);
498 /* restore type & etype */
505 /*------------------------------------------------------------------*/
506 /* reverseVal - reverses the values for a value chain */
507 /*------------------------------------------------------------------*/
509 reverseVal (value * val)
511 value *prev, *curr, *next;
526 val->next = (void *) NULL;
530 /*------------------------------------------------------------------*/
531 /* copyValueChain - will copy a chain of values */
532 /*------------------------------------------------------------------*/
534 copyValueChain (value * src)
541 dest = copyValue (src);
542 dest->next = copyValueChain (src->next);
547 /*------------------------------------------------------------------*/
548 /* copyValue - copies contents of a vlue to a fresh one */
549 /*------------------------------------------------------------------*/
551 copyValue (value * src)
556 dest->sym = copySymbol (src->sym);
557 strcpy (dest->name, src->name);
558 dest->type = (src->type ? copyLinkChain (src->type) : NULL);
559 dest->etype = (src->type ? getSpec (dest->type) : NULL);
564 /*------------------------------------------------------------------*/
565 /* charVal - converts a character constant to a value */
566 /*------------------------------------------------------------------*/
574 val->type = val->etype = newLink ();
575 val->type->class = SPECIFIER;
576 SPEC_NOUN (val->type) = V_CHAR;
577 SPEC_SCLS (val->type) = S_LITERAL;
579 s++; /* get rid of quotation */
580 /* if \ then special processing */
583 s++; /* go beyond the backslash */
587 SPEC_CVAL (val->type).v_int = '\n';
590 SPEC_CVAL (val->type).v_int = '\t';
593 SPEC_CVAL (val->type).v_int = '\v';
596 SPEC_CVAL (val->type).v_int = '\b';
599 SPEC_CVAL (val->type).v_int = '\r';
602 SPEC_CVAL (val->type).v_int = '\f';
605 SPEC_CVAL (val->type).v_int = '\a';
608 SPEC_CVAL (val->type).v_int = '\\';
611 SPEC_CVAL (val->type).v_int = '\?';
614 SPEC_CVAL (val->type).v_int = '\'';
617 SPEC_CVAL (val->type).v_int = '\"';
620 sscanf (s, "%o", &SPEC_CVAL (val->type).v_int);
623 s++; /* go behond the 'x' */
624 sscanf (s, "%x", &SPEC_CVAL (val->type).v_int);
627 SPEC_CVAL (val->type).v_int = *s;
631 else /* not a backslash */
632 SPEC_CVAL (val->type).v_int = *s;
637 /*------------------------------------------------------------------*/
638 /* valFromType - creates a value from type given */
639 /*------------------------------------------------------------------*/
641 valFromType (sym_link * type)
643 value *val = newValue ();
644 val->type = copyLinkChain (type);
645 val->etype = getSpec (val->type);
649 /*------------------------------------------------------------------*/
650 /* floatFromVal - value to unsinged integer conversion */
651 /*------------------------------------------------------------------*/
653 floatFromVal (value * val)
658 if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
660 werror (E_CONST_EXPECTED, val->name);
664 /* if it is not a specifier then we can assume that */
665 /* it will be an unsigned long */
666 if (!IS_SPEC (val->type))
667 return (double) SPEC_CVAL (val->etype).v_ulong;
669 if (SPEC_NOUN (val->etype) == V_FLOAT)
670 return (double) SPEC_CVAL (val->etype).v_float;
673 if (SPEC_LONG (val->etype))
675 if (SPEC_USIGN (val->etype))
676 return (double) SPEC_CVAL (val->etype).v_ulong;
678 return (double) SPEC_CVAL (val->etype).v_long;
682 if (SPEC_USIGN (val->etype))
683 return (double) SPEC_CVAL (val->etype).v_uint;
685 return (double) SPEC_CVAL (val->etype).v_int;
691 /*------------------------------------------------------------------*/
692 /* valUnaryPM - dones the unary +/- operation on a constant */
693 /*------------------------------------------------------------------*/
695 valUnaryPM (value * val)
697 /* depending on type */
698 if (SPEC_NOUN (val->etype) == V_FLOAT)
699 SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
702 if (SPEC_LONG (val->etype))
704 if (SPEC_USIGN (val->etype))
705 SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
707 SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
711 if (SPEC_USIGN (val->etype))
712 SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
714 SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
721 /*------------------------------------------------------------------*/
722 /* valueComplement - complements a constant */
723 /*------------------------------------------------------------------*/
725 valComplement (value * val)
727 /* depending on type */
728 if (SPEC_LONG (val->etype))
730 if (SPEC_USIGN (val->etype))
731 SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
733 SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
737 if (SPEC_USIGN (val->etype))
738 SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
740 SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
745 /*------------------------------------------------------------------*/
746 /* valueNot - complements a constant */
747 /*------------------------------------------------------------------*/
751 /* depending on type */
752 if (SPEC_LONG (val->etype))
754 if (SPEC_USIGN (val->etype))
755 SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
757 SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
761 if (SPEC_USIGN (val->etype))
762 SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
764 SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
769 /*------------------------------------------------------------------*/
770 /* valMult - multiply constants */
771 /*------------------------------------------------------------------*/
773 valMult (value * lval, value * rval)
777 /* create a new value */
779 val->type = val->etype = newLink ();
780 val->type->class = SPECIFIER;
781 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
782 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
783 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
784 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
785 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
787 if (IS_FLOAT (val->type))
788 SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
791 if (SPEC_LONG (val->type))
793 if (SPEC_USIGN (val->type))
794 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
795 (unsigned long) floatFromVal (rval);
797 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
798 (long) floatFromVal (rval);
802 if (SPEC_USIGN (val->type))
803 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
804 (unsigned) floatFromVal (rval);
806 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
807 (int) floatFromVal (rval);
813 /*------------------------------------------------------------------*/
814 /* valDiv - Divide constants */
815 /*------------------------------------------------------------------*/
817 valDiv (value * lval, value * rval)
821 if (floatFromVal (rval) == 0)
823 werror (E_DIVIDE_BY_ZERO);
827 /* create a new value */
829 val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ?
830 newCharLink () : newIntLink ());
831 if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype))
832 SPEC_NOUN (val->etype) = V_FLOAT;
833 SPEC_SCLS (val->etype) = S_LITERAL;
834 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
835 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
837 if (IS_FLOAT (val->type))
838 SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
841 if (SPEC_LONG (val->type))
843 if (SPEC_USIGN (val->type))
844 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
845 (unsigned long) floatFromVal (rval);
847 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
848 (long) floatFromVal (rval);
852 if (SPEC_USIGN (val->type))
853 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
854 (unsigned) floatFromVal (rval);
856 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
857 (int) floatFromVal (rval);
863 /*------------------------------------------------------------------*/
864 /* valMod - Modulus constants */
865 /*------------------------------------------------------------------*/
867 valMod (value * lval, value * rval)
871 /* create a new value */
873 val->type = val->etype = newLink ();
874 val->type->class = SPECIFIER;
875 SPEC_NOUN (val->type) = V_INT; /* type is int */
876 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
877 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
878 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
880 if (SPEC_LONG (val->type))
882 if (SPEC_USIGN (val->type))
883 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
884 (unsigned long) floatFromVal (rval);
886 SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
887 (unsigned long) floatFromVal (rval);
891 if (SPEC_USIGN (val->type))
892 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
893 (unsigned) floatFromVal (rval);
895 SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
896 (unsigned) floatFromVal (rval);
902 /*------------------------------------------------------------------*/
903 /* valPlus - Addition constants */
904 /*------------------------------------------------------------------*/
906 valPlus (value * lval, value * rval)
910 /* create a new value */
912 val->type = val->etype = newLink ();
913 val->type->class = SPECIFIER;
914 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
915 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
916 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
917 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
918 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
920 if (IS_FLOAT (val->type))
921 SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
924 if (SPEC_LONG (val->type))
926 if (SPEC_USIGN (val->type))
927 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
928 (unsigned long) floatFromVal (rval);
930 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
931 (long) floatFromVal (rval);
935 if (SPEC_USIGN (val->type))
936 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
937 (unsigned) floatFromVal (rval);
939 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
940 (int) floatFromVal (rval);
946 /*------------------------------------------------------------------*/
947 /* valMinus - Addition constants */
948 /*------------------------------------------------------------------*/
950 valMinus (value * lval, value * rval)
954 /* create a new value */
956 val->type = val->etype = newLink ();
957 val->type->class = SPECIFIER;
958 SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
959 IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
960 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
961 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
962 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
964 if (IS_FLOAT (val->type))
965 SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
968 if (SPEC_LONG (val->type))
970 if (SPEC_USIGN (val->type))
971 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) -
972 (unsigned long) floatFromVal (rval);
974 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
975 (long) floatFromVal (rval);
979 if (SPEC_USIGN (val->type))
980 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
981 (unsigned) floatFromVal (rval);
983 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
989 /*------------------------------------------------------------------*/
990 /* valShift - Shift left or right */
991 /*------------------------------------------------------------------*/
993 valShift (value * lval, value * rval, int lr)
997 /* create a new value */
999 val->type = val->etype = newLink ();
1000 val->type->class = SPECIFIER;
1001 SPEC_NOUN (val->type) = V_INT; /* type is int */
1002 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1003 SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1004 SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1008 if (SPEC_LONG (val->type))
1010 if (SPEC_USIGN (val->type))
1011 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) <<
1012 (unsigned long) floatFromVal (rval);
1014 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) <<
1015 (long) floatFromVal (rval);
1019 if (SPEC_USIGN (val->type))
1020 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) <<
1021 (unsigned) floatFromVal (rval);
1023 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) <<
1024 (int) floatFromVal (rval);
1029 if (SPEC_LONG (val->type))
1031 if (SPEC_USIGN (val->type))
1032 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >>
1033 (unsigned long) floatFromVal (rval);
1035 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >>
1036 (long) floatFromVal (rval);
1040 if (SPEC_USIGN (val->type))
1041 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >>
1042 (unsigned) floatFromVal (rval);
1044 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >>
1045 (int) floatFromVal (rval);
1052 /*------------------------------------------------------------------*/
1053 /* valCompare- Compares two literal */
1054 /*------------------------------------------------------------------*/
1056 valCompare (value * lval, value * rval, int ctype)
1060 /* create a new value */
1062 val->type = val->etype = newCharLink ();
1063 val->type->class = SPECIFIER;
1064 SPEC_NOUN (val->type) = V_INT; /* type is int */
1065 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1070 SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1074 SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1078 SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1082 SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1086 SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1090 SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1098 /*------------------------------------------------------------------*/
1099 /* valBitwise - Bitwise operation */
1100 /*------------------------------------------------------------------*/
1102 valBitwise (value * lval, value * rval, int op)
1106 /* create a new value */
1108 val->type = copyLinkChain (lval->type);
1109 val->etype = getSpec (val->type);
1114 if (SPEC_LONG (val->type))
1116 if (SPEC_USIGN (val->type))
1117 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1118 (unsigned long) floatFromVal (rval);
1120 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1121 (long) floatFromVal (rval);
1125 if (SPEC_USIGN (val->type))
1126 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1127 (unsigned) floatFromVal (rval);
1129 SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1134 if (SPEC_LONG (val->type))
1136 if (SPEC_USIGN (val->type))
1137 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1138 (unsigned long) floatFromVal (rval);
1140 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1141 (long) floatFromVal (rval);
1145 if (SPEC_USIGN (val->type))
1146 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1147 (unsigned) floatFromVal (rval);
1149 SPEC_CVAL (val->type).v_int =
1150 (int) floatFromVal (lval) | (int) floatFromVal (rval);
1156 if (SPEC_LONG (val->type))
1158 if (SPEC_USIGN (val->type))
1159 SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1160 (unsigned long) floatFromVal (rval);
1162 SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1163 (long) floatFromVal (rval);
1167 if (SPEC_USIGN (val->type))
1168 SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1169 (unsigned) floatFromVal (rval);
1171 SPEC_CVAL (val->type).v_int =
1172 (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1180 /*------------------------------------------------------------------*/
1181 /* valAndOr - Generates code for and / or operation */
1182 /*------------------------------------------------------------------*/
1184 valLogicAndOr (value * lval, value * rval, int op)
1188 /* create a new value */
1190 val->type = val->etype = newCharLink ();
1191 val->type->class = SPECIFIER;
1192 SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
1197 SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1201 SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1209 /*------------------------------------------------------------------*/
1210 /* valCastLiteral - casts a literal value to another type */
1211 /*------------------------------------------------------------------*/
1213 valCastLiteral (sym_link * dtype, double fval)
1221 val->etype = getSpec (val->type = copyLinkChain (dtype));
1222 SPEC_SCLS (val->etype) = S_LITERAL;
1223 /* if it is not a specifier then we can assume that */
1224 /* it will be an unsigned long */
1225 if (!IS_SPEC (val->type))
1227 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1231 if (SPEC_NOUN (val->etype) == V_FLOAT)
1232 SPEC_CVAL (val->etype).v_float = fval;
1235 if (SPEC_LONG (val->etype))
1237 if (SPEC_USIGN (val->etype))
1238 SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1240 SPEC_CVAL (val->etype).v_long = (long) fval;
1244 if (SPEC_USIGN (val->etype))
1245 SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1247 SPEC_CVAL (val->etype).v_int = (int) fval;
1253 /*------------------------------------------------------------------*/
1254 /* getNelements - determines # of elements from init list */
1255 /*------------------------------------------------------------------*/
1257 getNelements (sym_link * type, initList * ilist)
1259 sym_link *etype = getSpec (type);
1265 if (ilist->type == INIT_DEEP)
1266 ilist = ilist->init.deep;
1268 /* if type is a character array and there is only one
1269 initialiser then get the length of the string */
1270 if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1272 ast *iast = ilist->init.node;
1273 value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1276 werror (E_INIT_WRONG);
1279 if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype))
1281 werror (E_INIT_WRONG);
1284 return DCL_ELEM (v->type);
1291 ilist = ilist->next;
1297 /*-----------------------------------------------------------------*/
1298 /* valForArray - returns a value with name of array index */
1299 /*-----------------------------------------------------------------*/
1301 valForArray (ast * arrExpr)
1303 value *val, *lval = NULL;
1305 int size = getSize (arrExpr->left->ftype->next);
1306 /* if the right or left is an array
1308 if (IS_AST_OP (arrExpr->left))
1310 if (arrExpr->left->opval.op == '[')
1311 lval = valForArray (arrExpr->left);
1312 else if (arrExpr->left->opval.op == '.')
1313 lval = valForStructElem (arrExpr->left->left,
1314 arrExpr->left->right);
1315 else if (arrExpr->left->opval.op == PTR_OP &&
1316 IS_ADDRESS_OF_OP (arrExpr->left->left))
1317 lval = valForStructElem (arrExpr->left->left->left,
1318 arrExpr->left->right);
1323 else if (!IS_AST_SYM_VALUE (arrExpr->left))
1326 if (!IS_AST_LIT_VALUE (arrExpr->right))
1331 sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1333 sprintf (buffer, "%s", lval->name);
1335 sprintf (val->name, "(%s + %d)", buffer,
1336 (int) AST_LIT_VALUE (arrExpr->right) * size);
1338 val->type = newLink ();
1339 if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1341 DCL_TYPE (val->type) = CPOINTER;
1342 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1344 else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1345 DCL_TYPE (val->type) = FPOINTER;
1346 else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1347 DCL_TYPE (val->type) = PPOINTER;
1348 else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1349 DCL_TYPE (val->type) = IPOINTER;
1350 else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1351 DCL_TYPE (val->type) = EEPPOINTER;
1353 DCL_TYPE (val->type) = POINTER;
1354 val->type->next = arrExpr->left->ftype;
1355 val->etype = getSpec (val->type);
1359 /*-----------------------------------------------------------------*/
1360 /* valForStructElem - returns value with name of struct element */
1361 /*-----------------------------------------------------------------*/
1363 valForStructElem (ast * structT, ast * elemT)
1365 value *val, *lval = NULL;
1369 /* left could be furthur derefed */
1370 if (IS_AST_OP (structT))
1372 if (structT->opval.op == '[')
1373 lval = valForArray (structT);
1374 else if (structT->opval.op == '.')
1375 lval = valForStructElem (structT->left, structT->right);
1376 else if (structT->opval.op == PTR_OP &&
1377 IS_ADDRESS_OF_OP (structT->left))
1378 lval = valForStructElem (structT->left->left,
1384 if (!IS_AST_SYM_VALUE (elemT))
1387 if (!IS_STRUCT (structT->etype))
1390 if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1391 AST_SYMBOL (elemT))) == NULL)
1398 sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1400 sprintf (buffer, "%s", lval->name);
1402 sprintf (val->name, "(%s + %d)", buffer,
1405 val->type = newLink ();
1406 if (SPEC_SCLS (structT->etype) == S_CODE)
1408 DCL_TYPE (val->type) = CPOINTER;
1409 DCL_PTR_CONST (val->type) = port->mem.code_ro;
1411 else if (SPEC_SCLS (structT->etype) == S_XDATA)
1412 DCL_TYPE (val->type) = FPOINTER;
1413 else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1414 DCL_TYPE (val->type) = PPOINTER;
1415 else if (SPEC_SCLS (structT->etype) == S_IDATA)
1416 DCL_TYPE (val->type) = IPOINTER;
1417 else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1418 DCL_TYPE (val->type) = EEPPOINTER;
1420 DCL_TYPE (val->type) = POINTER;
1421 val->type->next = sym->type;
1422 val->etype = getSpec (val->type);
1426 /*-----------------------------------------------------------------*/
1427 /* valForCastAggr - will return value for a cast of an aggregate */
1428 /* plus minus a constant */
1429 /*-----------------------------------------------------------------*/
1431 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1435 if (!IS_AST_SYM_VALUE (aexpr))
1437 if (!IS_AST_LIT_VALUE (cnst))
1442 sprintf (val->name, "(%s %c %d)",
1443 AST_SYMBOL (aexpr)->rname, op,
1444 getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1447 val->etype = getSpec (val->type);
1451 /*-----------------------------------------------------------------*/
1452 /* valForCastAggr - will return value for a cast of an aggregate */
1453 /* with no constant */
1454 /*-----------------------------------------------------------------*/
1456 valForCastArr (ast * aexpr, sym_link * type)
1460 if (!IS_AST_SYM_VALUE (aexpr))
1465 sprintf (val->name, "(%s)",
1466 AST_SYMBOL (aexpr)->rname);
1469 val->etype = getSpec (val->type);