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