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