* src/SDCCast.c (decorateType): fix promotion of unary minus
[fw/sdcc] / src / SDCCval.c
1 /*----------------------------------------------------------------------
2     SDCCval.c :- has routine to do all kinds of fun stuff with the
3                 value wrapper & with initialiser lists.
4
5     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
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
10     later version.
11
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.
16
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.
20
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 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include "newalloc.h"
32
33 int cNestLevel;
34
35 /*-----------------------------------------------------------------*/
36 /* newValue - allocates and returns a new value        */
37 /*-----------------------------------------------------------------*/
38 value *
39 newValue ()
40 {
41   value *val;
42
43   val = Safe_alloc (sizeof (value));
44
45   return val;
46 }
47
48 /*-----------------------------------------------------------------*/
49 /* newiList - new initializer list                                 */
50 /*-----------------------------------------------------------------*/
51 initList *
52 newiList (int type, void *ilist)
53 {
54   initList *nilist;
55
56
57   nilist = Safe_alloc (sizeof (initList));
58
59   nilist->type = type;
60   nilist->lineno = mylineno;
61   nilist->filename = currFname;
62
63   switch (type)
64     {
65     case INIT_NODE:
66       nilist->init.node = (struct ast *) ilist;
67       break;
68
69     case INIT_DEEP:
70       nilist->init.deep = (struct initList *) ilist;
71       break;
72     }
73
74   return nilist;
75 }
76
77 /*------------------------------------------------------------------*/
78 /* revinit   - reverses the initial values for a value  chain        */
79 /*------------------------------------------------------------------*/
80 initList *
81 revinit (initList * val)
82 {
83   initList *prev, *curr, *next;
84
85   if (!val)
86     return NULL;
87
88   prev = val;
89   curr = val->next;
90
91   while (curr)
92     {
93       next = curr->next;
94       curr->next = prev;
95       prev = curr;
96       curr = next;
97     }
98   val->next = (void *) NULL;
99   return prev;
100 }
101
102 bool
103 convertIListToConstList(initList *src, literalList **lList)
104 {
105     initList    *iLoop;
106     literalList *head, *last, *newL;
107
108     head = last = NULL;
109
110     if (!src || src->type != INIT_DEEP)
111     {
112         return FALSE;
113     }
114
115     iLoop =  src->init.deep;
116
117     while (iLoop)
118     {
119         if (iLoop->type != INIT_NODE)
120         {
121             return FALSE;
122         }
123
124         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node), RESULT_TYPE_NONE)))
125         {
126             return FALSE;
127         }
128         iLoop = iLoop->next;
129     }
130
131     // We've now established that the initializer list contains only literal values.
132
133     iLoop = src->init.deep;
134     while (iLoop)
135     {
136         double val = AST_LIT_VALUE(iLoop->init.node);
137
138         if (last && last->literalValue == val)
139         {
140             last->count++;
141         }
142         else
143         {
144             newL = Safe_alloc(sizeof(literalList));
145             newL->literalValue = val;
146             newL->count = 1;
147             newL->next = NULL;
148
149             if (last)
150             {
151                 last->next = newL;
152             }
153             else
154             {
155                 head = newL;
156             }
157             last = newL;
158         }
159         iLoop = iLoop->next;
160     }
161
162     if (!head)
163     {
164         return FALSE;
165     }
166
167     *lList = head;
168     return TRUE;
169 }
170
171 literalList *
172 copyLiteralList(literalList *src)
173 {
174     literalList *head, *prev, *newL;
175
176     head = prev = NULL;
177
178     while (src)
179     {
180         newL = Safe_alloc(sizeof(literalList));
181
182         newL->literalValue = src->literalValue;
183         newL->count = src->count;
184         newL->next = NULL;
185
186         if (prev)
187         {
188             prev->next = newL;
189         }
190         else
191         {
192             head = newL;
193         }
194         prev = newL;
195         src = src->next;
196     }
197
198     return head;
199 }
200
201
202
203 /*------------------------------------------------------------------*/
204 /* copyIlist - copy initializer list            */
205 /*------------------------------------------------------------------*/
206 initList *
207 copyIlist (initList * src)
208 {
209   initList *dest = NULL;
210
211   if (!src)
212     return NULL;
213
214   switch (src->type)
215     {
216     case INIT_DEEP:
217       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
218       break;
219     case INIT_NODE:
220       dest = newiList (INIT_NODE, copyAst (src->init.node));
221       break;
222     }
223
224   if (src->next)
225     dest->next = copyIlist (src->next);
226
227   return dest;
228 }
229
230 /*------------------------------------------------------------------*/
231 /* list2int - converts the first element of the list to value       */
232 /*------------------------------------------------------------------*/
233 double
234 list2int (initList * val)
235 {
236   initList *i = val;
237
238   if (i->type == INIT_DEEP)
239     return list2int (val->init.deep);
240
241   return floatFromVal (constExprValue (val->init.node, TRUE));
242 }
243
244 /*------------------------------------------------------------------*/
245 /* list2val - converts the first element of the list to value       */
246 /*------------------------------------------------------------------*/
247 value *
248 list2val (initList * val)
249 {
250   if (!val)
251     return NULL;
252
253   if (val->type == INIT_DEEP)
254     return list2val (val->init.deep);
255
256   return constExprValue (val->init.node, TRUE);
257 }
258
259 /*------------------------------------------------------------------*/
260 /* list2expr - returns the first expression in the initializer list */
261 /*------------------------------------------------------------------*/
262 ast *
263 list2expr (initList * ilist)
264 {
265   if (ilist->type == INIT_DEEP)
266     return list2expr (ilist->init.deep);
267   return ilist->init.node;
268 }
269
270 /*------------------------------------------------------------------*/
271 /* resolveIvalSym - resolve symbols in initial values               */
272 /*------------------------------------------------------------------*/
273 void
274 resolveIvalSym (initList * ilist, sym_link * type)
275 {
276   RESULT_TYPE resultType;
277
278   if (!ilist)
279     return;
280
281   if (ilist->type == INIT_NODE)
282     {
283       if (IS_PTR (type))
284         resultType = RESULT_TYPE_INT;
285       else
286         resultType = getResultTypeFromType (getSpec (type));
287       ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
288                                        resultType);
289     }
290
291   if (ilist->type == INIT_DEEP)
292     resolveIvalSym (ilist->init.deep, type);
293
294   resolveIvalSym (ilist->next, type);
295 }
296
297 /*-----------------------------------------------------------------*/
298 /* symbolVal - creates a value for a symbol              */
299 /*-----------------------------------------------------------------*/
300 value *
301 symbolVal (symbol * sym)
302 {
303   value *val;
304
305   if (!sym)
306     return NULL;
307
308   val = newValue ();
309   val->sym = sym;
310
311   if (sym->type)
312     {
313       val->type = sym->type;
314       val->etype = getSpec (val->type);
315     }
316
317   if (*sym->rname)
318     {
319         SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
320     }
321   else
322     {
323         SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
324     }
325
326   return val;
327 }
328
329 /*--------------------------------------------------------------------*/
330 /* cheapestVal - convert a val to the cheapest as possible value      */
331 /*--------------------------------------------------------------------*/
332 static value *
333 cheapestVal (value *val)
334 {
335   if (IS_FLOAT (val->type) || IS_FIXED (val->type) || IS_CHAR (val->type))
336     return val;
337
338   /* long must not be changed */
339   if (SPEC_LONG(val->type))
340     return val;
341
342   /* only int can be reduced */
343   if (!IS_INT(val->type))
344     return val;
345
346   /* unsigned must not be changed */
347   if (SPEC_USIGN(val->type))
348     return val;
349
350   /* the only possible reduction is from signed int to (un)signed char,
351      because it's automatically promoted back to signed int.
352
353      a reduction from unsigned int to unsigned char is a bug,
354      because an _unsigned_ char is promoted to _signed_ int! */
355   if (SPEC_CVAL(val->type).v_int < -128 ||
356       SPEC_CVAL(val->type).v_int >  255)
357     {
358       /* not in the range of (un)signed char */
359       return val;
360     }
361
362   SPEC_NOUN(val->type) = V_CHAR;
363
364   /* 'unsigned char' promotes to 'signed int', so that we can
365      reduce it the other way */
366   if (SPEC_CVAL(val->type).v_int >= 0)
367     {
368       SPEC_USIGN(val->type) = 1;
369     }
370   return (val);
371 }
372
373 /*-----------------------------------------------------------------*/
374 /* valueFromLit - creates a value from a literal                   */
375 /*-----------------------------------------------------------------*/
376 value *
377 valueFromLit (double lit)
378 {
379   char buffer[50];
380
381   if ((((TYPE_DWORD) lit) - lit) == 0)
382     {
383       SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_DWORD) lit);
384       return constVal (buffer);
385     }
386
387   SNPRINTF (buffer, sizeof(buffer), "%f", lit);
388   return constFloatVal (buffer);
389 }
390
391 /*-----------------------------------------------------------------*/
392 /* constFloatVal - converts a FLOAT constant to value              */
393 /*-----------------------------------------------------------------*/
394 value *
395 constFloatVal (char *s)
396 {
397   value *val = newValue ();
398   double sval;
399
400   if (sscanf (s, "%lf", &sval) != 1)
401     {
402       werror (E_INVALID_FLOAT_CONST, s);
403       return constVal ("0");
404     }
405
406   val->type = val->etype = newLink (SPECIFIER);
407   SPEC_NOUN (val->type) = V_FLOAT;
408   SPEC_SCLS (val->type) = S_LITERAL;
409   SPEC_CVAL (val->type).v_float = sval;
410
411   return val;
412 }
413
414 /*-----------------------------------------------------------------*/
415 /* constFixed16x16Val - converts a FIXED16X16 constant to value    */
416 /*-----------------------------------------------------------------*/
417 value *
418 constFixed16x16Val (char *s)
419 {
420   value *val = newValue ();
421   double sval;
422
423   if (sscanf (s, "%lf", &sval) != 1)
424     {
425       werror (E_INVALID_FLOAT_CONST, s);
426       return constVal ("0");
427     }
428
429   val->type = val->etype = newLink (SPECIFIER);
430   SPEC_NOUN (val->type) = V_FLOAT;
431   SPEC_SCLS (val->type) = S_LITERAL;
432   SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
433
434   return val;
435 }
436
437 /*-----------------------------------------------------------------*/
438 /* constVal - converts an INTEGER constant into a cheapest value   */
439 /*-----------------------------------------------------------------*/
440 value *constVal (char *s)
441 {
442   value *val;
443   short hex = 0, octal = 0;
444   double dval;
445
446   val = newValue ();            /* alloc space for value   */
447
448   val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
449   SPEC_SCLS (val->type) = S_LITERAL;
450   // let's start with a signed char
451   SPEC_NOUN (val->type) = V_CHAR;
452   SPEC_USIGN (val->type) = 0;
453
454   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
455
456   /* set the octal flag   */
457   if (!hex && *s == '0' && *(s + 1))
458     octal = 1;
459
460   errno = 0;
461   if (hex || octal) {
462     unsigned long sval;
463     sval = strtoul (s, NULL, 0);
464     dval=sval;
465     if (errno) {
466       dval = 4294967295.0;
467       werror (W_INVALID_INT_CONST, s, dval);
468     }
469   } else {
470     sscanf (s, "%lf", &dval);
471   }
472
473   /* Setup the flags first */
474   /* set the unsigned flag if 'uU' is found */
475   if (strchr (s, 'u') || strchr (s, 'U')) {
476     SPEC_USIGN (val->type) = 1;
477   }
478
479   /* set the b_long flag if 'lL' is found */
480   if (strchr (s, 'l') || strchr (s, 'L')) {
481     SPEC_NOUN (val->type) = V_INT;
482     SPEC_LONG (val->type) = 1;
483   } else {
484     if (dval<0) { // "-28u" will still be signed and negative
485       if (dval<-128) { // check if we have to promote to int
486         SPEC_NOUN (val->type) = V_INT;
487       }
488       if (dval<-32768) { // check if we have to promote to long int
489         SPEC_LONG (val->type) = 1;
490       }
491     } else { // >=0
492       if (dval>0xff ||  /* check if we have to promote to int */
493           SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
494                                      char. After an integral promotion it will
495                                      be a signed int; this certainly isn't what
496                                      the programer wants */
497         SPEC_NOUN (val->type) = V_INT;
498       }
499       else { /* store char's always as unsigned; this helps other optimizations */
500         SPEC_USIGN (val->type) = 1;
501       }
502       if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
503         SPEC_LONG (val->type) = 1;
504       }
505       else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
506         if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
507             dval<=0xffff) {
508           SPEC_USIGN (val->type) = 1;
509         } else {
510           SPEC_LONG (val->type) = 1;
511           if (dval>0x7fffffff) {
512             SPEC_USIGN (val->type) = 1;
513           }
514         }
515       }
516     }
517   }
518
519   /* check for out of range */
520   if (dval<-2147483648.0) {
521     dval = -2147483648.0;
522     werror (W_INVALID_INT_CONST, s, dval);
523   }
524   if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
525     dval = 2147483647.0;
526     werror (W_INVALID_INT_CONST, s, dval);
527   }
528   if (dval>4294967295.0) {
529     dval = 4294967295.0;
530     werror (W_INVALID_INT_CONST, s, dval);
531   }
532
533   if (SPEC_LONG (val->type))
534     {
535       if (SPEC_USIGN (val->type))
536         {
537           SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD)dval;
538         }
539       else
540         {
541           SPEC_CVAL (val->type).v_long = (TYPE_DWORD)dval;
542         }
543     }
544   else
545     {
546       if (SPEC_USIGN (val->type))
547         {
548           SPEC_CVAL (val->type).v_uint = (TYPE_UWORD)dval;
549         }
550       else
551         {
552           SPEC_CVAL (val->type).v_int = (TYPE_WORD)dval;
553         }
554     }
555
556   return val;
557 }
558
559 /*! /fn char hexEscape(char **src)
560
561     /param src Pointer to 'x' from start of hex character value
562 */
563
564 unsigned char hexEscape(char **src)
565 {
566   char *s ;
567   unsigned long value ;
568
569   (*src)++ ;    /* Skip over the 'x' */
570   s = *src ;    /* Save for error detection */
571
572   value = strtol (*src, src, 16);
573
574   if (s == *src) {
575       // no valid hex found
576       werror(E_INVALID_HEX);
577   } else {
578     if (value > 255) {
579       werror(W_ESC_SEQ_OOR_FOR_CHAR);
580     }
581   }
582   return (char) value;
583 }
584
585 /*------------------------------------------------------------------*/
586 /* octalEscape - process an octal constant of max three digits      */
587 /* return the octal value, throw a warning for illegal octal        */
588 /* adjust src to point at the last proccesed char                   */
589 /*------------------------------------------------------------------*/
590
591 unsigned char octalEscape (char **str) {
592   int digits;
593   unsigned value=0;
594
595   for (digits=0; digits<3; digits++) {
596     if (**str>='0' && **str<='7') {
597       value = value*8 + (**str-'0');
598       (*str)++;
599     } else {
600       break;
601     }
602   }
603   if (digits) {
604     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
605       werror (W_ESC_SEQ_OOR_FOR_CHAR);
606     }
607   }
608   return value;
609 }
610
611 /*!
612   /fn int copyStr (char *dest, char *src)
613
614   Copies a source string to a dest buffer interpreting escape sequences
615   and special characters
616
617   /param dest Buffer to receive the resultant string
618   /param src  Buffer containing the source string with escape sequecnes
619   /return Number of characters in output string
620
621 */
622
623 int
624 copyStr (char *dest, char *src)
625
626 {
627   char *OriginalDest = dest ;
628
629   while (*src)
630     {
631       if (*src == '\"')
632         src++;
633       else if (*src == '\\')
634         {
635           src++;
636           switch (*src)
637             {
638             case 'n':
639               *dest++ = '\n';
640               break;
641             case 't':
642               *dest++ = '\t';
643               break;
644             case 'v':
645               *dest++ = '\v';
646               break;
647             case 'b':
648               *dest++ = '\b';
649               break;
650             case 'r':
651               *dest++ = '\r';
652               break;
653             case 'f':
654               *dest++ = '\f';
655               break;
656             case 'a':
657               *dest++ = '\a';
658               break;
659
660             case '0':
661             case '1':
662             case '2':
663             case '3':
664             case '4':
665             case '5':
666             case '6':
667             case '7':
668               *dest++ = octalEscape(&src);
669               src-- ;
670               break;
671
672             case 'x':
673               *dest++ = hexEscape(&src) ;
674               src-- ;
675               break ;
676
677             case '\\':
678               *dest++ = '\\';
679               break;
680             case '\?':
681               *dest++ = '\?';
682               break;
683             case '\'':
684               *dest++ = '\'';
685               break;
686             case '\"':
687               *dest++ = '\"';
688               break;
689             default:
690               *dest++ = *src;
691             }
692           src++;
693         }
694       else
695         *dest++ = *src++;
696     }
697
698   *dest++ = '\0';
699
700   return dest - OriginalDest ;
701 }
702
703 /*------------------------------------------------------------------*/
704 /* strVal - converts a string constant to a value       */
705 /*------------------------------------------------------------------*/
706 value *
707 strVal (char *s)
708 {
709   value *val;
710
711   val = newValue ();            /* get a new one */
712
713   /* get a declarator */
714   val->type = newLink (DECLARATOR);
715   DCL_TYPE (val->type) = ARRAY;
716   val->type->next = val->etype = newLink (SPECIFIER);
717   SPEC_NOUN (val->etype) = V_CHAR;
718   SPEC_SCLS (val->etype) = S_LITERAL;
719
720   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
721   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
722
723   return val;
724 }
725
726
727 /*------------------------------------------------------------------*/
728 /* reverseValWithType - reverses value chain with type & etype      */
729 /*------------------------------------------------------------------*/
730 value *
731 reverseValWithType (value * val)
732 {
733   sym_link *type;
734   sym_link *etype;
735
736   if (!val)
737     return NULL;
738
739   /* save the type * etype chains */
740   type = val->type;
741   etype = val->etype;
742
743   /* set the current one 2b null */
744   val->type = val->etype = NULL;
745   val = reverseVal (val);
746
747   /* restore type & etype */
748   val->type = type;
749   val->etype = etype;
750
751   return val;
752 }
753
754 /*------------------------------------------------------------------*/
755 /* reverseVal - reverses the values for a value  chain        */
756 /*------------------------------------------------------------------*/
757 value *
758 reverseVal (value * val)
759 {
760   value *prev, *curr, *next;
761
762   if (!val)
763     return NULL;
764
765   prev = val;
766   curr = val->next;
767
768   while (curr)
769     {
770       next = curr->next;
771       curr->next = prev;
772       prev = curr;
773       curr = next;
774     }
775   val->next = (void *) NULL;
776   return prev;
777 }
778
779 /*------------------------------------------------------------------*/
780 /* copyValueChain - will copy a chain of values                     */
781 /*------------------------------------------------------------------*/
782 value *
783 copyValueChain (value * src)
784 {
785   value *dest;
786
787   if (!src)
788     return NULL;
789
790   dest = copyValue (src);
791   dest->next = copyValueChain (src->next);
792
793   return dest;
794 }
795
796 /*------------------------------------------------------------------*/
797 /* copyValue - copies contents of a value to a fresh one            */
798 /*------------------------------------------------------------------*/
799 value *
800 copyValue (value * src)
801 {
802   value *dest;
803
804   dest = newValue ();
805   dest->sym = copySymbol (src->sym);
806   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
807   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
808   dest->etype = (src->type ? getSpec (dest->type) : NULL);
809
810   return dest;
811 }
812
813 /*------------------------------------------------------------------*/
814 /* charVal - converts a character constant to a value       */
815 /*------------------------------------------------------------------*/
816 value *
817 charVal (char *s)
818 {
819   value *val;
820
821   val = newValue ();
822
823   val->type = val->etype = newLink (SPECIFIER);
824   SPEC_NOUN (val->type) = V_CHAR;
825   SPEC_USIGN(val->type) = 1;
826   SPEC_SCLS (val->type) = S_LITERAL;
827
828   s++;                          /* get rid of quotation */
829   /* if \ then special processing */
830   if (*s == '\\')
831     {
832       s++;                      /* go beyond the backslash  */
833       switch (*s)
834         {
835         case 'n':
836           SPEC_CVAL (val->type).v_uint = '\n';
837           break;
838         case 't':
839           SPEC_CVAL (val->type).v_uint = '\t';
840           break;
841         case 'v':
842           SPEC_CVAL (val->type).v_uint = '\v';
843           break;
844         case 'b':
845           SPEC_CVAL (val->type).v_uint = '\b';
846           break;
847         case 'r':
848           SPEC_CVAL (val->type).v_uint = '\r';
849           break;
850         case 'f':
851           SPEC_CVAL (val->type).v_uint = '\f';
852           break;
853         case 'a':
854           SPEC_CVAL (val->type).v_uint = '\a';
855           break;
856         case '\\':
857           SPEC_CVAL (val->type).v_uint = '\\';
858           break;
859         case '\?':
860           SPEC_CVAL (val->type).v_uint = '\?';
861           break;
862         case '\'':
863           SPEC_CVAL (val->type).v_uint = '\'';
864           break;
865         case '\"':
866           SPEC_CVAL (val->type).v_uint = '\"';
867           break;
868
869         case '0' :
870         case '1' :
871         case '2' :
872         case '3' :
873         case '4' :
874         case '5' :
875         case '6' :
876         case '7' :
877           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
878           break;
879
880         case 'x':
881           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
882           break;
883
884         default:
885           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
886           break;
887         }
888     }
889   else                          /* not a backslash */
890     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
891
892   return val;
893 }
894
895 /*------------------------------------------------------------------*/
896 /* valFromType - creates a value from type given                    */
897 /*------------------------------------------------------------------*/
898 value *
899 valFromType (sym_link * type)
900 {
901   value *val = newValue ();
902   val->type = copyLinkChain (type);
903   val->etype = getSpec (val->type);
904   return val;
905 }
906
907 /*------------------------------------------------------------------*/
908 /* floatFromVal - value to double float conversion                  */
909 /*------------------------------------------------------------------*/
910 double
911 floatFromVal (value * val)
912 {
913   if (!val)
914     return 0;
915
916   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
917     {
918       werror (E_CONST_EXPECTED, val->name);
919       return 0;
920     }
921
922   /* if it is not a specifier then we can assume that */
923   /* it will be an unsigned long                      */
924   if (!IS_SPEC (val->type))
925     return (double) SPEC_CVAL (val->etype).v_ulong;
926
927   if (SPEC_NOUN (val->etype) == V_FLOAT)
928     return (double) SPEC_CVAL (val->etype).v_float;
929
930   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
931     return (double) doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
932
933   if (SPEC_LONG (val->etype))
934     {
935       if (SPEC_USIGN (val->etype))
936         return (double) SPEC_CVAL (val->etype).v_ulong;
937       else
938         return (double) SPEC_CVAL (val->etype).v_long;
939     }
940
941   if (SPEC_NOUN (val->etype) == V_INT) {
942     if (SPEC_USIGN (val->etype))
943       return (double) SPEC_CVAL (val->etype).v_uint;
944     else
945       return (double) SPEC_CVAL (val->etype).v_int;
946   }
947
948   if (SPEC_NOUN (val->etype) == V_CHAR) {
949     if (SPEC_USIGN (val->etype))
950       return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
951     else
952       return (double) (signed char)SPEC_CVAL (val->etype).v_int;
953   }
954
955   if (IS_BITVAR(val->etype)) {
956     return (double) SPEC_CVAL (val->etype).v_uint;
957   }
958
959   if (SPEC_NOUN (val->etype) == V_VOID) {
960     return (double) SPEC_CVAL (val->etype).v_ulong;
961   }
962
963   // we are lost !
964   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
965           "floatFromVal: unknown value");
966   return 0;
967 }
968
969 /*------------------------------------------------------------------*/
970 /* valUnaryPM - does the unary +/- operation on a constant          */
971 /*------------------------------------------------------------------*/
972 value *
973 valUnaryPM (value * val)
974 {
975   /* depending on type */
976   if (SPEC_NOUN (val->etype) == V_FLOAT)
977     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
978   else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
979     SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
980   else
981     {
982       if (SPEC_LONG (val->etype))
983         {
984           if (SPEC_USIGN (val->etype))
985             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
986           else
987             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
988         }
989       else
990         {
991           if (SPEC_USIGN (val->etype))
992             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
993           else
994             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
995
996           if (SPEC_NOUN(val->etype) == V_CHAR)
997             {
998               /* promote to 'signed int', cheapestVal() might reduce it again */
999               SPEC_USIGN(val->etype) = 0;
1000               SPEC_NOUN(val->etype) = V_INT;
1001             }
1002           return cheapestVal (val);
1003         }
1004     }
1005   return val;
1006 }
1007
1008 /*------------------------------------------------------------------*/
1009 /* valueComplement - complements a constant                         */
1010 /*------------------------------------------------------------------*/
1011 value *
1012 valComplement (value * val)
1013 {
1014   /* depending on type */
1015   if (SPEC_LONG (val->etype))
1016     {
1017       if (SPEC_USIGN (val->etype))
1018         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1019       else
1020         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1021     }
1022   else
1023     {
1024       if (SPEC_USIGN (val->etype))
1025         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1026       else
1027         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1028
1029       if (SPEC_NOUN(val->etype) == V_CHAR)
1030         {
1031           /* promote to 'signed int', cheapestVal() might reduce it again */
1032           SPEC_USIGN(val->etype) = 0;
1033           SPEC_NOUN(val->etype) = V_INT;
1034         }
1035       return cheapestVal (val);
1036     }
1037   return val;
1038 }
1039
1040 /*------------------------------------------------------------------*/
1041 /* valueNot - complements a constant                                */
1042 /*------------------------------------------------------------------*/
1043 value *
1044 valNot (value * val)
1045 {
1046   /* depending on type */
1047   if (SPEC_LONG (val->etype))
1048     {
1049       if (SPEC_USIGN (val->etype))
1050         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
1051       else
1052         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
1053     }
1054   else
1055     {
1056       if (SPEC_USIGN (val->etype))
1057         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
1058       else
1059         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1060
1061       if (SPEC_NOUN(val->etype) == V_CHAR)
1062         {
1063           /* promote to 'signed int', cheapestVal() might reduce it again */
1064           SPEC_USIGN(val->etype) = 0;
1065           SPEC_NOUN(val->etype) = V_INT;
1066         }
1067       return cheapestVal (val);
1068     }
1069   return val;
1070 }
1071
1072 /*------------------------------------------------------------------*/
1073 /* valMult - multiply constants                                     */
1074 /*------------------------------------------------------------------*/
1075 value *
1076 valMult (value * lval, value * rval)
1077 {
1078   value *val;
1079
1080   /* create a new value */
1081   val = newValue ();
1082   val->type = val->etype = computeType (lval->etype,
1083                                         rval->etype,
1084                                         RESULT_TYPE_INT,
1085                                         '*');
1086   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1087
1088   if (IS_FLOAT (val->type))
1089     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1090   else
1091   if (IS_FIXED16X16 (val->type))
1092     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1093       /* signed and unsigned mul are the same, as long as the precision of the
1094          result isn't bigger than the precision of the operands. */
1095   else if (SPEC_LONG (val->type))
1096     SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) *
1097                                     (TYPE_UDWORD) floatFromVal (rval);
1098   else if (SPEC_USIGN (val->type)) /* unsigned int */
1099     {
1100       TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) *
1101                        (TYPE_UWORD) floatFromVal (rval);
1102
1103       SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) ul;
1104       if (ul != (TYPE_UWORD) ul)
1105         werror (W_INT_OVL);
1106     }
1107   else /* signed int */
1108     {
1109       TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) *
1110                      (TYPE_WORD) floatFromVal (rval);
1111
1112       SPEC_CVAL (val->type).v_int = (TYPE_WORD) l;
1113       if (l != (TYPE_WORD) l)
1114         werror (W_INT_OVL);
1115     }
1116   return cheapestVal (val);
1117 }
1118
1119 /*------------------------------------------------------------------*/
1120 /* valDiv  - Divide   constants                                     */
1121 /*------------------------------------------------------------------*/
1122 value *
1123 valDiv (value * lval, value * rval)
1124 {
1125   value *val;
1126
1127   if (floatFromVal (rval) == 0)
1128     {
1129       werror (E_DIVIDE_BY_ZERO);
1130       return rval;
1131     }
1132
1133   /* create a new value */
1134   val = newValue ();
1135   val->type = val->etype = computeType (lval->etype,
1136                                         rval->etype,
1137                                         RESULT_TYPE_INT,
1138                                         '/');
1139   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1140
1141   if (IS_FLOAT (val->type))
1142     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1143   else
1144   if (IS_FIXED16X16 (val->type))
1145     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1146   else if (SPEC_LONG (val->type))
1147     {
1148       if (SPEC_USIGN (val->type))
1149         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) /
1150           (TYPE_UDWORD) floatFromVal (rval);
1151       else
1152         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) /
1153           (TYPE_DWORD) floatFromVal (rval);
1154     }
1155   else
1156     {
1157       if (SPEC_USIGN (val->type))
1158         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) /
1159           (TYPE_UWORD) floatFromVal (rval);
1160       else
1161         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) /
1162           (TYPE_WORD) floatFromVal (rval);
1163     }
1164   return cheapestVal (val);
1165 }
1166
1167 /*------------------------------------------------------------------*/
1168 /* valMod  - Modulus  constants                                     */
1169 /*------------------------------------------------------------------*/
1170 value *
1171 valMod (value * lval, value * rval)
1172 {
1173   value *val;
1174
1175   /* create a new value */
1176   val = newValue();
1177   val->type = val->etype = computeType (lval->etype,
1178                                         rval->etype,
1179                                         RESULT_TYPE_INT,
1180                                         '%');
1181   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1182
1183   if (SPEC_LONG (val->type))
1184     {
1185       if (SPEC_USIGN (val->type))
1186         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) %
1187           (TYPE_UDWORD) floatFromVal (rval);
1188       else
1189         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) %
1190           (TYPE_DWORD) floatFromVal (rval);
1191     }
1192   else
1193     {
1194       if (SPEC_USIGN (val->type))
1195         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) %
1196           (TYPE_UWORD) floatFromVal (rval);
1197       else
1198         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) %
1199           (TYPE_WORD) floatFromVal (rval);
1200     }
1201   return cheapestVal (val);
1202 }
1203
1204 /*------------------------------------------------------------------*/
1205 /* valPlus - Addition constants                                     */
1206 /*------------------------------------------------------------------*/
1207 value *
1208 valPlus (value * lval, value * rval)
1209 {
1210   value *val;
1211
1212   /* create a new value */
1213   val = newValue();
1214   val->type = val->etype = computeType (lval->etype,
1215                                         rval->etype,
1216                                         RESULT_TYPE_INT,
1217                                         '+');
1218   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1219
1220   if (IS_FLOAT (val->type))
1221     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1222   else
1223   if (IS_FIXED16X16 (val->type))
1224     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1225   else  if (SPEC_LONG (val->type))
1226     {
1227       if (SPEC_USIGN (val->type))
1228         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) +
1229          (TYPE_UDWORD) floatFromVal (rval);
1230       else
1231         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) +
1232           (TYPE_DWORD) floatFromVal (rval);
1233     }
1234   else
1235     {
1236       if (SPEC_USIGN (val->type))
1237         SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) +
1238           (TYPE_UWORD) floatFromVal (rval);
1239       else
1240         SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) +
1241           (TYPE_WORD) floatFromVal (rval);
1242     }
1243   return cheapestVal (val);
1244 }
1245
1246 /*------------------------------------------------------------------*/
1247 /* valMinus - Addition constants                                    */
1248 /*------------------------------------------------------------------*/
1249 value *
1250 valMinus (value * lval, value * rval)
1251 {
1252   value *val;
1253
1254   /* create a new value */
1255   val = newValue();
1256   val->type = val->etype = computeType (lval->etype,
1257                                         rval->etype,
1258                                         RESULT_TYPE_INT,
1259                                         '-');
1260   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1261
1262   if (IS_FLOAT (val->type))
1263     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1264   else
1265   if (IS_FIXED16X16 (val->type))
1266     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1267   else  if (SPEC_LONG (val->type))
1268     {
1269       if (SPEC_USIGN (val->type))
1270         SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) -
1271           (TYPE_UDWORD) floatFromVal (rval);
1272       else
1273         SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) -
1274           (TYPE_DWORD) floatFromVal (rval);
1275     }
1276   else
1277    {
1278      if (SPEC_USIGN (val->type))
1279        SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) -
1280          (TYPE_UWORD) floatFromVal (rval);
1281      else
1282        SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) -
1283          (TYPE_WORD) floatFromVal (rval);
1284     }
1285   return cheapestVal (val);
1286 }
1287
1288 /*------------------------------------------------------------------*/
1289 /* valShift - Shift left or right                                   */
1290 /*------------------------------------------------------------------*/
1291 value *
1292 valShift (value * lval, value * rval, int lr)
1293 {
1294   value *val;
1295
1296   /* create a new value */
1297   val = newValue();
1298   val->type = val->etype = computeType (lval->etype,
1299                                         NULL,
1300                                         RESULT_TYPE_INT,
1301                                         'S');
1302   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1303
1304   if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
1305        /* left shift */
1306       (lr ||
1307         /* right shift and unsigned */
1308        (!lr && SPEC_USIGN (rval->type))))
1309     {
1310       werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1311     }
1312
1313   if (SPEC_LONG (val->type))
1314     {
1315       if (SPEC_USIGN (val->type))
1316         {
1317           SPEC_CVAL (val->type).v_ulong = lr ?
1318             (TYPE_UDWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1319             (TYPE_UDWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1320         }
1321       else
1322         {
1323           SPEC_CVAL (val->type).v_long = lr ?
1324             (TYPE_DWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1325             (TYPE_DWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1326         }
1327     }
1328   else
1329     {
1330       if (SPEC_USIGN (val->type))
1331         {
1332           SPEC_CVAL (val->type).v_uint = lr ?
1333             (TYPE_UWORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1334             (TYPE_UWORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1335         }
1336       else
1337         {
1338           SPEC_CVAL (val->type).v_int = lr ?
1339             (TYPE_WORD) floatFromVal (lval) << (TYPE_UDWORD) floatFromVal (rval) : \
1340             (TYPE_WORD) floatFromVal (lval) >> (TYPE_UDWORD) floatFromVal (rval);
1341         }
1342     }
1343   return cheapestVal (val);
1344 }
1345
1346 /*------------------------------------------------------------------*/
1347 /* valCompare- Compares two literal                                 */
1348 /*------------------------------------------------------------------*/
1349 value *
1350 valCompare (value * lval, value * rval, int ctype)
1351 {
1352   value *val;
1353
1354   /* create a new value */
1355   val = newValue ();
1356   val->type = val->etype = newCharLink ();
1357   val->type->class = SPECIFIER;
1358   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1359   SPEC_USIGN (val->type) = 1;
1360   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1361
1362   switch (ctype)
1363     {
1364     case '<':
1365       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1366       break;
1367
1368     case '>':
1369       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1370       break;
1371
1372     case LE_OP:
1373       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1374       break;
1375
1376     case GE_OP:
1377       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1378       break;
1379
1380     case EQ_OP:
1381       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1382           SPEC_NOUN(rval->type) == V_FLOAT)
1383         {
1384           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1385         }
1386       else
1387       if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1388           SPEC_NOUN(rval->type) == V_FIXED16X16)
1389         {
1390           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1391         }
1392       else
1393         {
1394           /* integrals: ignore signedness */
1395           TYPE_UDWORD l, r;
1396
1397           l = (TYPE_UDWORD) floatFromVal (lval);
1398           r = (TYPE_UDWORD) floatFromVal (rval);
1399           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1400              neccessary to strip them to 16 bit.
1401              Literals are reduced to their cheapest type, therefore left and
1402              right might have different types. It's neccessary to find a
1403              common type: int (used for char too) or long */
1404           if (!IS_LONG (lval->etype) &&
1405               !IS_LONG (rval->etype))
1406             {
1407               r = (TYPE_UWORD) r;
1408               l = (TYPE_UWORD) l;
1409             }
1410           SPEC_CVAL (val->type).v_int = l == r;
1411         }
1412       break;
1413     case NE_OP:
1414       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1415           SPEC_NOUN(rval->type) == V_FLOAT)
1416         {
1417           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1418         }
1419       else
1420       if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1421           SPEC_NOUN(rval->type) == V_FIXED16X16)
1422         {
1423           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1424         }
1425       else
1426         {
1427           /* integrals: ignore signedness */
1428           TYPE_UDWORD l, r;
1429
1430           l = (TYPE_UDWORD) floatFromVal (lval);
1431           r = (TYPE_UDWORD) floatFromVal (rval);
1432           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1433              neccessary to strip them to 16 bit.
1434              Literals are reduced to their cheapest type, therefore left and
1435              right might have different types. It's neccessary to find a
1436              common type: int (used for char too) or long */
1437           if (!IS_LONG (lval->etype) &&
1438               !IS_LONG (rval->etype))
1439             {
1440               r = (TYPE_UWORD) r;
1441               l = (TYPE_UWORD) l;
1442             }
1443           SPEC_CVAL (val->type).v_int = l != r;
1444         }
1445       break;
1446
1447     }
1448
1449   return val;
1450 }
1451
1452 /*------------------------------------------------------------------*/
1453 /* valBitwise - Bitwise operation                                   */
1454 /*------------------------------------------------------------------*/
1455 value *
1456 valBitwise (value * lval, value * rval, int op)
1457 {
1458   value *val;
1459
1460   /* create a new value */
1461   val = newValue ();
1462   val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1463   val->etype = getSpec (val->type);
1464   SPEC_SCLS (val->etype) = S_LITERAL;
1465
1466   switch (op)
1467     {
1468     case '&':
1469       if (SPEC_LONG (val->type))
1470         {
1471           if (SPEC_USIGN (val->type))
1472             SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) &
1473               (TYPE_UDWORD) floatFromVal (rval);
1474           else
1475             SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) &
1476               (TYPE_DWORD) floatFromVal (rval);
1477         }
1478       else
1479         {
1480           if (SPEC_USIGN (val->type))
1481             SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) &
1482               (TYPE_UWORD) floatFromVal (rval);
1483           else
1484             SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) & (TYPE_WORD) floatFromVal (rval);
1485         }
1486       break;
1487
1488     case '|':
1489       if (SPEC_LONG (val->type))
1490         {
1491           if (SPEC_USIGN (val->type))
1492             SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) |
1493               (TYPE_UDWORD) floatFromVal (rval);
1494           else
1495             SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) |
1496               (TYPE_DWORD) floatFromVal (rval);
1497         }
1498       else
1499         {
1500           if (SPEC_USIGN (val->type))
1501             SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) |
1502               (TYPE_UWORD) floatFromVal (rval);
1503           else
1504             SPEC_CVAL (val->type).v_int =
1505               (TYPE_WORD) floatFromVal (lval) | (TYPE_WORD) floatFromVal (rval);
1506         }
1507
1508       break;
1509
1510     case '^':
1511       if (SPEC_LONG (val->type))
1512         {
1513           if (SPEC_USIGN (val->type))
1514             SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) ^
1515               (TYPE_UDWORD) floatFromVal (rval);
1516           else
1517             SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) ^
1518               (TYPE_DWORD) floatFromVal (rval);
1519         }
1520       else
1521         {
1522           if (SPEC_USIGN (val->type))
1523             SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) ^
1524               (TYPE_UWORD) floatFromVal (rval);
1525           else
1526             SPEC_CVAL (val->type).v_int =
1527               (TYPE_WORD) floatFromVal (lval) ^ (TYPE_WORD) floatFromVal (rval);
1528         }
1529       break;
1530     }
1531
1532   return cheapestVal(val);
1533 }
1534
1535 /*------------------------------------------------------------------*/
1536 /* valAndOr   - Generates code for and / or operation               */
1537 /*------------------------------------------------------------------*/
1538 value *
1539 valLogicAndOr (value * lval, value * rval, int op)
1540 {
1541   value *val;
1542
1543   /* create a new value */
1544   val = newValue ();
1545   val->type = val->etype = newCharLink ();
1546   val->type->class = SPECIFIER;
1547   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1548   SPEC_USIGN (val->type) = 1;
1549
1550   switch (op)
1551     {
1552     case AND_OP:
1553       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1554       break;
1555
1556     case OR_OP:
1557       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1558       break;
1559     }
1560
1561
1562   return val;
1563 }
1564
1565 /*------------------------------------------------------------------*/
1566 /* valCastLiteral - casts a literal value to another type           */
1567 /*------------------------------------------------------------------*/
1568 value *
1569 valCastLiteral (sym_link * dtype, double fval)
1570 {
1571   value *val;
1572   TYPE_UDWORD l = (TYPE_UDWORD)fval;
1573
1574   if (!dtype)
1575     return NULL;
1576
1577   val = newValue ();
1578   if (dtype)
1579     val->etype = getSpec (val->type = copyLinkChain (dtype));
1580   else
1581     {
1582       val->etype = val->type = newLink (SPECIFIER);
1583       SPEC_NOUN (val->etype) = V_VOID;
1584     }
1585   SPEC_SCLS (val->etype) = S_LITERAL;
1586
1587   /* if it is not a specifier then we can assume that */
1588   /* it will be an unsigned long                      */
1589   if (!IS_SPEC (val->type)) {
1590       SPEC_CVAL (val->etype).v_ulong = l;
1591       return val;
1592   }
1593
1594   if (SPEC_NOUN (val->etype) == V_FLOAT)
1595       SPEC_CVAL (val->etype).v_float = fval;
1596   else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1597       SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1598   else if (SPEC_NOUN (val->etype) == V_BIT ||
1599            SPEC_NOUN (val->etype) == V_SBIT)
1600     SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1601   else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1602     SPEC_CVAL (val->etype).v_uint = l &
1603                                     (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1604   else if (SPEC_NOUN (val->etype) == V_CHAR) {
1605       if (SPEC_USIGN (val->etype))
1606           SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
1607       else
1608           SPEC_CVAL (val->etype).v_int = (TYPE_BYTE) l;
1609   } else {
1610       if (SPEC_LONG (val->etype)) {
1611           if (SPEC_USIGN (val->etype))
1612               SPEC_CVAL (val->etype).v_ulong = (TYPE_UDWORD) l;
1613           else
1614               SPEC_CVAL (val->etype).v_long = (TYPE_DWORD) l;
1615       } else {
1616           if (SPEC_USIGN (val->etype))
1617               SPEC_CVAL (val->etype).v_uint = (TYPE_UWORD)l;
1618           else
1619               SPEC_CVAL (val->etype).v_int = (TYPE_WORD)l;
1620       }
1621   }
1622   return val;
1623 }
1624
1625 /*------------------------------------------------------------------*/
1626 /* getNelements - determines # of elements from init list           */
1627 /*------------------------------------------------------------------*/
1628 int
1629 getNelements (sym_link * type, initList * ilist)
1630 {
1631   int i;
1632
1633   if (!ilist)
1634     return 0;
1635
1636   if (ilist->type == INIT_DEEP)
1637     ilist = ilist->init.deep;
1638
1639   /* if type is a character array and there is only one
1640      (string) initialiser then get the length of the string */
1641   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
1642     {
1643       ast *iast = ilist->init.node;
1644       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1645       if (!v)
1646         {
1647           werror (E_CONST_EXPECTED);
1648           return 0;
1649         }
1650
1651       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1652         // yep, it's a string
1653         {
1654           return DCL_ELEM (v->type);
1655         }
1656     }
1657
1658   i = 0;
1659   while (ilist)
1660     {
1661       i++;
1662       ilist = ilist->next;
1663     }
1664   return i;
1665 }
1666
1667 /*-----------------------------------------------------------------*/
1668 /* valForArray - returns a value with name of array index          */
1669 /*-----------------------------------------------------------------*/
1670 value *
1671 valForArray (ast * arrExpr)
1672 {
1673   value *val, *lval = NULL;
1674   char buffer[128];
1675   int size = getSize (arrExpr->left->ftype->next);
1676   /* if the right or left is an array
1677      resolve it first */
1678   if (IS_AST_OP (arrExpr->left))
1679     {
1680       if (arrExpr->left->opval.op == '[')
1681         lval = valForArray (arrExpr->left);
1682       else if (arrExpr->left->opval.op == '.')
1683         lval = valForStructElem (arrExpr->left->left,
1684                                  arrExpr->left->right);
1685       else if (arrExpr->left->opval.op == PTR_OP &&
1686                IS_ADDRESS_OF_OP (arrExpr->left->left))
1687         lval = valForStructElem (arrExpr->left->left->left,
1688                                  arrExpr->left->right);
1689       else
1690         return NULL;
1691
1692     }
1693   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1694     return NULL;
1695
1696   if (!IS_AST_LIT_VALUE (arrExpr->right))
1697     return NULL;
1698
1699   val = newValue ();
1700   if (!lval)
1701     {
1702         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
1703     }
1704   else
1705     {
1706         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1707     }
1708
1709   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1710            (int) AST_LIT_VALUE (arrExpr->right) * size);
1711
1712   val->type = newLink (DECLARATOR);
1713   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1714     DCL_TYPE (val->type) = CPOINTER;
1715   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1716     DCL_TYPE (val->type) = FPOINTER;
1717   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1718     DCL_TYPE (val->type) = PPOINTER;
1719   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1720     DCL_TYPE (val->type) = IPOINTER;
1721   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1722     DCL_TYPE (val->type) = EEPPOINTER;
1723   else
1724     DCL_TYPE (val->type) = POINTER;
1725   val->type->next = arrExpr->left->ftype->next;
1726   val->etype = getSpec (val->type);
1727   return val;
1728 }
1729
1730 /*-----------------------------------------------------------------*/
1731 /* valForStructElem - returns value with name of struct element    */
1732 /*-----------------------------------------------------------------*/
1733 value *
1734 valForStructElem (ast * structT, ast * elemT)
1735 {
1736   value *val, *lval = NULL;
1737   char buffer[128];
1738   symbol *sym;
1739
1740   /* left could be furthur derefed */
1741   if (IS_AST_OP (structT))
1742     {
1743       if (structT->opval.op == '[')
1744         lval = valForArray (structT);
1745       else if (structT->opval.op == '.')
1746         lval = valForStructElem (structT->left, structT->right);
1747       else if (structT->opval.op == PTR_OP &&
1748                IS_ADDRESS_OF_OP (structT->left))
1749         lval = valForStructElem (structT->left->left,
1750                                  structT->right);
1751       else
1752         return NULL;
1753     }
1754
1755   if (!IS_AST_SYM_VALUE (elemT))
1756     return NULL;
1757
1758   if (!IS_STRUCT (structT->etype))
1759     return NULL;
1760
1761   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1762                                AST_SYMBOL (elemT))) == NULL)
1763     {
1764       return NULL;
1765     }
1766
1767   val = newValue ();
1768   if (!lval)
1769     {
1770         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
1771     }
1772   else
1773     {
1774         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
1775     }
1776
1777   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
1778            (int) sym->offset);
1779
1780   val->type = newLink (DECLARATOR);
1781   if (SPEC_SCLS (structT->etype) == S_CODE)
1782     DCL_TYPE (val->type) = CPOINTER;
1783   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1784     DCL_TYPE (val->type) = FPOINTER;
1785   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1786     DCL_TYPE (val->type) = PPOINTER;
1787   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1788     DCL_TYPE (val->type) = IPOINTER;
1789   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1790     DCL_TYPE (val->type) = EEPPOINTER;
1791   else
1792     DCL_TYPE (val->type) = POINTER;
1793   val->type->next = sym->type;
1794   val->etype = getSpec (val->type);
1795   return val;
1796 }
1797
1798 /*-----------------------------------------------------------------*/
1799 /* valForCastAggr - will return value for a cast of an aggregate   */
1800 /*                  plus minus a constant                          */
1801 /*-----------------------------------------------------------------*/
1802 value *
1803 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1804 {
1805   value *val;
1806
1807   if (!IS_AST_SYM_VALUE (aexpr))
1808     return NULL;
1809   if (!IS_AST_LIT_VALUE (cnst))
1810     return NULL;
1811
1812   val = newValue ();
1813
1814   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
1815            AST_SYMBOL (aexpr)->rname, op,
1816            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1817
1818   val->type = type;
1819   val->etype = getSpec (val->type);
1820   return val;
1821 }
1822
1823 /*-----------------------------------------------------------------*/
1824 /* valForCastAggr - will return value for a cast of an aggregate   */
1825 /*                  with no constant                               */
1826 /*-----------------------------------------------------------------*/
1827 value *
1828 valForCastArr (ast * aexpr, sym_link * type)
1829 {
1830   value *val;
1831
1832   if (!IS_AST_SYM_VALUE (aexpr))
1833     return NULL;
1834
1835   val = newValue ();
1836
1837   SNPRINTF (val->name, sizeof(val->name), "(%s)",
1838            AST_SYMBOL (aexpr)->rname);
1839
1840   val->type = type;
1841   val->etype = getSpec (val->type);
1842   return val;
1843 }