* src/SDCC.y, src/SDCCast.c, src/SDCCcse.c, src/SDCCglue.c, src/SDCCicode.c,
[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 = lexLineno;
61   nilist->filename = lexFilename;
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   int is_ptr = IS_PTR (type);
277   RESULT_TYPE resultType = getResultTypeFromType (getSpec (type));
278
279   while (ilist)
280     {
281       if (ilist->type == INIT_NODE)
282         {
283           ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
284             is_ptr ? RESULT_TYPE_INT : resultType);
285         }
286       else if (ilist->type == INIT_DEEP)
287         {
288           resolveIvalSym (ilist->init.deep, type);
289         }
290
291       ilist = ilist->next;
292    }
293 }
294
295 /*------------------------------------------------------------------*/
296 /* symbolVal - creates a value for a symbol                         */
297 /*------------------------------------------------------------------*/
298 value *
299 symbolVal (symbol * sym)
300 {
301   value *val;
302
303   if (!sym)
304     return NULL;
305
306   val = newValue ();
307   val->sym = sym;
308
309   if (sym->type)
310     {
311       val->type = sym->type;
312       val->etype = getSpec (val->type);
313     }
314
315   if (*sym->rname)
316     {
317         SNPRINTF (val->name, sizeof(val->name), "%s", sym->rname);
318     }
319   else
320     {
321         SNPRINTF (val->name, sizeof(val->name), "_%s", sym->name);
322     }
323
324   return val;
325 }
326
327 /*--------------------------------------------------------------------*/
328 /* cheapestVal - try to reduce 'signed int' to 'char'                 */
329 /*--------------------------------------------------------------------*/
330 static value *
331 cheapestVal (value *val)
332 {
333   /* only int can be reduced */
334   if (!IS_INT(val->type))
335     return val;
336
337   /* long must not be changed */
338   if (SPEC_LONG(val->type))
339     return val;
340
341   /* unsigned must not be changed */
342   if (SPEC_USIGN(val->type))
343     return val;
344
345   /* the only possible reduction is from signed int to (un)signed char,
346      because it's automatically promoted back to signed int.
347
348      a reduction from unsigned int to unsigned char is a bug,
349      because an _unsigned_ char is promoted to _signed_ int! */
350   if (SPEC_CVAL(val->type).v_int < -128 ||
351       SPEC_CVAL(val->type).v_int >  255)
352     {
353       /* not in the range of (un)signed char */
354       return val;
355     }
356
357   SPEC_NOUN(val->type) = V_CHAR;
358
359   /* 'unsigned char' promotes to 'signed int', so that we can
360      reduce it the other way */
361   if (SPEC_CVAL(val->type).v_int >= 0)
362     {
363       SPEC_USIGN(val->type) = 1;
364     }
365   return (val);
366 }
367
368 /*--------------------------------------------------------------------*/
369 /* checkConstantRange - check if constant fits in numeric range of    */
370 /* var type in comparisons and assignments                            */
371 /*--------------------------------------------------------------------*/
372 CCR_RESULT
373 checkConstantRange (sym_link *var, sym_link *lit, int op, bool exchangeLeftRight)
374 {
375   sym_link *reType;
376   double litVal;
377   int varBits;
378
379   litVal = floatFromVal (valFromType (lit));
380   varBits = bitsForType (var);
381
382   /* sanity checks */
383   if (   IS_FLOAT (var)
384       || IS_FIXED (var))
385     return CCR_OK;
386   if (varBits < 1)
387     return CCR_ALWAYS_FALSE;
388   if (varBits > 32)
389     return CCR_ALWAYS_TRUE;
390
391   /* special: assignment */
392   if (op == '=')
393     {
394       if (IS_BIT (var))
395         return CCR_OK;
396
397       if (getenv ("SDCC_VERY_PEDANTIC"))
398         {
399           if (SPEC_USIGN (var))
400             {
401               TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
402
403               if (   litVal < 0
404                   || litVal > maxVal)
405                 return CCR_OVL;
406               return CCR_OK;
407             }
408           else
409             {
410               TYPE_TARGET_LONG minVal = 0xffffffff << (varBits - 1);
411               TYPE_TARGET_LONG maxVal = 0x7fffffff >> (32 - varBits);
412
413               if (   litVal < minVal
414                   || litVal > maxVal)
415                 return CCR_OVL;
416               return CCR_OK;
417             }
418         }
419       else
420         {
421           /* ignore signedness, e.g. allow everything
422              from -127...+255 for (unsigned) char */
423           TYPE_TARGET_LONG  minVal = 0xffffffff  << (varBits - 1);
424           TYPE_TARGET_ULONG maxVal = 0xffffffffu >> (32 - varBits);
425
426           if (   litVal < minVal
427               || litVal > maxVal)
428             return CCR_OVL;
429           return CCR_OK;
430         }
431     }
432
433   if (exchangeLeftRight)
434     switch (op)
435       {
436         case EQ_OP:             break;
437         case NE_OP:             break;
438         case '>':   op = '<';   break;
439         case GE_OP: op = LE_OP; break;
440         case '<':   op = '>';   break;
441         case LE_OP: op = GE_OP; break;
442         default:                return CCR_ALWAYS_FALSE;
443       }
444
445   reType = computeType (var, lit, RESULT_TYPE_NONE, op);
446
447   if (SPEC_USIGN (reType))
448     {
449       /* unsigned operation */
450       TYPE_TARGET_ULONG minValP, maxValP, minValM, maxValM;
451       TYPE_TARGET_ULONG opBitsMask = 0xffffffffu >> (32 - bitsForType (reType));
452
453       if (SPEC_USIGN (lit) && SPEC_USIGN (var))
454         {
455           /* both operands are unsigned, this is easy */
456           minValP = 0;
457           maxValP = 0xffffffffu >> (32 - varBits);
458           /* there's only range, just copy it to 2nd set */
459           minValM = minValP;
460           maxValM = maxValP;
461         }
462       else if (SPEC_USIGN (var))
463         {
464           /* lit is casted from signed to unsigned, e.g.:
465                unsigned u;
466                  u == (char) -17
467               -> u == 0xffef'
468           */
469           minValP = 0;
470           maxValP = 0xffffffffu >> (32 - varBits);
471           /* there's only one range, just copy it to 2nd set */
472           minValM = minValP;
473           maxValM = maxValP;
474
475           /* it's an unsigned operation */
476           if (   IS_CHAR (reType)
477               || IS_INT (reType))
478             {
479               /* make signed literal unsigned and
480                  limit no of bits to size of return type */
481               litVal = (TYPE_TARGET_ULONG) double2ul (litVal) & opBitsMask;
482             }
483         }
484       else /* SPEC_USIGN (lit) */
485         {
486           /* var is casted from signed to unsigned, e.g.:
487                signed char c;
488                  c == (unsigned) -17
489               -> c == 0xffef'
490
491              The possible values after casting var
492              split up in two, nonconsecutive ranges:
493
494              minValP =      0;  positive range: 0...127
495              maxValP =   0x7f;
496              minValM = 0xff80;  negative range: -128...-1
497              maxValM = 0xffff;
498           */
499
500           /* positive range */
501           minValP = 0;
502           maxValP = 0x7fffffffu >> (32 - varBits);
503
504           /* negative range */
505           minValM = 0xffffffff  << (varBits - 1);
506           maxValM = 0xffffffffu; /* -1 */
507           /* limit no of bits to size of return type */
508           minValM &= opBitsMask;
509           maxValM &= opBitsMask;
510         }
511
512       switch (op)
513         {
514           case EQ_OP:                   /* var == lit */
515             if (   litVal <= maxValP
516                 && litVal >= minValP) /* 0 */
517               return CCR_OK;
518             if (   litVal <= maxValM
519                 && litVal >= minValM)
520               return CCR_OK;
521             return CCR_ALWAYS_FALSE;
522           case NE_OP:                   /* var != lit */
523             if (   litVal <= maxValP
524                 && litVal >= minValP) /* 0 */
525               return CCR_OK;
526             if (   litVal <= maxValM
527                 && litVal >= minValM)
528               return CCR_OK;
529             return CCR_ALWAYS_TRUE;
530           case '>':                     /* var >  lit */
531             if (litVal >= maxValM)
532               return CCR_ALWAYS_FALSE;
533             if (litVal <  minValP) /* 0 */
534               return CCR_ALWAYS_TRUE;
535             return CCR_OK;
536           case GE_OP:                   /* var >= lit */
537             if (litVal >  maxValM)
538               return CCR_ALWAYS_FALSE;
539             if (litVal <= minValP) /* 0 */
540               return CCR_ALWAYS_TRUE;
541             return CCR_OK;
542           case '<':                     /* var <  lit */
543             if (litVal >  maxValM)
544               return CCR_ALWAYS_TRUE;
545             if (litVal <= minValP) /* 0 */
546               return CCR_ALWAYS_FALSE;
547             return CCR_OK;
548           case LE_OP:                   /* var <= lit */
549             if (litVal >= maxValM)
550               return CCR_ALWAYS_TRUE;
551             if (litVal <  minValP) /* 0 */
552               return CCR_ALWAYS_FALSE;
553             return CCR_OK;
554           default:
555             return CCR_ALWAYS_FALSE;
556         }
557     }
558   else
559     {
560       /* signed operation */
561       TYPE_TARGET_LONG minVal, maxVal;
562
563       if (SPEC_USIGN (var))
564         {
565           /* unsigned var, but signed operation. This happens
566              when var is promoted to signed int.
567              Set actual min/max values of var. */
568           minVal = 0;
569           maxVal = 0xffffffff >> (32 - varBits);
570         }
571       else
572         {
573           /* signed var */
574           minVal = 0xffffffff << (varBits - 1);
575           maxVal = 0x7fffffff >> (32 - varBits);
576         }
577
578       switch (op)
579         {
580           case EQ_OP:                   /* var == lit */
581             if (   litVal > maxVal
582                 || litVal < minVal)
583               return CCR_ALWAYS_FALSE;
584             return CCR_OK;
585           case NE_OP:                   /* var != lit */
586             if (   litVal > maxVal
587                 || litVal < minVal)
588               return CCR_ALWAYS_TRUE;
589             return CCR_OK;
590           case '>':                     /* var >  lit */
591             if (litVal >= maxVal)
592               return CCR_ALWAYS_FALSE;
593             if (litVal <  minVal)
594               return CCR_ALWAYS_TRUE;
595             return CCR_OK;
596           case GE_OP:                   /* var >= lit */
597             if (litVal >  maxVal)
598               return CCR_ALWAYS_FALSE;
599             if (litVal <= minVal)
600               return CCR_ALWAYS_TRUE;
601             return CCR_OK;
602           case '<':                     /* var <  lit */
603             if (litVal >  maxVal)
604               return CCR_ALWAYS_TRUE;
605             if (litVal <= minVal)
606               return CCR_ALWAYS_FALSE;
607             return CCR_OK;
608           case LE_OP:                   /* var <= lit */
609             if (litVal >= maxVal)
610               return CCR_ALWAYS_TRUE;
611             if (litVal <  minVal)
612               return CCR_ALWAYS_FALSE;
613             return CCR_OK;
614           default:
615             return CCR_ALWAYS_FALSE;
616         }
617     }
618 }
619
620 /*-----------------------------------------------------------------*/
621 /* valueFromLit - creates a value from a literal                   */
622 /*-----------------------------------------------------------------*/
623 value *
624 valueFromLit (double lit)
625 {
626   char buffer[50];
627
628   if ((((TYPE_TARGET_LONG) lit) - lit) == 0)
629     {
630       SNPRINTF (buffer, sizeof(buffer), "%d", (TYPE_TARGET_LONG) lit);
631       return constVal (buffer);
632     }
633
634   SNPRINTF (buffer, sizeof(buffer), "%f", lit);
635   return constFloatVal (buffer);
636 }
637
638 /*-----------------------------------------------------------------*/
639 /* constFloatVal - converts a FLOAT constant to value              */
640 /*-----------------------------------------------------------------*/
641 value *
642 constFloatVal (char *s)
643 {
644   value *val = newValue ();
645   double sval;
646   char *p;
647
648   sval = strtod(s, &p);
649   if (p == s)
650     {
651       werror (E_INVALID_FLOAT_CONST, s);
652       return constVal ("0");
653     }
654
655   val->type = val->etype = newLink (SPECIFIER);
656   SPEC_NOUN (val->type) = V_FLOAT;
657   SPEC_SCLS (val->type) = S_LITERAL;
658   SPEC_CVAL (val->type).v_float = sval;
659
660   return val;
661 }
662
663 /*-----------------------------------------------------------------*/
664 /* constFixed16x16Val - converts a FIXED16X16 constant to value    */
665 /*-----------------------------------------------------------------*/
666 value *
667 constFixed16x16Val (char *s)
668 {
669   value *val = newValue ();
670   double sval;
671   char *p;
672
673   sval = strtod(s, &p);
674   if (p == s)
675     {
676       werror (E_INVALID_FLOAT_CONST, s);
677       return constVal ("0");
678     }
679
680   val->type = val->etype = newLink (SPECIFIER);
681   SPEC_NOUN (val->type) = V_FLOAT;
682   SPEC_SCLS (val->type) = S_LITERAL;
683   SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble ( sval );
684
685   return val;
686 }
687
688 /*-----------------------------------------------------------------*/
689 /* constVal - converts an INTEGER constant into a cheapest value   */
690 /*-----------------------------------------------------------------*/
691 value *constVal (const char *s)
692 {
693   value *val;
694   short hex = 0, octal = 0;
695   double dval;
696
697   val = newValue ();            /* alloc space for value   */
698
699   val->type = val->etype = newLink (SPECIFIER); /* create the spcifier */
700   SPEC_SCLS (val->type) = S_LITERAL;
701   // let's start with a signed char
702   SPEC_NOUN (val->type) = V_CHAR;
703   SPEC_USIGN (val->type) = 0;
704
705   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
706
707   /* set the octal flag   */
708   if (!hex && *s == '0' && *(s + 1))
709     octal = 1;
710
711   errno = 0;
712   if (hex || octal) {
713     unsigned long sval;
714     sval = strtoul (s, NULL, 0);
715     dval = sval;
716     if (errno) {
717       dval = 4294967295.0;
718       werror (W_INVALID_INT_CONST, s, dval);
719     }
720   } else {
721     dval = strtod(s, NULL);
722   }
723
724   /* Setup the flags first */
725   /* set the unsigned flag if 'uU' is found */
726   if (strchr (s, 'u') || strchr (s, 'U')) {
727     SPEC_USIGN (val->type) = 1;
728   }
729
730   /* set the b_long flag if 'lL' is found */
731   if (strchr (s, 'l') || strchr (s, 'L')) {
732     SPEC_NOUN (val->type) = V_INT;
733     SPEC_LONG (val->type) = 1;
734   } else {
735     if (dval<0) { // "-28u" will still be signed and negative
736       if (dval<-128) { // check if we have to promote to int
737         SPEC_NOUN (val->type) = V_INT;
738       }
739       if (dval<-32768) { // check if we have to promote to long int
740         SPEC_LONG (val->type) = 1;
741       }
742     } else { // >=0
743       if (dval>0xff ||  /* check if we have to promote to int */
744           SPEC_USIGN (val->type)) { /* if it's unsigned, we can't use unsigned
745                                      char. After an integral promotion it will
746                                      be a signed int; this certainly isn't what
747                                      the programer wants */
748         SPEC_NOUN (val->type) = V_INT;
749       }
750       else { /* store char's always as unsigned; this helps other optimizations */
751         SPEC_USIGN (val->type) = 1;
752       }
753       if (dval>0xffff && SPEC_USIGN (val->type)) { // check if we have to promote to long
754         SPEC_LONG (val->type) = 1;
755       }
756       else if (dval>0x7fff && !SPEC_USIGN (val->type)) { // check if we have to promote to long int
757         if ((hex || octal) && /* hex or octal constants may be stored in unsigned type */
758             dval<=0xffff) {
759           SPEC_USIGN (val->type) = 1;
760         } else {
761           SPEC_LONG (val->type) = 1;
762           if (dval>0x7fffffff) {
763             SPEC_USIGN (val->type) = 1;
764           }
765         }
766       }
767     }
768   }
769
770   /* check for out of range */
771   if (dval<-2147483648.0) {
772     dval = -2147483648.0;
773     werror (W_INVALID_INT_CONST, s, dval);
774   }
775   if (dval>2147483647.0 && !SPEC_USIGN (val->type)) {
776     dval = 2147483647.0;
777     werror (W_INVALID_INT_CONST, s, dval);
778   }
779   if (dval>4294967295.0) {
780     dval = 4294967295.0;
781     werror (W_INVALID_INT_CONST, s, dval);
782   }
783
784   if (SPEC_LONG (val->type))
785     {
786       if (SPEC_USIGN (val->type))
787         {
788           SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) double2ul (dval);
789         }
790       else
791         {
792           SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) double2ul (dval);
793         }
794     }
795   else
796     {
797       if (SPEC_USIGN (val->type))
798         {
799           SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) double2ul (dval);
800         }
801       else
802         {
803           SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) double2ul (dval);
804         }
805     }
806
807   return val;
808 }
809
810 /*------------------------------------------------------------------*/
811 /* strVal - converts a string constant to a value       */
812 /*------------------------------------------------------------------*/
813 value *
814 strVal (const char *s)
815 {
816   value *val;
817
818   val = newValue ();            /* get a new one */
819
820   /* get a declarator */
821   val->type = newLink (DECLARATOR);
822   DCL_TYPE (val->type) = ARRAY;
823   val->type->next = val->etype = newLink (SPECIFIER);
824   SPEC_NOUN (val->etype) = V_CHAR;
825   SPEC_SCLS (val->etype) = S_LITERAL;
826
827   SPEC_CVAL (val->etype).v_char = Safe_alloc (strlen (s) + 1);
828   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
829
830   return val;
831 }
832
833
834 /*------------------------------------------------------------------*/
835 /* reverseValWithType - reverses value chain with type & etype      */
836 /*------------------------------------------------------------------*/
837 value *
838 reverseValWithType (value * val)
839 {
840   sym_link *type;
841   sym_link *etype;
842
843   if (!val)
844     return NULL;
845
846   /* save the type * etype chains */
847   type = val->type;
848   etype = val->etype;
849
850   /* set the current one 2b null */
851   val->type = val->etype = NULL;
852   val = reverseVal (val);
853
854   /* restore type & etype */
855   val->type = type;
856   val->etype = etype;
857
858   return val;
859 }
860
861 /*------------------------------------------------------------------*/
862 /* reverseVal - reverses the values for a value  chain        */
863 /*------------------------------------------------------------------*/
864 value *
865 reverseVal (value * val)
866 {
867   value *prev, *curr, *next;
868
869   if (!val)
870     return NULL;
871
872   prev = val;
873   curr = val->next;
874
875   while (curr)
876     {
877       next = curr->next;
878       curr->next = prev;
879       prev = curr;
880       curr = next;
881     }
882   val->next = (void *) NULL;
883   return prev;
884 }
885
886 /*------------------------------------------------------------------*/
887 /* copyValueChain - will copy a chain of values                     */
888 /*------------------------------------------------------------------*/
889 value *
890 copyValueChain (value * src)
891 {
892   value *dest;
893
894   if (!src)
895     return NULL;
896
897   dest = copyValue (src);
898   dest->next = copyValueChain (src->next);
899
900   return dest;
901 }
902
903 /*------------------------------------------------------------------*/
904 /* copyValue - copies contents of a value to a fresh one            */
905 /*------------------------------------------------------------------*/
906 value *
907 copyValue (value * src)
908 {
909   value *dest;
910
911   dest = newValue ();
912   dest->sym = copySymbol (src->sym);
913   strncpyz (dest->name, src->name, SDCC_NAME_MAX);
914   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
915   dest->etype = (src->type ? getSpec (dest->type) : NULL);
916
917   return dest;
918 }
919
920 /*------------------------------------------------------------------*/
921 /* charVal - converts a character constant to a value       */
922 /*------------------------------------------------------------------*/
923 value *
924 charVal (const char *s)
925 {
926   value *val;
927
928   val = newValue ();
929
930   val->type = val->etype = newLink (SPECIFIER);
931   SPEC_NOUN (val->type) = V_CHAR;
932   SPEC_USIGN(val->type) = 1;
933   SPEC_SCLS (val->type) = S_LITERAL;
934
935   s++;                          /* get rid of quotation */
936   /* if \ then special processing */
937   if (*s == '\\')
938     {
939       s++;                      /* go beyond the backslash  */
940       switch (*s)
941         {
942         case 'n':
943           SPEC_CVAL (val->type).v_uint = '\n';
944           break;
945         case 't':
946           SPEC_CVAL (val->type).v_uint = '\t';
947           break;
948         case 'v':
949           SPEC_CVAL (val->type).v_uint = '\v';
950           break;
951         case 'b':
952           SPEC_CVAL (val->type).v_uint = '\b';
953           break;
954         case 'r':
955           SPEC_CVAL (val->type).v_uint = '\r';
956           break;
957         case 'f':
958           SPEC_CVAL (val->type).v_uint = '\f';
959           break;
960         case 'a':
961           SPEC_CVAL (val->type).v_uint = '\a';
962           break;
963         case '\\':
964           SPEC_CVAL (val->type).v_uint = '\\';
965           break;
966         case '\?':
967           SPEC_CVAL (val->type).v_uint = '\?';
968           break;
969         case '\'':
970           SPEC_CVAL (val->type).v_uint = '\'';
971           break;
972         case '\"':
973           SPEC_CVAL (val->type).v_uint = '\"';
974           break;
975
976         case '0' :
977         case '1' :
978         case '2' :
979         case '3' :
980         case '4' :
981         case '5' :
982         case '6' :
983         case '7' :
984           SPEC_CVAL (val->type).v_uint = octalEscape(&s);
985           break;
986
987         case 'x':
988           SPEC_CVAL (val->type).v_uint = hexEscape(&s) ;
989           break;
990
991         default:
992           SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
993           break;
994         }
995     }
996   else                          /* not a backslash */
997     SPEC_CVAL (val->type).v_uint = (unsigned char)*s;
998
999   return val;
1000 }
1001
1002 /*------------------------------------------------------------------*/
1003 /* valFromType - creates a value from type given                    */
1004 /*------------------------------------------------------------------*/
1005 value *
1006 valFromType (sym_link * type)
1007 {
1008   value *val = newValue ();
1009   val->type = copyLinkChain (type);
1010   val->etype = getSpec (val->type);
1011   return val;
1012 }
1013
1014 /*------------------------------------------------------------------*/
1015 /* floatFromVal - value to double float conversion                  */
1016 /*------------------------------------------------------------------*/
1017 #if 0
1018 double
1019 floatFromVal (value * val)
1020 {
1021   double res;
1022
1023   if (!val)
1024     return 0;
1025
1026   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1027     {
1028       werror (E_CONST_EXPECTED, val->name);
1029       return 0;
1030     }
1031
1032   /* if it is not a specifier then we can assume that */
1033   /* it will be an unsigned long                      */
1034   if (!IS_SPEC (val->type)) {
1035     //return (double) SPEC_CVAL (val->etype).v_ulong;
1036     res =SPEC_CVAL (val->etype).v_ulong;
1037     goto ret;
1038   }
1039
1040   if (SPEC_NOUN (val->etype) == V_FLOAT) {
1041     //return (double) SPEC_CVAL (val->etype).v_float;
1042     res =SPEC_CVAL (val->etype).v_float;
1043     goto ret;
1044   }
1045
1046   if (SPEC_NOUN (val->etype) == V_FIXED16X16) {
1047     res =doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1048     goto ret;
1049   }
1050
1051   if (SPEC_LONG (val->etype))
1052     {
1053       if (SPEC_USIGN (val->etype)) {
1054         //return (double) SPEC_CVAL (val->etype).v_ulong;
1055         res =SPEC_CVAL (val->etype).v_ulong;
1056         goto ret;
1057       }
1058       else {
1059         //return (double) SPEC_CVAL (val->etype).v_long;
1060         res =SPEC_CVAL (val->etype).v_long;
1061         goto ret;
1062       }
1063     }
1064
1065   if (SPEC_NOUN (val->etype) == V_INT) {
1066     if (SPEC_USIGN (val->etype)) {
1067       //return (double) SPEC_CVAL (val->etype).v_uint;
1068       res =SPEC_CVAL (val->etype).v_uint;
1069       goto ret;
1070     }
1071     else {
1072       //return (double) SPEC_CVAL (val->etype).v_int;
1073       res =SPEC_CVAL (val->etype).v_int;
1074       goto ret;
1075     }
1076   }
1077
1078   if (SPEC_NOUN (val->etype) == V_CHAR) {
1079     if (SPEC_USIGN (val->etype)) {
1080       //return (double) (unsigned char)SPEC_CVAL (val->etype).v_uint;
1081       res =(unsigned char)SPEC_CVAL (val->etype).v_uint;
1082       goto ret;
1083     }
1084     else
1085     {
1086       res = (signed char)SPEC_CVAL (val->etype).v_int;
1087       goto ret;
1088     }
1089   }
1090
1091   if (IS_BITVAR(val->etype)) {
1092     //return (double) SPEC_CVAL (val->etype).v_uint;
1093     res =SPEC_CVAL (val->etype).v_uint;
1094     goto ret;
1095   }
1096
1097   if (SPEC_NOUN (val->etype) == V_VOID) {
1098     //return (double) SPEC_CVAL (val->etype).v_ulong;
1099     res = SPEC_CVAL (val->etype).v_ulong;
1100     goto ret;
1101   }
1102
1103   // we are lost !
1104   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1105           "floatFromVal: unknown value");
1106   return 0;
1107
1108 ret:
1109    printf("floatFromVal(%f)\n", res);
1110    return res;
1111 }
1112 #endif
1113
1114 double
1115 floatFromVal (value * val)
1116 {
1117   if (!val)
1118     return 0;
1119
1120   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1121     {
1122       werror (E_CONST_EXPECTED, val->name);
1123       return 0;
1124     }
1125
1126   /* if it is not a specifier then we can assume that */
1127   /* it will be an unsigned long                      */
1128   if (!IS_SPEC (val->type))
1129     return SPEC_CVAL (val->etype).v_ulong;
1130
1131   if (SPEC_NOUN (val->etype) == V_FLOAT)
1132     return SPEC_CVAL (val->etype).v_float;
1133
1134   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1135     return doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 );
1136
1137   if (SPEC_LONG (val->etype))
1138     {
1139       if (SPEC_USIGN (val->etype))
1140         return SPEC_CVAL (val->etype).v_ulong;
1141       else
1142         return SPEC_CVAL (val->etype).v_long;
1143     }
1144
1145   if (SPEC_NOUN (val->etype) == V_INT) {
1146     if (SPEC_USIGN (val->etype))
1147       return SPEC_CVAL (val->etype).v_uint;
1148     else
1149       return SPEC_CVAL (val->etype).v_int;
1150   }
1151
1152   if (SPEC_NOUN (val->etype) == V_CHAR) {
1153     if (SPEC_USIGN (val->etype))
1154       return (unsigned char)SPEC_CVAL (val->etype).v_uint;
1155     else
1156       return (signed char)SPEC_CVAL (val->etype).v_int;
1157   }
1158
1159   if (IS_BITVAR(val->etype))
1160     return SPEC_CVAL (val->etype).v_uint;
1161
1162   if (SPEC_NOUN (val->etype) == V_VOID)
1163     return SPEC_CVAL (val->etype).v_ulong;
1164
1165   // we are lost !
1166   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "floatFromVal: unknown value");
1167   return 0;
1168 }
1169
1170 /*------------------------------------------------------------------*/
1171 /* ulFromVal - value to unsigned long conversion                    */
1172 /*------------------------------------------------------------------*/
1173 unsigned long
1174 ulFromVal (value * val)
1175 {
1176   if (!val)
1177     return 0;
1178
1179   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
1180     {
1181       werror (E_CONST_EXPECTED, val->name);
1182       return 0;
1183     }
1184
1185   /* if it is not a specifier then we can assume that */
1186   /* it will be an unsigned long                      */
1187   if (!IS_SPEC (val->type))
1188     return SPEC_CVAL (val->etype).v_ulong;
1189
1190   if (SPEC_NOUN (val->etype) == V_FLOAT)
1191     return double2ul (SPEC_CVAL (val->etype).v_float);
1192
1193   if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1194     return double2ul (doubleFromFixed16x16( SPEC_CVAL (val->etype).v_fixed16x16 ));
1195
1196   if (SPEC_LONG (val->etype))
1197     {
1198       if (SPEC_USIGN (val->etype))
1199         return SPEC_CVAL (val->etype).v_ulong;
1200       else
1201         return SPEC_CVAL (val->etype).v_long;
1202     }
1203
1204   if (SPEC_NOUN (val->etype) == V_INT) {
1205     if (SPEC_USIGN (val->etype))
1206       return SPEC_CVAL (val->etype).v_uint;
1207     else
1208       return SPEC_CVAL (val->etype).v_int;
1209   }
1210
1211   if (SPEC_NOUN (val->etype) == V_CHAR) {
1212     if (SPEC_USIGN (val->etype))
1213       return (unsigned char)SPEC_CVAL (val->etype).v_uint;
1214     else
1215       return (signed char)SPEC_CVAL (val->etype).v_int;
1216   }
1217
1218   if (IS_BITVAR(val->etype)) {
1219     return SPEC_CVAL (val->etype).v_uint;
1220   }
1221
1222   if (SPEC_NOUN (val->etype) == V_VOID) {
1223     return SPEC_CVAL (val->etype).v_ulong;
1224   }
1225
1226   // we are lost !
1227   werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "ulFromVal: unknown value");
1228   return 0;
1229 }
1230
1231 /*-----------------------------------------------------------------*/
1232 /* doubleFromFixed16x16 - convert a fixed16x16 to double           */
1233 /*-----------------------------------------------------------------*/
1234 double doubleFromFixed16x16(TYPE_TARGET_ULONG value)
1235 {
1236 #if 0
1237   /* This version is incorrect negative values. */
1238   double tmp=0, exp=2;
1239
1240     tmp = (value & 0xffff0000) >> 16;
1241     
1242     while(value) {
1243       value &= 0xffff;
1244       if(value & 0x8000)tmp += 1/exp;
1245       exp *= 2;
1246       value <<= 1;
1247     }
1248   
1249   return (tmp);
1250 #else
1251   return ((double)(value * 1.0) / (double)(1UL << 16));
1252 #endif
1253 }
1254
1255 TYPE_TARGET_ULONG fixed16x16FromDouble(double value)
1256 {
1257 #if 0
1258   /* This version is incorrect negative values. */
1259   unsigned int tmp=0, pos=16;
1260   TYPE_TARGET_ULONG res;
1261
1262     tmp = floor( value );
1263     res = tmp << 16;
1264     value -= tmp;
1265     
1266     tmp = 0;
1267     while(pos--) {
1268       value *= 2;
1269       if(value >= 1.0)tmp |= (1 << pos);
1270       value -= floor( value );
1271     }
1272   
1273     res |= tmp;
1274
1275   return (res);
1276 #else
1277   return  double2ul (value * (double)(1UL << 16));
1278 #endif
1279 }
1280
1281 /*------------------------------------------------------------------*/
1282 /* valUnaryPM - does the unary +/- operation on a constant          */
1283 /*------------------------------------------------------------------*/
1284 value *
1285 valUnaryPM (value * val)
1286 {
1287   /* depending on type */
1288   if (SPEC_NOUN (val->etype) == V_FLOAT)
1289     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
1290   else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1291     SPEC_CVAL (val->etype).v_fixed16x16 = -SPEC_CVAL (val->etype).v_fixed16x16;
1292   else
1293     {
1294       if (SPEC_LONG (val->etype))
1295         {
1296           if (SPEC_USIGN (val->etype))
1297             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
1298           else
1299             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
1300         }
1301       else
1302         {
1303           if (SPEC_USIGN (val->etype))
1304             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
1305           else
1306             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
1307
1308           if (SPEC_NOUN(val->etype) == V_CHAR)
1309             {
1310               /* promote to 'signed int', cheapestVal() might reduce it again */
1311               SPEC_USIGN(val->etype) = 0;
1312               SPEC_NOUN(val->etype) = V_INT;
1313             }
1314           return cheapestVal (val);
1315         }
1316     }
1317   return val;
1318 }
1319
1320 /*------------------------------------------------------------------*/
1321 /* valueComplement - complements a constant                         */
1322 /*------------------------------------------------------------------*/
1323 value *
1324 valComplement (value * val)
1325 {
1326   /* depending on type */
1327   if (SPEC_LONG (val->etype))
1328     {
1329       if (SPEC_USIGN (val->etype))
1330         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
1331       else
1332         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
1333     }
1334   else
1335     {
1336       if (SPEC_USIGN (val->etype))
1337         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
1338       else
1339         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
1340
1341       if (SPEC_NOUN(val->etype) == V_CHAR)
1342         {
1343           /* promote to 'signed int', cheapestVal() might reduce it again */
1344           SPEC_USIGN(val->etype) = 0;
1345           SPEC_NOUN(val->etype) = V_INT;
1346         }
1347       return cheapestVal (val);
1348     }
1349   return val;
1350 }
1351
1352 /*------------------------------------------------------------------*/
1353 /* valueNot - complements a constant                                */
1354 /*------------------------------------------------------------------*/
1355 value *
1356 valNot (value * val)
1357 {
1358   /* depending on type */
1359   if (SPEC_LONG (val->etype))
1360     {
1361       if (SPEC_USIGN (val->etype))
1362         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_ulong;
1363       else
1364         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_long;
1365     }
1366   else
1367     {
1368       if (SPEC_USIGN (val->etype))
1369         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_uint;
1370       else
1371         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
1372
1373     }
1374   /* ANSI: result type is int, value is 0 or 1 */
1375   /* sdcc will hold this in an 'unsigned char' */
1376   SPEC_USIGN(val->etype) = 1;
1377   SPEC_LONG (val->etype) = 0;
1378   SPEC_NOUN(val->etype) = V_CHAR;
1379   return val;
1380 }
1381
1382 /*------------------------------------------------------------------*/
1383 /* valMult - multiply constants                                     */
1384 /*------------------------------------------------------------------*/
1385 value *
1386 valMult (value * lval, value * rval)
1387 {
1388   value *val;
1389
1390   /* create a new value */
1391   val = newValue ();
1392   val->type = val->etype = computeType (lval->etype,
1393                                         rval->etype,
1394                                         RESULT_TYPE_INT,
1395                                         '*');
1396   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1397
1398   if (IS_FLOAT (val->type))
1399     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
1400   else
1401   if (IS_FIXED16X16 (val->type))
1402     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble(floatFromVal (lval) * floatFromVal (rval));
1403       /* signed and unsigned mul are the same, as long as the precision of the
1404          result isn't bigger than the precision of the operands. */
1405   else if (SPEC_LONG (val->type))
1406     SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) *
1407                                     (TYPE_TARGET_ULONG) ulFromVal (rval);
1408   else if (SPEC_USIGN (val->type)) /* unsigned int */
1409     {
1410       TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) ulFromVal (lval) *
1411                              (TYPE_TARGET_UINT) ulFromVal (rval);
1412
1413       SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ul;
1414       if (ul != (TYPE_TARGET_UINT) ul)
1415         werror (W_INT_OVL);
1416     }
1417   else /* signed int */
1418     {
1419       TYPE_TARGET_LONG l = (TYPE_TARGET_INT) floatFromVal (lval) *
1420                            (TYPE_TARGET_INT) floatFromVal (rval);
1421
1422       SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) l;
1423       if (l != (TYPE_TARGET_INT) l)
1424         werror (W_INT_OVL);
1425     }
1426   return cheapestVal (val);
1427 }
1428
1429 /*------------------------------------------------------------------*/
1430 /* valDiv  - Divide   constants                                     */
1431 /*------------------------------------------------------------------*/
1432 value *
1433 valDiv (value * lval, value * rval)
1434 {
1435   value *val;
1436
1437   if (floatFromVal (rval) == 0)
1438     {
1439       werror (E_DIVIDE_BY_ZERO);
1440       return rval;
1441     }
1442
1443   /* create a new value */
1444   val = newValue ();
1445   val->type = val->etype = computeType (lval->etype,
1446                                         rval->etype,
1447                                         RESULT_TYPE_INT,
1448                                         '/');
1449   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1450
1451   if (IS_FLOAT (val->type))
1452     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
1453   else
1454   if (IS_FIXED16X16 (val->type))
1455     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) / floatFromVal (rval) );
1456   else if (SPEC_LONG (val->type))
1457     {
1458       if (SPEC_USIGN (val->type))
1459         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) /
1460           (TYPE_TARGET_ULONG) ulFromVal (rval);
1461       else
1462         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) /
1463           (TYPE_TARGET_LONG) ulFromVal (rval);
1464     }
1465   else
1466     {
1467       if (SPEC_USIGN (val->type))
1468         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) /
1469           (TYPE_TARGET_UINT) ulFromVal (rval);
1470       else
1471         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) /
1472           (TYPE_TARGET_INT) ulFromVal (rval);
1473     }
1474   return cheapestVal (val);
1475 }
1476
1477 /*------------------------------------------------------------------*/
1478 /* valMod  - Modulus  constants                                     */
1479 /*------------------------------------------------------------------*/
1480 value *
1481 valMod (value * lval, value * rval)
1482 {
1483   value *val;
1484
1485   /* create a new value */
1486   val = newValue();
1487   val->type = val->etype = computeType (lval->etype,
1488                                         rval->etype,
1489                                         RESULT_TYPE_INT,
1490                                         '%');
1491   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1492
1493   if (SPEC_LONG (val->type))
1494     {
1495       if (SPEC_USIGN (val->type))
1496         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) %
1497           (TYPE_TARGET_ULONG) ulFromVal (rval);
1498       else
1499         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) %
1500           (TYPE_TARGET_LONG) ulFromVal (rval);
1501     }
1502   else
1503     {
1504       if (SPEC_USIGN (val->type))
1505         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) %
1506           (TYPE_TARGET_UINT) ulFromVal (rval);
1507       else
1508         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) %
1509           (TYPE_TARGET_INT) ulFromVal (rval);
1510     }
1511   return cheapestVal (val);
1512 }
1513
1514 /*------------------------------------------------------------------*/
1515 /* valPlus - Addition constants                                     */
1516 /*------------------------------------------------------------------*/
1517 value *
1518 valPlus (value * lval, value * rval)
1519 {
1520   value *val;
1521
1522   /* create a new value */
1523   val = newValue();
1524   val->type = val->etype = computeType (lval->etype,
1525                                         rval->etype,
1526                                         RESULT_TYPE_INT,
1527                                         '+');
1528   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1529
1530   if (IS_FLOAT (val->type))
1531     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1532   else
1533   if (IS_FIXED16X16 (val->type))
1534     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) + floatFromVal (rval) );
1535   else  if (SPEC_LONG (val->type))
1536     {
1537       if (SPEC_USIGN (val->type))
1538         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) +
1539          (TYPE_TARGET_ULONG) ulFromVal (rval);
1540       else
1541         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) +
1542           (TYPE_TARGET_LONG) ulFromVal (rval);
1543     }
1544   else
1545     {
1546       if (SPEC_USIGN (val->type))
1547         SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) +
1548           (TYPE_TARGET_UINT) ulFromVal (rval);
1549       else
1550         SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) +
1551           (TYPE_TARGET_INT) ulFromVal (rval);
1552     }
1553   return cheapestVal (val);
1554 }
1555
1556 /*------------------------------------------------------------------*/
1557 /* valMinus - Addition constants                                    */
1558 /*------------------------------------------------------------------*/
1559 value *
1560 valMinus (value * lval, value * rval)
1561 {
1562   value *val;
1563
1564   /* create a new value */
1565   val = newValue();
1566   val->type = val->etype = computeType (lval->etype,
1567                                         rval->etype,
1568                                         RESULT_TYPE_INT,
1569                                         '-');
1570   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1571
1572   if (IS_FLOAT (val->type))
1573     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1574   else
1575   if (IS_FIXED16X16 (val->type))
1576     SPEC_CVAL (val->type).v_fixed16x16 = fixed16x16FromDouble( floatFromVal (lval) - floatFromVal (rval) );
1577   else  if (SPEC_LONG (val->type))
1578     {
1579       if (SPEC_USIGN (val->type))
1580         SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) -
1581           (TYPE_TARGET_ULONG) ulFromVal (rval);
1582       else
1583         SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) -
1584           (TYPE_TARGET_LONG) ulFromVal (rval);
1585     }
1586   else
1587    {
1588      if (SPEC_USIGN (val->type))
1589        SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) -
1590          (TYPE_TARGET_UINT) ulFromVal (rval);
1591      else
1592        SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) -
1593          (TYPE_TARGET_INT) ulFromVal (rval);
1594     }
1595   return cheapestVal (val);
1596 }
1597
1598 /*------------------------------------------------------------------*/
1599 /* valShift - Shift left or right                                   */
1600 /*------------------------------------------------------------------*/
1601 value *
1602 valShift (value * lval, value * rval, int lr)
1603 {
1604   value *val;
1605
1606   /* create a new value */
1607   val = newValue();
1608   val->type = val->etype = computeType (lval->etype,
1609                                         NULL,
1610                                         RESULT_TYPE_INT,
1611                                         'S');
1612   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
1613
1614   if (getSize (val->type) * 8 <= (TYPE_TARGET_ULONG) ulFromVal (rval) &&
1615        /* left shift */
1616       (lr ||
1617         /* right shift and unsigned */
1618        (!lr && SPEC_USIGN (rval->type))))
1619     {
1620       werror (W_SHIFT_CHANGED, (lr ? "left" : "right"));
1621     }
1622
1623   if (SPEC_LONG (val->type))
1624     {
1625       if (SPEC_USIGN (val->type))
1626         {
1627           SPEC_CVAL (val->type).v_ulong = lr ?
1628             (TYPE_TARGET_ULONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1629             (TYPE_TARGET_ULONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1630         }
1631       else
1632         {
1633           SPEC_CVAL (val->type).v_long = lr ?
1634             (TYPE_TARGET_LONG) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1635             (TYPE_TARGET_LONG) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1636         }
1637     }
1638   else
1639     {
1640       if (SPEC_USIGN (val->type))
1641         {
1642           SPEC_CVAL (val->type).v_uint = lr ?
1643             (TYPE_TARGET_UINT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1644             (TYPE_TARGET_UINT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1645         }
1646       else
1647         {
1648           SPEC_CVAL (val->type).v_int = lr ?
1649             (TYPE_TARGET_INT) ulFromVal (lval) << (TYPE_TARGET_ULONG) ulFromVal (rval) : \
1650             (TYPE_TARGET_INT) ulFromVal (lval) >> (TYPE_TARGET_ULONG) ulFromVal (rval);
1651         }
1652     }
1653   return cheapestVal (val);
1654 }
1655
1656 /*------------------------------------------------------------------*/
1657 /* valCompare- Compares two literal                                 */
1658 /*------------------------------------------------------------------*/
1659 value *
1660 valCompare (value * lval, value * rval, int ctype)
1661 {
1662   value *val;
1663
1664   /* create a new value */
1665   val = newValue ();
1666   val->type = val->etype = newCharLink ();
1667   val->type->class = SPECIFIER;
1668   SPEC_NOUN (val->type) = V_CHAR;       /* type is char */
1669   SPEC_USIGN (val->type) = 1;
1670   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1671
1672   switch (ctype)
1673     {
1674     case '<':
1675       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1676       break;
1677
1678     case '>':
1679       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1680       break;
1681
1682     case LE_OP:
1683       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1684       break;
1685
1686     case GE_OP:
1687       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1688       break;
1689
1690     case EQ_OP:
1691       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1692           SPEC_NOUN(rval->type) == V_FLOAT)
1693         {
1694           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1695         }
1696       else
1697       if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1698           SPEC_NOUN(rval->type) == V_FIXED16X16)
1699         {
1700           SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1701         }
1702       else
1703         {
1704           /* integrals: ignore signedness */
1705           TYPE_TARGET_ULONG l, r;
1706
1707           l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1708           r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1709           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1710              neccessary to strip them to 16 bit.
1711              Literals are reduced to their cheapest type, therefore left and
1712              right might have different types. It's neccessary to find a
1713              common type: int (used for char too) or long */
1714           if (!IS_LONG (lval->etype) &&
1715               !IS_LONG (rval->etype))
1716             {
1717               r = (TYPE_TARGET_UINT) r;
1718               l = (TYPE_TARGET_UINT) l;
1719             }
1720           SPEC_CVAL (val->type).v_int = l == r;
1721         }
1722       break;
1723     case NE_OP:
1724       if (SPEC_NOUN(lval->type) == V_FLOAT ||
1725           SPEC_NOUN(rval->type) == V_FLOAT)
1726         {
1727           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1728         }
1729       else
1730       if (SPEC_NOUN(lval->type) == V_FIXED16X16 ||
1731           SPEC_NOUN(rval->type) == V_FIXED16X16)
1732         {
1733           SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1734         }
1735       else
1736         {
1737           /* integrals: ignore signedness */
1738           TYPE_TARGET_ULONG l, r;
1739
1740           l = (TYPE_TARGET_ULONG) ulFromVal (lval);
1741           r = (TYPE_TARGET_ULONG) ulFromVal (rval);
1742           /* In order to correctly compare 'signed int' and 'unsigned int' it's
1743              neccessary to strip them to 16 bit.
1744              Literals are reduced to their cheapest type, therefore left and
1745              right might have different types. It's neccessary to find a
1746              common type: int (used for char too) or long */
1747           if (!IS_LONG (lval->etype) &&
1748               !IS_LONG (rval->etype))
1749             {
1750               r = (TYPE_TARGET_UINT) r;
1751               l = (TYPE_TARGET_UINT) l;
1752             }
1753           SPEC_CVAL (val->type).v_int = l != r;
1754         }
1755       break;
1756
1757     }
1758
1759   return val;
1760 }
1761
1762 /*------------------------------------------------------------------*/
1763 /* valBitwise - Bitwise operation                                   */
1764 /*------------------------------------------------------------------*/
1765 value *
1766 valBitwise (value * lval, value * rval, int op)
1767 {
1768   value *val;
1769
1770   /* create a new value */
1771   val = newValue ();
1772   val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
1773   val->etype = getSpec (val->type);
1774   SPEC_SCLS (val->etype) = S_LITERAL;
1775
1776   switch (op)
1777     {
1778     case '&':
1779       if (SPEC_LONG (val->type))
1780         {
1781           if (SPEC_USIGN (val->type))
1782             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) &
1783               (TYPE_TARGET_ULONG) ulFromVal (rval);
1784           else
1785             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) &
1786               (TYPE_TARGET_LONG) ulFromVal (rval);
1787         }
1788       else
1789         {
1790           if (SPEC_USIGN (val->type))
1791             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) &
1792               (TYPE_TARGET_UINT) ulFromVal (rval);
1793           else
1794             SPEC_CVAL (val->type).v_int = (TYPE_TARGET_INT) ulFromVal (lval) &
1795               (TYPE_TARGET_INT) ulFromVal (rval);
1796         }
1797       break;
1798
1799     case '|':
1800       if (SPEC_LONG (val->type))
1801         {
1802           if (SPEC_USIGN (val->type))
1803             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) |
1804               (TYPE_TARGET_ULONG) ulFromVal (rval);
1805           else
1806             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) |
1807               (TYPE_TARGET_LONG) ulFromVal (rval);
1808         }
1809       else
1810         {
1811           if (SPEC_USIGN (val->type))
1812             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) |
1813               (TYPE_TARGET_UINT) ulFromVal (rval);
1814           else
1815             SPEC_CVAL (val->type).v_int =
1816               (TYPE_TARGET_INT) ulFromVal (lval) | (TYPE_TARGET_INT) ulFromVal (rval);
1817         }
1818
1819       break;
1820
1821     case '^':
1822       if (SPEC_LONG (val->type))
1823         {
1824           if (SPEC_USIGN (val->type))
1825             SPEC_CVAL (val->type).v_ulong = (TYPE_TARGET_ULONG) ulFromVal (lval) ^
1826               (TYPE_TARGET_ULONG) ulFromVal (rval);
1827           else
1828             SPEC_CVAL (val->type).v_long = (TYPE_TARGET_LONG) ulFromVal (lval) ^
1829               (TYPE_TARGET_LONG) ulFromVal (rval);
1830         }
1831       else
1832         {
1833           if (SPEC_USIGN (val->type))
1834             SPEC_CVAL (val->type).v_uint = (TYPE_TARGET_UINT) ulFromVal (lval) ^
1835               (TYPE_TARGET_UINT) ulFromVal (rval);
1836           else
1837             SPEC_CVAL (val->type).v_int =
1838               (TYPE_TARGET_INT) ulFromVal (lval) ^ (TYPE_TARGET_INT) ulFromVal (rval);
1839         }
1840       break;
1841     }
1842
1843   return cheapestVal(val);
1844 }
1845
1846 /*------------------------------------------------------------------*/
1847 /* valAndOr   - Generates code for and / or operation               */
1848 /*------------------------------------------------------------------*/
1849 value *
1850 valLogicAndOr (value * lval, value * rval, int op)
1851 {
1852   value *val;
1853
1854   /* create a new value */
1855   val = newValue ();
1856   val->type = val->etype = newCharLink ();
1857   val->type->class = SPECIFIER;
1858   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1859   SPEC_USIGN (val->type) = 1;
1860
1861   switch (op)
1862     {
1863     case AND_OP:
1864       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1865       break;
1866
1867     case OR_OP:
1868       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1869       break;
1870     }
1871
1872
1873   return val;
1874 }
1875
1876 /*------------------------------------------------------------------*/
1877 /* valCastLiteral - casts a literal value to another type           */
1878 /*------------------------------------------------------------------*/
1879 #if 0
1880 value *
1881 valCastLiteral (sym_link * dtype, double fval)
1882 {
1883   value *val;
1884   unsigned long l = double2ul (fval);
1885
1886   if (!dtype)
1887     return NULL;
1888
1889   val = newValue ();
1890   if (dtype)
1891     val->etype = getSpec (val->type = copyLinkChain (dtype));
1892   else
1893     {
1894       val->etype = val->type = newLink (SPECIFIER);
1895       SPEC_NOUN (val->etype) = V_VOID;
1896     }
1897   SPEC_SCLS (val->etype) = S_LITERAL;
1898
1899   /* if it is not a specifier then we can assume that */
1900   /* it will be an unsigned long                      */
1901   if (!IS_SPEC (val->type)) {
1902       SPEC_CVAL (val->etype).v_ulong = l;
1903       return val;
1904   }
1905
1906   if (SPEC_NOUN (val->etype) == V_FLOAT)
1907       SPEC_CVAL (val->etype).v_float = fval;
1908   else if (SPEC_NOUN (val->etype) == V_FIXED16X16)
1909       SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble( fval );
1910   else if (SPEC_NOUN (val->etype) == V_BIT ||
1911            SPEC_NOUN (val->etype) == V_SBIT)
1912     SPEC_CVAL (val->etype).v_uint = l ? 1 : 0;
1913   else if (SPEC_NOUN (val->etype) == V_BITFIELD)
1914     SPEC_CVAL (val->etype).v_uint = l &
1915                                     (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1916   else if (SPEC_NOUN (val->etype) == V_CHAR) {
1917       if (SPEC_USIGN (val->etype))
1918           SPEC_CVAL (val->etype).v_uint= (TYPE_TARGET_UCHAR) l;
1919       else
1920           SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1921   } else {
1922       if (SPEC_LONG (val->etype)) {
1923           if (SPEC_USIGN (val->etype))
1924               SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1925           else
1926               SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1927       } else {
1928           if (SPEC_USIGN (val->etype))
1929               SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
1930           else
1931               SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
1932       }
1933   }
1934   return val;
1935 }
1936 #endif
1937
1938 value *
1939 valCastLiteral (sym_link * dtype, double fval)
1940 {
1941   value *val;
1942   unsigned long l = double2ul (fval);
1943
1944   if (!dtype)
1945     return NULL;
1946
1947   val = newValue ();
1948   if (dtype)
1949     val->etype = getSpec (val->type = copyLinkChain (dtype));
1950   else
1951     {
1952       val->etype = val->type = newLink (SPECIFIER);
1953       SPEC_NOUN (val->etype) = V_VOID;
1954     }
1955   SPEC_SCLS (val->etype) = S_LITERAL;
1956
1957   /* if it is not a specifier then we can assume that */
1958   /* it will be an unsigned long                      */
1959   if (!IS_SPEC (val->type))
1960     {
1961       SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1962       return val;
1963     }
1964
1965   switch (SPEC_NOUN (val->etype))
1966     {
1967     case V_FLOAT:
1968       SPEC_CVAL (val->etype).v_float = fval;
1969       break;
1970
1971     case V_FIXED16X16:
1972       SPEC_CVAL (val->etype).v_fixed16x16 = fixed16x16FromDouble (fval);
1973       break;
1974
1975     case V_BIT:
1976     case V_SBIT:
1977       SPEC_CVAL (val->etype).v_uint = fval ? 1 : 0;
1978       break;
1979
1980     case V_BITFIELD:
1981       SPEC_CVAL (val->etype).v_uint = ((TYPE_TARGET_UINT) l) &
1982         (0xffffu >> (16 - SPEC_BLEN (val->etype)));
1983       break;
1984
1985     case V_CHAR:
1986       if (SPEC_USIGN (val->etype))
1987         SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UCHAR) l;
1988       else
1989         SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_CHAR) l;
1990       break;
1991
1992     default:
1993       if (SPEC_LONG (val->etype))
1994         {
1995           if (SPEC_USIGN (val->etype))
1996             SPEC_CVAL (val->etype).v_ulong = (TYPE_TARGET_ULONG) l;
1997           else
1998             SPEC_CVAL (val->etype).v_long = (TYPE_TARGET_LONG) l;
1999         }
2000       else
2001         {
2002           if (SPEC_USIGN (val->etype))
2003             SPEC_CVAL (val->etype).v_uint = (TYPE_TARGET_UINT) l;
2004           else
2005             SPEC_CVAL (val->etype).v_int = (TYPE_TARGET_INT) l;
2006         }
2007     }
2008
2009   return val;
2010 }
2011
2012 /*------------------------------------------------------------------*/
2013 /* getNelements - determines # of elements from init list           */
2014 /*------------------------------------------------------------------*/
2015 int
2016 getNelements (sym_link * type, initList * ilist)
2017 {
2018   int i;
2019
2020   if (!ilist)
2021     return 0;
2022
2023   if (ilist->type == INIT_DEEP)
2024     ilist = ilist->init.deep;
2025
2026   /* if type is a character array and there is only one
2027      (string) initialiser then get the length of the string */
2028   if (IS_ARRAY (type) && IS_CHAR (type->next) && !ilist->next)
2029     {
2030       ast *iast = ilist->init.node;
2031       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
2032       if (!v)
2033         {
2034           werror (E_CONST_EXPECTED);
2035           return 0;
2036         }
2037
2038       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
2039         // yep, it's a string
2040         {
2041           return DCL_ELEM (v->type);
2042         }
2043     }
2044
2045   i = 0;
2046   while (ilist)
2047     {
2048       i++;
2049       ilist = ilist->next;
2050     }
2051   return i;
2052 }
2053
2054 /*-----------------------------------------------------------------*/
2055 /* valForArray - returns a value with name of array index          */
2056 /*-----------------------------------------------------------------*/
2057 value *
2058 valForArray (ast * arrExpr)
2059 {
2060   value *val, *lval = NULL;
2061   char buffer[128];
2062   int size = getSize (arrExpr->left->ftype->next);
2063   /* if the right or left is an array
2064      resolve it first */
2065   if (IS_AST_OP (arrExpr->left))
2066     {
2067       if (arrExpr->left->opval.op == '[')
2068         lval = valForArray (arrExpr->left);
2069       else if (arrExpr->left->opval.op == '.')
2070         lval = valForStructElem (arrExpr->left->left,
2071                                  arrExpr->left->right);
2072       else if (arrExpr->left->opval.op == PTR_OP &&
2073                IS_ADDRESS_OF_OP (arrExpr->left->left))
2074         lval = valForStructElem (arrExpr->left->left->left,
2075                                  arrExpr->left->right);
2076       else
2077         return NULL;
2078
2079     }
2080   else if (!IS_AST_SYM_VALUE (arrExpr->left))
2081     return NULL;
2082
2083   if (!IS_AST_LIT_VALUE (arrExpr->right))
2084     return NULL;
2085
2086   val = newValue ();
2087   if (!lval)
2088     {
2089         SNPRINTF (buffer, sizeof(buffer), "%s", AST_SYMBOL (arrExpr->left)->rname);
2090     }
2091   else
2092     {
2093         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2094     }
2095
2096   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2097            (int) AST_LIT_VALUE (arrExpr->right) * size);
2098
2099   val->type = newLink (DECLARATOR);
2100   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
2101     DCL_TYPE (val->type) = CPOINTER;
2102   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
2103     DCL_TYPE (val->type) = FPOINTER;
2104   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
2105     DCL_TYPE (val->type) = PPOINTER;
2106   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
2107     DCL_TYPE (val->type) = IPOINTER;
2108   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
2109     DCL_TYPE (val->type) = EEPPOINTER;
2110   else
2111     DCL_TYPE (val->type) = POINTER;
2112   val->type->next = arrExpr->left->ftype->next;
2113   val->etype = getSpec (val->type);
2114   return val;
2115 }
2116
2117 /*-----------------------------------------------------------------*/
2118 /* valForStructElem - returns value with name of struct element    */
2119 /*-----------------------------------------------------------------*/
2120 value *
2121 valForStructElem (ast * structT, ast * elemT)
2122 {
2123   value *val, *lval = NULL;
2124   char buffer[128];
2125   symbol *sym;
2126
2127   /* left could be furthur derefed */
2128   if (IS_AST_OP (structT))
2129     {
2130       if (structT->opval.op == '[')
2131         lval = valForArray (structT);
2132       else if (structT->opval.op == '.')
2133         lval = valForStructElem (structT->left, structT->right);
2134       else if (structT->opval.op == PTR_OP &&
2135                IS_ADDRESS_OF_OP (structT->left))
2136         lval = valForStructElem (structT->left->left,
2137                                  structT->right);
2138       else
2139         return NULL;
2140     }
2141
2142   if (!IS_AST_SYM_VALUE (elemT))
2143     return NULL;
2144
2145   if (!IS_STRUCT (structT->etype))
2146     return NULL;
2147
2148   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
2149                                AST_SYMBOL (elemT))) == NULL)
2150     {
2151       return NULL;
2152     }
2153
2154   val = newValue ();
2155   if (!lval)
2156     {
2157         SNPRINTF(buffer, sizeof(buffer), "%s", AST_SYMBOL (structT)->rname);
2158     }
2159   else
2160     {
2161         SNPRINTF (buffer, sizeof(buffer), "%s", lval->name);
2162     }
2163
2164   SNPRINTF (val->name, sizeof(val->name), "(%s + %d)", buffer,
2165            (int) sym->offset);
2166
2167   val->type = newLink (DECLARATOR);
2168   if (SPEC_SCLS (structT->etype) == S_CODE)
2169     DCL_TYPE (val->type) = CPOINTER;
2170   else if (SPEC_SCLS (structT->etype) == S_XDATA)
2171     DCL_TYPE (val->type) = FPOINTER;
2172   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
2173     DCL_TYPE (val->type) = PPOINTER;
2174   else if (SPEC_SCLS (structT->etype) == S_IDATA)
2175     DCL_TYPE (val->type) = IPOINTER;
2176   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
2177     DCL_TYPE (val->type) = EEPPOINTER;
2178   else
2179     DCL_TYPE (val->type) = POINTER;
2180   val->type->next = sym->type;
2181   val->etype = getSpec (val->type);
2182   return val;
2183 }
2184
2185 /*-----------------------------------------------------------------*/
2186 /* valForCastAggr - will return value for a cast of an aggregate   */
2187 /*                  plus minus a constant                          */
2188 /*-----------------------------------------------------------------*/
2189 value *
2190 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
2191 {
2192   value *val;
2193
2194   if (!IS_AST_SYM_VALUE (aexpr))
2195     return NULL;
2196   if (!IS_AST_LIT_VALUE (cnst))
2197     return NULL;
2198
2199   val = newValue ();
2200
2201   SNPRINTF (val->name, sizeof(val->name), "(%s %c %d)",
2202            AST_SYMBOL (aexpr)->rname, op,
2203            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
2204
2205   val->type = type;
2206   val->etype = getSpec (val->type);
2207   return val;
2208 }
2209
2210 /*-----------------------------------------------------------------*/
2211 /* valForCastAggr - will return value for a cast of an aggregate   */
2212 /*                  with no constant                               */
2213 /*-----------------------------------------------------------------*/
2214 value *
2215 valForCastArr (ast * aexpr, sym_link * type)
2216 {
2217   value *val;
2218
2219   if (!IS_AST_SYM_VALUE (aexpr))
2220     return NULL;
2221
2222   val = newValue ();
2223
2224   SNPRINTF (val->name, sizeof(val->name), "(%s)",
2225            AST_SYMBOL (aexpr)->rname);
2226
2227   val->type = type;
2228   val->etype = getSpec (val->type);
2229   return val;
2230 }