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