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